You are here

FreeRTOS Tick Code

Перевод может содержать ошибки. Читайте первоисточник: 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

Hobby's category: