从 μC/OS 升级到 μC/OS-II

嵌入式系统 时间:2016-10-08来源:网络

对栈操作由低地址向高地址增长,设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() 都抽出来并移到了

1 2 3

关键词:

加入微信
获取电子行业最新资讯
搜索微信公众号:EEPW

或用微信扫描左侧二维码

相关文章

查看电脑版