|
TNeo: тщательно протестированная РТОС для Cortex-M0/M0+/M3/M4/M4F, PIC24/dsPIC, PIC32MX. |
|
|
|
Jan 18 2015, 01:41
|
Участник

Группа: Участник
Сообщений: 34
Регистрация: 16-09-14
Пользователь №: 82 835

|
Представляю новое ядро реального времени: TNeo. Как можно догадаться из названия, изначально она основана на TNKernel, но в итоге код был переписан почти полностью (потому что оригинальный код, по моему мнению, далек от совершенства), написаны подробные юнит-тесты, исправлены ошибки и добавлено много новых фич. Список найденных и исправленных ошибок в TNKernel 2.7 можно посмотреть тут: http://dfrank.bitbucket.org/tneokernel_api...implement__bugsКод TNeo написан аккуратно и тщательно, документирован очень подробно. Документация генерируется автоматически посредством doxygen, таким образом, легко поддерживать документацию в актуальном состоянии: Список новых возможностей: * Dynamic tick (опционально): если системе нечего делать, эта опция позволяет действительно ничего не делать (уйти в sleep), и даже не просыпаться каждую миллисекунду для обработки системного тика. Подробнее: http://dfrank.bitbucket.org/tneokernel_api...time_ticks.html* Timer: позволяет попросить ядро запустить пользовательскую функцию через определенный промежуток времени. Подробнее: http://dfrank.bitbucket.org/tneokernel_api...__timer_8h.html* Event group connection: позволяет "соединить" группу флагов с другими объектами РТОС. Очень удобно в случаях, когда в задаче нужно ждать, скажем, сообщения из нескольких очередей, или ждать каких-то флагов плюс сообщения из очереди. Подробнее: http://dfrank.bitbucket.org/tneokernel_api...ventgrp_connect* Profiler (опционально): позволяет узнать общее время работы каждой задачи, максимальное время работы задачи подряд и т.д. Полезно для отладки. * Software stack overflow check (опционально) - программный контроль переполнения стека, очень существенно облегчает дебаг; * Recursive mutexes (опционально) - позволяет вложенную блокировку мютексов; * Mutex deadlock detection (опционально) - в случае deadlock, ядро сообщает об этом посредством callback-функции; * Separate interrupt stack - на всех поддерживаемых платформах прерывания используют отдельный стек. Полный список фич тут: http://dfrank.bitbucket.org/tneokernel_api...l/features.htmlОтличия API TNeo от API TNKernel 2.7 тут: http://dfrank.bitbucket.org/tneokernel_api...ernel_diff.htmlЧем не устраивает TNKernel: см. документацию: Why reimplement TNKernel, также можно посмотреть мой старый пост на этом форуме: http://electronix.ru/forum/index.php?s=&am...t&p=1280109Кратко: ключевые проблемы TNKernel: - Самая основная проблема в том, что TNKernel - проект, написанный на коленке, т.е. в спешке. Огромное количество дублирования кода, непоследовательности и недостаточной продуманности.
- Проект не тестировался (только "вручную", как это нередко делается в эмбеддинге, к сожалению). Среди найденных багов есть банальнейшие ситуации с мютексами, которые не обрабатываются ядром корректно (см. ссылку на список багов выше). Ну, учитывая первый пункт про спешку, отсутствие тестов неудивительно, т.к. на них нужно огромное количество времени. У меня на тесты ушло примерно столько же времени, сколько на само ядро.
- Документация живет отдельной от самого ядра жизнью.
- Проект не поддерживается. Я присылал Юрию исправления некоторых ошибок, мои сообщения были проигнорированы.
Любопытный читатель может спросить: если уж я так сильно ругаю TNKernel, почему же я взял это ядро за основу? С удовольствием отвечу: не смотря на то, что реализация TNKernel, по моему мнению, далека от совершенства, идеи, стоящие за реализацией, я считаю в целом очень достойными. Ядро компактное и быстрое, и данные организованы грамотно. Я хотел переписать его так, чтобы на код было приятно смотреть и легко модифицировать (не боясь что-то сломать), хотел быть уверенным в отсутствии багов (посредством юнит-тестов), хотел достойную актуальную документацию. Все это готово. Попутно я реализовал вещи, которых мне самому раньше не хватало, плюс реализовал пожелания людей, заинтересовавшихся проектом (я представил TNeo на семинаре Microchip MASTERS 2014, после чего и получил предложение реализовать порт для линейки Cortex-M и несколько других фич) Выражаю огромную благодарность Юрию за проделанную работу над TNKernel: без нее, конечно, TNeo никогда не появилась бы. Полный список благодарностей можно прочитать на странице Thanks.
|
|
|
|
|
 |
Ответов
(60 - 74)
|
Jan 22 2015, 12:07
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(AHTOXA @ Jan 22 2015, 14:56)  То есть, если одна задача захватит мьютекс при помощи wait(), то другая задача может его освободить, вызвав release()? Нет. Мьютекс достается только одной задаче. Если одна задача получила мьютекс, то, значит, у другой его не было. То есть, и отдавать другой задаче нечего. Я не пробовал выполнять osMutexRelease до его получения. Но, думаю, просто ничего не произойдет.
|
|
|
|
|
Jan 22 2015, 15:37
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(ViKo @ Jan 22 2015, 17:07)  Нет. Мьютекс достается только одной задаче. Вот это и называется - задача владеет мьютексом. Захватила, и владеет единолично, пока не отдаст. Это я к вашей фразе Цитата(ViKo @ Jan 22 2015, 15:01)  И у него нет владельца. Не вижу принципиальной разницы с семафором. Теперь видите разницу?
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jan 22 2015, 17:13
|
Участник

Группа: Участник
Сообщений: 34
Регистрация: 16-09-14
Пользователь №: 82 835

|
Цитата(ViKo @ Jan 22 2015, 21:51)  Почитайте выше, что пишет топикстартер, У него мьютекс всегда принадлежит одной и той же задаче. Вот ему я и пишу, что у Кейла - не так. Мьютекс создает ОС, задачи им пользуются. Вы меня совершенно неправильно поняли. Где именно я так неясно выразился? Конечно, мютекс принадлежит той задаче, которая его захватила. Когда задача его разблокирует, он снова ничей. А семафор ничей даже когда задача его "захватила" (в кавычках - потому что некорректный термин для семафора). И в этом главное отличие семафоров от мютексов. Когда задача А заблокировала мютекс, задача Б не может его разблокировать. Когда задача А "заблокировала" семафор, задача Б (или даже прерывание) может его "разблокировать". Не знаю как у Кейла, может, и не так. Это не новость, что эти термины постоянно путаются, к сожалению. Ну еще раз дам ссылку на статью: Mutexes and Semaphores Demystified, почитайте там хотя бы The Myth: Mutexes and semaphores are similar or even interchangeable, а также The History of Semaphores and Mutexes.
|
|
|
|
|
Jan 22 2015, 20:33
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Хотите семафоров? - их есть у Кейла. Как говорится, найдите отличие от мьютекса.
То же, что в статье и dimonomid называют семафором, у Кейла выполняют "сигналы" (osSignalSet, osSignalClear, osSignalWait), они же в девичестве "события" (Event), они же "флаги". Они принадлежат задаче (по умолчанию у каждой задачи их 16 штук), и могут обрабатываться поодиночке или группой. Еще предлагаю посмотреть документ от Кейла: http://www.keil.com/product/brochures/rl-arm_gs.pdfСинтаксис устарел, но принципы остались теми же. В-частности, там показано, как используются семафоры: Сигнализация, Мультиплекс, Рандеву, Турникет.
|
|
|
|
|
Jan 23 2015, 06:49
|
Частый гость
 
Группа: Участник
Сообщений: 78
Регистрация: 7-04-10
Из: Пушкино
Пользователь №: 56 462

|
Ай пошли войны. Создали бы тему или блог какой и обсуждали бы краеугольные камни архитектуры ПО. Мне бы больше хотелось увидеть сравнение времени переключения контекста от количества задач между TNeo и той же FreeRTOS (порт для pic32  ) . Да и по памяти выделяемой на те же объекты синхронизации. У меня пока что руки дошли запустить-помигать. Исходный код у проекта выглядит очень приятно. Попробую прикрутить гармониевский стек, заодно буду смотреть что у TNeo с менеджером динамической памяти.
|
|
|
|
|
Jan 23 2015, 12:01
|
Частый гость
 
Группа: Участник
Сообщений: 180
Регистрация: 5-04-09
Пользователь №: 47 205

|
QUOTE (ViKo @ Jan 23 2015, 11:04)  Так что, разница есть. Но и говорить, что мьютекс - частный случай семафора - тоже верно. Принципиальная разница в том, что освободить мьютекс может только тот, кто им в настоящий момент владеет. У семафора нет такого ограничения.
|
|
|
|
|
Feb 9 2015, 10:47
|
Участник

Группа: Участник
Сообщений: 16
Регистрация: 28-04-14
Из: Екатеринбург
Пользователь №: 81 530

|
Прошу прошения. А почему такой древний компилятор XC32 v1.21?
|
|
|
|
|
Feb 9 2015, 16:30
|
Участник

Группа: Участник
Сообщений: 34
Регистрация: 16-09-14
Пользователь №: 82 835

|
Цитата(zaicev_ekb @ Feb 9 2015, 15:47)  Прошу прошения. А почему такой древний компилятор XC32 v1.21? Нет особых причин, соберите новым компилятором, проблем быть не должно.
|
|
|
|
|
Apr 7 2015, 23:58
|
Участник

Группа: Участник
Сообщений: 34
Регистрация: 16-09-14
Пользователь №: 82 835

|
Насчет FreeRTOS: Цитата(Mahagam @ Jan 20 2015, 12:17)  Aner, фриртос действительно тормознее других переключалок. в некоторых моментах - существенно. после одного из таких сравнений задали вопрос автору. в итоге в лицензии фриртос появился пункт запрещающий её сравнивать с другими ))) Цитата(Aner @ Jan 20 2015, 14:20)  кроме bla-bla-bla пример тормознутости в студию! Цитата(dimonomid @ Jan 20 2015, 02:14)  Если я заморочусь когда-нибудь на подобное сравнение, я напишу. Пока нечего сказать. Ради интереса, таки провел сравнение, вопреки лицензии FreeRTOS. Пример простейший: две задачи: А (высокоприоритетная) и B (низкоприоритетная). А ждет семафора, B через определенный интервал сигналит семафором. Т.к. А высокоприоритетная, то как только B сигналит семафором, управление передается задаче А. Измерял время от момента вызова сервиса сигнализирования из задачи B до получения управления задачей А. В TNeo: 624 тиков (594 с отключенной проверкой переполнения стека), в FreeRTOS: 1215 тиков (1075 с отключенной проверкой переполнения стека).UPD: в FreeRTOS: 863 тиков (699 с отключенной проверкой переполнения стека). Я по запаре накосячил с измерениями первый раз, см. след. сообщение. Измерения производились на PIC32MX с помощью stopwatch в MPLABX. TNeo: Код volatile int i;
/* * Low-priority task (2). The lower value, the higher priority. */ void task_b_body(void *par) { for(;;) { tn_task_sleep(10); i = 0; //-- stopwatch start tn_sem_signal(&sem); } }
/* * High-priority task (1). The lower value, the higher priority. */ void task_a_body(void *par) { for(;;) { tn_sem_wait(&sem, TN_WAIT_INFINITE); i = 1; //-- stopwatch stop: 624 cycles (594 without stack overflow check) } } FreeRTOS: Код volatile int i;
/* * Low-priority task (tskIDLE_PRIORITY + 1) */ void prvTaskB (void* pvParameters) { for (;;) { vTaskDelay(10); i = 1; //-- stopwatch start xSemaphoreGive( mySem ); } }
/* * High-priority task (tskIDLE_PRIORITY + 2) */ void prvTaskA (void* pvParameters) { for (;;) { xSemaphoreTake( mySem, portMAX_DELAY ); i = 0; //-- stopwatch stop: 863 cycles (624 without stack overflow check) } }
Сообщение отредактировал dimonomid - Apr 8 2015, 09:59
|
|
|
|
|
Apr 8 2015, 10:03
|
Участник

Группа: Участник
Сообщений: 34
Регистрация: 16-09-14
Пользователь №: 82 835

|
Так, отставить, я ерунду написал в прошлом сообщении: для TNeo-то я взял существующий настроенный проект, а для FreeRTOS создал новый, и забыл в нем оптимизацию включить. Пардон.
Так что отличия поскромнее:
В TNeo: 624 тиков (594 с отключенной проверкой переполнения стека), в FreeRTOS: 863 тиков (699 с отключенной проверкой переполнения стека).
|
|
|
|
|
Apr 8 2015, 13:42
|
Частый гость
 
Группа: Участник
Сообщений: 180
Регистрация: 5-04-09
Пользователь №: 47 205

|
QUOTE (dimonomid @ Apr 8 2015, 13:03)  Так, отставить, я ерунду написал в прошлом сообщении: для TNeo-то я взял существующий настроенный проект, а для FreeRTOS создал новый, и забыл в нем оптимизацию включить. Пардон.
Так что отличия поскромнее:
В TNeo: 624 тиков (594 с отключенной проверкой переполнения стека), в FreeRTOS: 863 тиков (699 с отключенной проверкой переполнения стека). Насколько я помню, автор FreeRTOS всегда упирал на большую предсказуемость. Т.е. две задачи - не показатель, а вот что будет с 20 задачами - вопрос интересный. Простой пример: TNeo реализует таймеры как callback-и из обработчика таймерного прерывания (я не ошибся?). Какой смысл говорить о времени переключения контекста в таком раскладе? Переключение реально не произойдет до тех пор, пока не будут отработаны все таймеры. Т.е. задержка не детерминирована, совсем.
Сообщение отредактировал LightElf - Apr 8 2015, 14:20
|
|
|
|
|
Apr 8 2015, 14:02
|
Участник

Группа: Участник
Сообщений: 34
Регистрация: 16-09-14
Пользователь №: 82 835

|
Цитата(LightElf @ Apr 8 2015, 17:42)  Насколько я помню, автор FreeRTOS всегда упирал на большую предсказуемость. Т.е. две задачи - не показатель, а вот что будет с 20 задачами - вопрос интересный. Как в FreeRTOS - не знаю, а в TNeo, как и в TNKernel, количество задач не влияет на скорость переключения контекста: для каждого приоритета есть связанный список задач, готовых к запуску. И есть битовая маска, каждый бит которой отражает приоритет, в котором есть готовые к запуску задачи. Таким образом, когда ядро выясняет, какую задачу нужно запустить, оно делает следующее: - Находит номер младшего установленного бита в маске. Некоторые архитектуры имеют специальную инструкцию для этой операции ( Find first set). Если такой инструкции нет, то приходится вручную проверять каждый бит, но тогда время выполнения зависит не от количества задач, а от количества приоритетов. - Передает управление первой задаче из связанного списка для соответствующего приоритета. Время константное. Цитата(LightElf @ Apr 8 2015, 17:42)  Особенно такой скользкий параметр, как максимальная задержка входа в прерывание. От количества задач эта задержка тоже не зависит.
Сообщение отредактировал dimonomid - Apr 8 2015, 14:16
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|