从 μC/OS 升级到 μC/OS-II
对栈操作由低地址向高地址增长,设OS_STK_GROWTH 为 0
对栈操作由高地址向低地址递减,设OS_STK_GROWTH 为 1
有些新的常数定义(#define constants )在μC/OS中是没有的,故要加到OS_CPU.H中去。
10.2.4OS_TASK_SW()
OS_TASK_SW()是一个宏,从μC/OS升级到μC/OS-II时,这个宏不需要改动。当μC/OS-II从低优先级的任务向高优先级的任务切换时要用到这个宏,OS_TASK_SW()的调用总是出现在任务级代码中。
10.2.5OS_FAR
因为Intel80x86的结构特点, 在μC/OS中使用过OS_FAR 。 这个定义语句 (#define ) 在μC/OS-II中去掉了,因为这条定义使移植变得不方便。结果是对于Intel80x86,如果用户定义在大模式下编译时,所有存储器属性都将为远程(FAR).
在μC/OS-II中,任务返回值类型定义如程序清单L10.5所示。用户可以重新编辑所有OS_FAR的文件,或者在μC/OS-II中将OS_FAR定义为空,去掉OS_FAR,以实现向μC/OS-II的升级。
程序清单 L10.5 在 μC/OS 中任务函数的定义
voidOS_FARtask(void*pdata)
{
pdata=pdata;
while(1){
.
.
}
}
10.3 OS_CPU_A.ASM
移植μC/OS 和μC/OS-II 需要用户用汇编语言写4个相当简单的函数。
OSSTartHighRdy()
OSCtxSw()
OSIntCtxSw()
OSTickISR()
10.3.1OSStartHighRdy()
在μC/OS-II中,OSStartHighRdy()要调用OSSTaskSwHook()。OSTaskSwHook()这个函数在μC/OS中没有。用户将最高优先级任务的栈指针装入CPU之前要先调用OSTaskSwHook()。
还有, OSStartHighRdy要在调用OSTaskSwHook()之后立即将OSRunning设为1。程序清单L10.6 给出OSStartHighRdy()的示意代码。.μC/OS只有其中最后三步。
程序清单 L10.6 OSStartHighRdy()的示意代码
OSStartHighRdy:
CallOSTaskSwHook(); 调用OSTaskSwHook();
SetOSRunningto1; 置 OSRunning 为
1;
LoadtheprocessorstackpointerwithOSTCBHighRdy->OSTCBStkPtr;
将 OSTCBHighRdy->OSTCBStkPtr 装入处理器的栈指
针;
POPalltheprocessorregistersfromthestack; 从栈中弹出所有寄存器的值;
ExecuteaReturnfromInterruptinstruction; 执行中断返回指令;
10.3.2OSCtxSw()
在μC/OS-II中,任务切换要增作两件事,首先,将当前任务栈指针保存到当前任务控制块TCB后要立即调用OSTaskSwHook()。其次,在装载新任务的栈指针之前必须将OSPrioCur设为OSPrioHighRdy 。OSCtxSw()的示意代码如程序清单L10.7所示。μC/OS-II加上了步骤L10.7(1)和(2)。
程序清单 L10.7 OSCtxSw()的示意代码
OSCtxSw:
PUSHprocessorregistersontothecurrenttask’sstack;
所有处理器寄存器的值推入当前任务栈;
SavethestackpointeratOSTCBCur->OSTCBStkPtr;
CallOSTaskSwHook();1)
OSTCBCur=OSTCBHighRdy;
OSPrioCur=OSPrioHighRdy;(2)
LoadtheprocessorstackpointerwithOSTCBHighRdy->OSTCBStkPtr;
将 OSTCBHighRdy->OSTCBStkPtr 装入处理器的栈指
针;
POPalltheprocessorregistersfromthestack; 从栈中弹出所有寄存器的值;
ExecuteaReturnfromInterruptinstruction;
10.3.3OSIntCtxSw()
如同上述函数一样,在μC/OS-II.中,OSCtxSw()也增加了两件事。首先,将当前任务的栈指针保存到当前任务的控制块TCB后要立即调用OSTaskSwHook()。其次,在装载新任务的栈指针之前必须将OSPrioCur 设为OSPrioHighRdy。程序清单L10.8给出OSIntCtxSw()的示意代码。μC/OS-II.中增加了L10.8(1)和(2)。
程序清单L10.8OSIntCtxSw()的示意代码
OSIntCtxSw():
AdjustthestackpointertoremovecalltoOSIntExit(),localsin
OSIntExit()
andthecalltoOSIntCtxSw();
调整由于调用上述子程序引起的栈指针值的变化;
SavethestackpointeratOSTCBCur->OSTCBStkPtr;
保存栈指针到OSTCBCur->OSTCBStkPtr;
CallOSTaskSwHook(); 调用OSTaskSwHook();(1)
OSTCBCur=OSTCBHighRdy;
OSPrioCur=OSPrioHighRdy;(2)
LoadtheprocessorstackpointerwithOSTCBHighRdy->OSTCBStkPtr;
将 OSTCBHighRdy->OSTCBStkPtr 装入处理器的栈指针;
POPalltheprocessorregistersfromthestack; 从栈中弹出所有寄存器的值;
ExecuteaReturnfromInterruptinstruction; 执行中断返回指令;
10.3.4OSTickISR()
在μC/OS-II和μC/OS 中,这个函数的代码是一样,无须改变。
10.4 OS_CPU_C.C
移植 μC/OS-II 需要用C语言写6个非常简单的函数:
OSTaskStkInit()
OSTaskCreateHook()
OSTaskDelHook()
OSTaskSwHook()
OSTaskStatHook()
OSTimeTickHook()
其中只有一个函数OSTaskStkInit()是必不可少的。其它5个只需定义,而不包括任何代码。
10.4.1OSTaskStkInit()
在μC/OS中,OSTaskCreate()被认为是与使用的微处理器类型有关的函数。实际上这个函数中只有一部分内容是依赖于微处理器类型的。在μC/OS-II中,与使用的微处理器类型有关的那一部分已经从函数OSTaskCreate() 中抽出来了,放在一个叫作OSTaskStkInit()的函数中。
OSTaskStkInit()只负责设定任务的栈,使之看起来好像中断刚刚发生过,所有的CPU寄存器都被推入堆栈。作为提供给用户的例子,程序清单L10.9给出Intel80x86实模式,在大模式下编译的 μC/OS的OSTaskCreate()函数的代码。程序清单L10.10是同类微微处理器的μC/OS-II的OSTaskStkInit()函数的代码。比较这两段代码,可以看出:从 [L10.9(1)]
OS_EXIT_CRIITICAL() 到 [L10.9(2)] 调用 OSTaskStkInit() 都抽出来并移到了

加入微信
获取电子行业最新资讯
搜索微信公众号:EEPW
或用微信扫描左侧二维码