Comments 36

Константы configKERNEL_INTERRUPT_PRIORITY и configMAX_SYSCALL_INTERRUPT_PRIORITY также настраиваются в файле FreeRTOSConfig.h. Все свежие релизы FreeRTOS поддерживают вложенность и аппаратные приоритеты прерываний (на тех архитектурах, которые предусматривают настройку приоритета аппаратных прерываний).
FreeRTOS помимо классического псевдо-параллелизма с жирным стеком для каждой задачи позволяет работать с сопрограммами, которые исполняются кооперативно. Причем сопрограммы в данном случае полноценные, в отличии от имитации их за счет switch-case, как у Эдама Данкелса в Contiki.
Моменты времени, когда происходят переключения задач с использованием шедулера, бывают в точках окончания каждого тика времени (для этого используется прерывание по таймеру), а также в момент вызова функций API FreeRTOS, и при наступлении специальных событий (окончание аппаратного прерывания, окончание времени блокировки задачи, наступление момента обновления очереди или семафора).
Задачи, которые имеют равный приоритет, имеют одинаковые права на процессор, и переключаются на выполнение по очереди. Задачи, которые имеют более высокий приоритет, вытесняют (preempt) все задачи, которые имеют приоритет меньше. Высокоприоритетные задачи могут принудительно отдать свое процессорное время (вызовом taskYIELD(), если они завершили свою нужную работу), или заблокироваться в ожидании специального события, позволяя тем самым менее приоритетным задачам возможность запуститься. Таким образом во FreeRTOS для переключения задач используется алгоритм приоритетного (с фиксацией приоритета) планирования запуска задач с вытеснением, вытесняющая многозадачность (Fixed Priority Preemptive Scheduling). Однако имеется возможность применить и другой алгоритм переключения задач — кооперативная многозадачность (Co-operative Scheduling). У каждого алгоритма свои достоинства и недостатки, и соответственно разная область применения.
Для обмена данными задача-задача, задача-прерывание, прерывание-задача во FreeRTOS имеются специально предусмотренные объекты — очереди. При обмене данными или событиями предусмотрена синхронизация высокоприоритетной задачи (или прерывания) и менее приоритетной задачи. Синхронизация происходит с помощью блокировки на очереди или семафоре, при этом можно задать время блокировки (таймаута процесса передачи). Для атомарных операций есть возможность создавать критические секции кода.
Это самое интересное :)
Не слишком ли это много для RTOS? Может мкс (микросекунд)?
Кто нибудь тестил low-latency ядро линукс по этому же параметру?
Во FreeRTOS переключение контекста выполнения реально может происходить намного чаще, чем каждый слайс времени — при окончании аппаратного прерывания, при добровольной передаче контекста (вызовом taskYIELD()), при наступлении событий.
Это эквивалентно обновлению TickCount в Windows (16 мс минимум)? Если да, то как я понимаю это не совсем «latency» в контексте разговора про отзывчивость ядра и в контексте low-latency- и rt- ядер линукс. Как я понимаю TickCount для апишной функции винды обновляется редко, но контекст между процессами переключается чаще.
Я путаюсь?
void TASK_YYY( void *pvParameters)
{
while( 1 ){
while( value != xxx ){
// алгоритм
}
}
}
В таких местах могут быть зависоны, по крайней мере на IAR STM32 бывали, и нужно делать так:
void TASK_YYY( void *pvParameters)
{
while( 1 ){
while( value != xxx ){
// алгоритм
taskYIELD();
}
}
}
Т.е. после каждого перегона алгоритма нужно сделать переключение задачи, а то могут быть проблемы и вообще нужно избегать таких вот «ожидающих» состояний, например когда ожидаются данные с периферии низко скоростного интерфейса
Будет ли сообществу интересен материал, подобный этому, но про Embox?
Уж очень много человек одержимы идеей влиться в OSDEV-сцену, и среди пользователей хабрахабра таких также не мало. Часть одержимых идеей пытается прыгнуть чуть выше и пишет для таких же как они сами уроки. В итоге и появляются очередные протуберанцы о работе с защищенным режимом на ассемблере вместо основной темы — разработки ядра операционной системы.
У вас в багаже вполне переносимый код, достаточное множество реализованных алгоритмов, документация, хоть и изобилующая опечатками, страдающая орфографией, но все же вполне качественная. Вы могли бы показать сообществу, как реально устроена операционная система, с примерами кода. Пожевать, чтобы все могли это проглотить. Ну например, взять менеджер физической памяти и рассказать, как он работает, что такое buddy-алгоритм, чем хорош, или переходя уже к более высокому уровню — поведать о механизме slab. Рассказать про виртуальную память на примере своей ОС (хотя насколько помню тут у вас не все еще есть), про виртуальную файловую систему, драйверы, планирование, загрузку ELF. При достаточном качестве материалов они бы были мегапопулярны.
Также, статьи об использовании ОС в своих проектах могут быть очень интересными. Можно преподносить их подобно этому материалу про FreeRTOS. А можно комбинировать рассмотрение внутренностей ОС вместе с применением ее на практике. Например, рассказываете как сделать в вашей ОС что-то конкретное и добавляете немного информации о том, как же оно устроено. Чтобы у людей не складывалось ощущение черного ящика.
Ну и про стек я лично ничего не знаю — если это не совсем тривиальная вещь, то опиши ПЛЗ — зачем каждой таске свой стек и т.д.
Надуманный пример: на начальном этапе проектирования, заранее неизвестно, о будущем масштабе системы и хотелось бы предусмотреть ее будущий рост, вот РТОС, как раз позволяет сделать это достаточно прозрачно.
А применять ее не стоит в самых тривиальных случаях, например, есть простая логика: контроллер-сенсор, которую можно решить привычным способом, так как KISS никто не отменял :-).
Стэк по сути область памяти выделенная из кучи для каждого таска т.к каджый таск — мини подпрограмма, то соответственно имеет собственную область памяти.
Если говорить, не касаясь многозадачности:
1. При вызове подпрограмм в стек кладутся их формальные параметры, а также адрес возврата из подпрограммы. За счет этого подхода мы можем вызывать функции и всегда возвращаться туда, откуда мы их вызывали;
2. Также, на стеке выделяется память для локальных объектов функции;
3. Стек используется для временного сохранения данных из регистров процессора, потому что регистров обычно — не много.
Касаемо многозадачности:
Когда происходит прерывание таймера (как и любое другое) большинство ядер ОС сохраняют текущий регистровый контекст задачи в стеке. Переключение задач представляет собой подмену стека текущей задачи на стек той, что планировщик решил выполнить следом. Когда обработка прерывания завершается, регистровый контекст выталкивается из стека новой задачи, таким образом происходит переключение контекста. И именно за счет этого механизма программы могут разделять между собой единственный физический процессор.
Есть подходы, когда регистровый контекст сохраняется вручную, без использования аналогов инструкций push и pop, но это встречается довольно редко. Тем более, многие архитектуры умеют делать это (сохранение части регистрового контекста в стеке на момент обработки прерывания) почти на автомате.
Увы всё про мягкое и жесткое мы уже слышали…
Интересно всё же как эволюция ЭВМ и развитие операционных систем в частности пришли к тому, что в 2003 г. понадобилось изобрести новую операционную систему.
Казалось бы, FreeRTOS с его простотой, минимализмом, должен был появиться где-то в 60е...
в 60х не было целевой аудитории. Как мне кажется, необходимость FreeRTOS обусловлена широким распространением DIY микроконтроллерных девайсов.
Концепция вытесняющей многозадачности относительно новая, достаточно долго предполагалось, что если считаем задачу, остальные выгружаем. Использование функций ОС в стандарте С было новаторским решением, а это уже 70е. Про историю хорошо пишут Таненбаум и Непейвода, если интересуеесь, очень советую.
Ну и простота с минимализмом это скорее к FemtoOS :) слышал я, как FreeRTOS называли тяжёлой и перегруженной)
"Использование функций ОС в стандарте С"
Раскройте пожалуйста что имеется ввиду…
По моему мнению никаких функций ОС в C99 нет. Как минимум была бы проблема использовать все конструкции языка Си в системах без ОС вообще, однако как раз в таких системах (без ОС) язык Си и используется в основном.
В ANSI C (и даже в K&R C, приложение В) предполагалось, что, например, putc не пишет в регистр, а дергает стандартную библиотеку, уже портированную на платформу, а та дёргает ОС (хотя никто не мешает перенаправить stdout как удобно программисту, но это скорее исключение). В 60е концепция стандартной библиотеки и системных вызовов была новаторской - программы были вполне себе "вещами в себе", и если я не путаю, поддержка многозадачности в ОС появилась раньше стандартизированного доступа к периферии.
The exception permits the source code of applications that use FreeRTOS solely through the API published on this website to remain closed source, thus permitting the use of FreeRTOS in commercial applications without necessitating that the whole application be open sourced. The exception can only be used if you wish to combine FreeRTOS with a proprietary product and you comply with the terms stated in the exception itself.
As a special exception, the copyright holder of FreeRTOS gives you permission to link FreeRTOS with independent modules that communicate with FreeRTOS solely through the FreeRTOS API interface, regardless of the license terms of these independent modules, and to copy and distribute the resulting combined work under terms of your choice, provided that
- Every copy of the combined work is accompanied by a written statement that details to the recipient the version of FreeRTOS used and an offer by yourself to provide the FreeRTOS source code (including any modifications you may have made) should the recipient request it.
- The combined work is not itself an RTOS, scheduler, kernel or related product.
- The independent modules add significant and primary functionality to FreeRTOS and do not merely extend the existing functionality already present in FreeRTOS.
FreeRTOS: введение