Перевод может содержать ошибки. Читайте первоисточник: FreeRTOS Tick Code
Назад: [Как работает FreeRTOS] | Вверх: [Как работает FreeRTOS] | Вперёд: [Как работает FreeRTOS] |
Фактический исходный код, используемый портом FreeRTOS для микроконтроллеров AVR, немного отличается от примеров, приведённых на предыдущих страницах. Функция vPortYieldFromTick() сама реализована с атрибутом 'naked', и контекст сохраняется и восстанавливается внутри vPortYieldFromTick(). Это сделано именно таким образом, чтобы реализовать не-[приоритетный/упреждающий] non-preemptive context switches переключение контекста (где задача блокирует сама себя), которое здесь не описано.
Поэтому реализация тиков ОС во FreeRTOS такова (смотрите комментарии в фрагменте исходного кода для более подробной информации):
/*----------------------------------------------------------------------------*/
void SIG_OUTPUT_COMPARE1A ( void ) __attribute__ ( ( signal, naked ) );
void vPortYieldFromTick ( void ) __attribute__ ( ( naked ) );
/*----------------------------------------------------------------------------*/
/* Обработчик прерывания для тиков ОС. */
void SIG_OUTPUT_COMPARE1A( void )
{
/* Вызов функции тиков ОС. */
vPortYieldFromTick();
/* Возврат из прерывания. Если было выполнено переключение контекста,
возврат произойдёт в другую задачу. */
asm volatile ( "reti" );
}
/*----------------------------------------------------------------------------*/
void vPortYieldFromTick( void )
{
/* Это naked-функция, поэтому контекст должен быть сохранён. */
portSAVE_CONTEXT();
/* Увеличение счётчика тиков ОС и проверка, не вызвало ли новое значение
счётчика тиков истечение времени ожидания. Вызов этой функции может
вызвать перевод какой-либо задачи в состояние готовности к запуску. */
vTaskIncrementTick();
/* Проверяем, не требуется ли переключение контекста. Переключаемся на
контекст задачи, которая была переведена в состояние готовности к запуску
вызовом vTaskIncrementTick(), разумеется если эта задача имеет приоритет
выше, чем прерванная задача. */
vTaskSwitchContext();
/* Восстанавливаем контекст. Если было выполнено переключение контекста,
здесь будет восстановлен контекст задачи, которая была возобновлена. */
portRESTORE_CONTEXT();
/* Возврат из naked-функции. */
asm volatile ( "ret" );
}
Далее: Реализация RTOS - Контекст микроконтроллера AVR