从 μC/OS 升级到 μC/OS-II
; 从栈中弹出所有寄存器的值;
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() 都抽出来并移到了
OSTaskStkInit()中。
程序清单L10.9μC/OS 中的 OSTaskCreate()
UBYTEOSTaskCreate(void(*task)(void*pd),void*pdata,void*pstk,UBYTE
p)
{
UWORDOS_FAR*stk;
UBYTEerr;
OS_ENTER_CRITICAL();
if(OSTCBPrioTbl[p]==(OS_TCB*)0){
OSTCBPrioTbl[p]=(OS_TCB*)1;
OS_EXIT_CRITICAL();(1)
stk=(UWORDOS_FAR*)pstk;
*--stk=(UWORD)FP_OFF(pdata);
*--stk=(UWORD)FP_SEG(task);
*--stk=(UWORD)FP_OFF(task);
*--stk=(UWORD)0x0202;
*--stk=(UWORD)FP_SEG(task);
*--stk=(UWORD)FP_OFF(task);
*--stk=(UWORD)0x0000;
*--stk=(UWORD)0x0000;
*--stk=(UWORD)0x0000;
*--stk=(UWORD)0x0000;
*--stk=(UWORD)0x0000;
*--stk=(UWORD)0x0000;
*--stk=(UWORD)0x0000;
*--stk=(UWORD)0x0000;
*--stk=(UWORD)0x0000;
*--stk=_DS;
err=OSTCBInit(p,(voidfar*)stk);(2)
if(err==OS_NO_ERR){
if(OSRunning){
OSSched();
}
}else{
OSTCBPrioTbl[p]=(OS_TCB*)0;
}
return(err);
}else{
OS_EXIT_CRITICAL();
return(OS_PRIO_EXIST);
}
}
程序清单 L10.10 μC/OS-II中的OSTaskStkInit()
void*OSTaskStkInit(void(*task)(void*pd),void*pdata,void*ptos,
INT16Uopt)
{
INT16U*stk;
opt=opt;
stk=(INT16U*)ptos;
*stk--=(INT16U)FP_SEG(pdata);
*stk--=(INT16U)FP_OFF(pdata);
*stk--=(INT16U)FP_SEG(task);
*stk--=(INT16U)FP_OFF(task);
*stk--=(INT16U)0x0202;
*stk--=(INT16U)FP_SEG(task);
*stk--=(INT16U)FP_OFF(task);
*stk--=(INT16U)0xAAAA;
*stk--=(INT16U)0xCCCC;
*stk--=(INT16U)0xDDDD;
*stk--=(INT16U)0xBBBB;
*stk--=(INT16U)0x0000;
*stk--=(INT16U)0x1111;
*stk--=(INT16U)0x2222;
*stk--=(INT16U)0x3333;
*stk--=(INT16U)0x4444;
*stk=_DS;
return((void*)stk);
}
10.4.2OSTaskCreateHook()
OSTaskCreateHook()在μC/OS中没有,如程序清单L10.11所示,在由.μC/OS 向μC/OS-II升级时,定义一个空函数就可以了。注意其中的赋值语句,如果不把Ptcb赋给Ptcb,有些编译器会产生一个警告错误,说定义的Ptcb变量没有用到。
程序清单10.11 μC/OS-II 中的OSTaskCreateHook()
#ifOS_CPU_HOOKS_EN
OSTaskCreateHook(OS_TCB*ptcb)
{
ptcb=ptcb;
}
#endif
OS_CFG.H
OS_CPU_HOOKS _EN设为1时,OSTaskCreateHook()的代码才会生成。这样做的好处是允许
用户移植时可在不同文件中定义钩子函数。
10.4.3OSTaskDelHook()
OSTaskDelHook() 这个函数在μC/OS中没有,如程序清单10.12所示,从μC/OS 到μC/OS-II,只要简单地定义一个空函数就可以了。注意,如果不用赋值语句将ptcb赋值为ptcb,有些编译程序可能会产生一些警告信息,指出定义的ptcb变量没有用到。
程序清单L10.12 μC/OS-II中的OSTaskDelHook().
#ifOS_CPU_HOOKS_EN
OSTaskDelHook(OS_TCB*ptcb)
{
ptcb=ptcb;
}
#endif
也还是要用条件编译管理指令来处理这个函数。只有把OS_CFG.H. 文件中的
OS_CPU_HOOKS_EN 设为1,OSTaskDelHook()的代码才能生成。这样做的好处是允许用户移植时在不同的文件中定义钩子函数。
10.4.4OSTaskSwHook()
OSTaskSwHook() 在μC/OS 中也不存在。从μC/OS向μC/OS-II升级时,只要简单地定义一个空
函数就可以了,如程
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)
