Перевод может содержать ошибки. Читайте первоисточник: RTOS Context Switch - Step 3
Назад: [Как работает FreeRTOS] | Вверх: [Как работает FreeRTOS] | Вперёд: [Как работает 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 )
{
portSAVE_CONTEXT();
vTaskIncrementTick();
vTaskSwitchContext();
portRESTORE_CONTEXT();
asm volatile ( "ret" );
}
Функция SIG_OUTPUT_COMPARE1A() объявляется с атрибутом 'naked', поэтому первой инструкцией будет вызов функции vPortYieldFromTick(). Эта функция также объявлена с атрибутом 'naked', поэтому контекст сохраняется явно, вызовом макроса portSAVE_CONTEXT().
Макрос portSAVE_CONTEXT() полностью помещает контекст AVR в стек задачи TaskA. Результат показан на рисунке ниже. Указатель стека для задачи TaskA теперь указывать на вершину своего собственного контекста. Макрос portSAVE_CONTEXT() завершается сохранением копии указателя стека. И ядро реального времени уже имеет копию указателя стека для задачи TaskB - она была сделана, когда задача TaskB была приостановлена.