В RTOS вы создаете и запускаете задачи.Если вы не выполняете более одной задачи, то использование RTOS не дает большого преимущества.
Я не использую FreeRTOS (но уже выполнил), но следующее относится к любой RTOS и является псевдо-код, а не специфичный для FreeRTOS API - многие детали, такие как приоритеты задач и распределение стека, намеренно отсутствуют.
Первая в самой простой ОСРВ, включая FreeRTOS, main()
используется для инициализации оборудования, создания задач и запуска планировщика:
int main( void )
{
// Necessary h/w & kernel initialisation
initHardware() ;
initKernel() ;
// Create tasks
createTask( task1 ) ;
createTask( task2 ) ;
// Start scheduling
schedulerStart() ;
// schedulerStart should not normally return
return 0 ;
}
Теперь давайте предположим, что ваш первый пример реализованв task1
.Типичная ОСРВ будет иметь функции таймера и задержки.Самым простым в использовании является задержка, и она подходит, когда периодическая обработка гарантированно займет менее одного такта ОС:
void task1()
{
// do something every 100 ms
for(;;)
{
delay( 100 ) ; // assuming 1ms tick period
// something
...
}
}
Если something
в этом случае занимает более 1 мс, этобудет выполняться не каждые 100 мс, а через 100 мс плюс время выполнения something
, которое само по себе может быть переменным или недетерминированным, что приводит к нежелательному дрожанию синхронизации.В этом случае вы должны использовать таймер:
void task1()
{
// do something every 100 ms
TIMER timer = createTimer( 100 ) ; // assuming 1ms tick period
for(;;)
{
timerWait() ;
// something
...
}
}
Таким образом something
может занять до 100 мс и все равно будет выполняться точно и детерминистически каждые 100 мс.
Теперь к вашему второму примеру;это немного сложнее.Если ничего не произойдет до тех пор, пока не будет инициализировано оборудование, вы можете использовать существующий шаблон в main()
перед запуском планировщика.Однако, как обобщение, ожидание чего-либо в другом контексте (задача или прерывание) происходит с использованием примитива синхронизации, такого как семафор или флаг события задачи (не во всей ОСРВ есть флаги событий задачи).Таким образом, в простом случае в main()
вы можете создать семафор:
createSemaphore( hardware_ready ) ;
Затем в контексте, выполняющем процесс, который должен завершиться:
// Init hardware
...
// Tell waiting task hardware ready
semaphoreGive( hardware_ready ) ;
Затем в некоторой задаче, которая будетдождитесь готовности оборудования:
void task2()
{
// wait for hardware ready
semaphoreTake( hardware_ready ) ;
// do something else
for(;;)
{
// This loop must block is any lower-priority task
// will run. Equal priority tasks may run is round-robin
// scheduling is implemented.
...
}
}