下面介绍一个完整的上下文切换的例子连起来(PuttingItAllTogether)在第2节的最后一部分展示了这些积木模块(buildingblocks)和源代码模块(sourcecodemodules)使如何来达到一个在AVR微控制器上进行RTOS上下文切换的目的的。这个例子分几步演示了从一个低的优先级的任务TaskA,切换到高优先级的任务TaskB的。源代码与WinAVRC开发工具兼容。上下文切换-第1步在RTOStick中断发生之前这个例子,以TaskA的执行开始。TaskB先前已经被挂起,所以它的上下文已经被保存到TaskB的stack里面。TaskA的上下文如下图所示: 在每个寄存器里标上(A),表示,这寄存器含有任务A的上下文的正确值。 上下文切换—第2步RTOStick中断发生了 当TaskA将要执行到一个LDI指令的时候,RTOStick发生。当中断发生时,AVR微控制器会在跳入到RTOStickISR之前,自动放置当前的PC到stack里面。上下文切换-第3步RTOStick中断(服务)执行ISR源代码如下。为便于阅读,移除注释。/*InterruptserviceroutinefortheRTOStick.*/PARE1A(void){ vPortYieldFromTick(); asmvolatile("reti");}/*--------------------------------------------------*/voidvPortYieldFromTick(void){ portSAVE_CONTEXT(); vTaskIncrementTick(); vTaskSwitchContext(); portRESTORE_CONTEXT(); asmvolatile("ret");}/*--------------------------------------------------*/PARE1A()是一个naked函数。所以第一条指令是调用vPortYieldFromTick()..vPortYieldFromTick()也是一个naked函数,所以AVR执行上下文被portSAVE_CONTEXT().明确保存。portSAVE_CONTEXT()将整个AVR执行上下文全部压入TaskA的Stack..示意图如下。TaskA的栈顶指针(StackPointer)现在指向它自己的上下文的顶部。portSAVE_CONTEXT()通过保存栈顶指针的一份拷贝来完成。在上次TaskB挂起时,实时内核已经复制了TaskB的栈顶指针。上下文切换-第4步增加tickcount在TaskA上下文被保存之后再执行vTaskIncrementTick()。这个例子,假定tickcount的增加会引起TaskB准备运行。TaskB比TaskA有更高的优先级,所以vTaskSwitchContext()-第5步
一个完整的上下文切换的例子 来自淘豆网m.daumloan.com转载请标明出处.