FreeRTOS是如何工作的--上下文切换的完整例子
下面介绍一个完整的上下文切换的例子
连起来(Putting It All Together)
在第2节的最后一部分 展示了这些 积木模块(building blocks)和源代码模块(source code modules)使如何来达到 一个在AVR微控制器上进行RTOS上下文切换的目的的。这个例子分几步演示了从一个低的优先级的任务Task A,切换到高优先级的任务Task B的。
源代码与WinAVR C开发工具兼容。
上下文切换-第1步
在RTOS tick 中断发生之前
这个例子,以TaskA的执行开始。TaskB先前已经被挂起,所以它的上下文已经被保存到TaskB的stack里面。
TaskA的上下文如下图所示:
在每个寄存器里标上(A),表示,这寄存器含有 任务A的上下文的正确值。
上下文切换—第2步
RTOS tick中断 发生了
当TaskA 将要执行到一个LDI指令的时候,RTOS tick 发生。当中断发生时,AVR微控制器会在跳入到RTOS tickISR之前,自动放置当前的PC到stack里面。

上下文切换-第3步
RTOS tick 中断(服务)执行
ISR源代码如下。为便于阅读,移除注释。
/* Interrupt service routine for the RTOS tick. */
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()..vPortYieldFromTick()也是一个naked 函数,所以AVR执行上下文被portSAVE_CONTEXT().明确保存。
portSAVE_CONTEXT()将整个AVR执行上下文全部压入TaskA的Stack..示意图如下。TaskA的栈顶指针(Stack Pointer)现在指向它自己的上下文的顶部。portSAVE_CONTEXT()通过保存栈顶指针的一份拷贝来完成。在上次TaskB挂起时,实时内核已经复制了TaskB的栈顶指针。

上下文切换-第4步
增加tick count
在TaskA上下文被保存之后 再执行vTaskIncrementTick()。这个例子,假定tick count的增加会引起TaskB 准备运行。TaskB比TaskA有更高的优先级,所以vTaskSwitchContext()在ISR完成后将处理器交给 TaskB.
上下文切换-第5步
TaskB的栈顶指针被取得
TaskB的任务必须被恢复。portRESTORE_CONTEXT要做的第1件事情就是从TaskB被挂起时保存的拷贝里 取得TaskB的栈顶指针。TaskB的栈顶指针 被载入到处理器的stack pointer.所以现在AVR的栈顶指针就是指向TaskB的上下文。
上下文切换-第6步
恢复TaskB的上下文
portRESTORE_CONTEXT()从TaskB的stack中恢复它的上下文到相应的处理器寄存器。

只有PC(program counter)还留在stack中。
上下文切换-第7步
RTOS tick退出
vPortYieldFromTick()返回到SIG_OUTPUT_COMPARE1A(),在那里,最后一条指令是从中断返回(RETI). RETI指令假定stack中的下个值就是中断发生时返回地址。
当RTOS tick 中断发生时,AVR自动放置TaskA的返回地址(在TaskA中的下条指令的地址)到stack.。 ISR修改stack pointer 它指向了TaskB的stack. 从而,RETI指令从stack弹出的返回地址是 TaskB在挂起前 将要立即执行的指令的地址.
RTOS tick,它中断的是 TaskA,然而却返回到了TaskB,这就完成了上下文切换。
====The End( 全文完)====
作者:Gavin Lee 更新日期:2006-04-24
来源:upsdn.net
浏览次数:
相关文章
相关评论 发表评论
- No Comments