μC/OS-II 移植笔记 2(FreeScale 68HCS12 核单片机)
- OS_STK*OSTaskStkInit(void(*task)(void*pd),void*p_arg,OS_STK*ptos,INT16Uopt)
- {
- INT16U*wstk;
- INT8U*bstk;
- (void)opt;/*optisnotused,preventwarning*/
- ptos--;/*需要这么调整一下栈顶地址,否则存的第一个int16的低Byte会溢出堆栈*/
- wstk=(INT16U*)ptos;/*Loadstackpointer*/
- *wstk--=(INT16U)task;/*Returnaddress.Format:PCH:PCL*/
- *wstk--=(INT16U)task;/*Returnaddress.Format:PCH:PCL*/
- *wstk--=(INT16U)0x2222;/*YRegister*/
- *wstk--=(INT16U)0x1111;/*XRegister*/
- *wstk=(INT16U)p_arg;/*Simulatecalltofunctionwithargument(InDRegister)*/
- bstk=(INT8U*)wstk;/*ConvertWORDptrtoBYTEptrtosetCCR*/
- bstk--;
- *bstk=(0xC0);/*CCRRegister(DisableSTOPinstructionandXIRQ)*/
- return((OS_STK*)bstk);/*Returnpointertonewtop-of-stack*/
- }
其中有几点需要特别注意:
(1)68HC12 内核与 68HC11 内核一个大的区别就是 SP 指向的是实栈顶。老的68HC11的移植代码都是 *--wstk = XXXX。移植到68HC12 内核就要改为*wstk-- = XXXX。否则会浪费掉堆栈的前两个字节。
(2)先要执行 ptos--;否则第一个双字节会有一半溢出堆栈空间。
(3)任务的参数传递是通过寄存器 D 的,而不是堆栈。网上代码多数是:
[cpp]view plaincopy
- *wstk--=(INT16U)p_arg;
- *wstk--=(INT16U)task;
这样参数是传递不进来的,只有像我的代码中这样写才是正确的。
(4)代码中 *wstk-- = (INT16U)task; 重复了两遍,千万别以为这是我的笔误。堆栈中先存的(INT16U)task实际上是 task 函数的返回地址。虽然 μC/OS-II 要求任务不能返回,但是作为 C 语言的调用约定,在调用一个 C 函数之前要将 C 函数的返回地址先入栈。因此我将 task 的地址重复了两次,实际上第一的地址是什么都不重要,因为程序运行中觉得不会用到。甚至不要这行也行,还能节省堆栈中两个字节的空间。不过我还是选择了保留这行,使其看起来更加符合 C 语言的调用规范。
除此之外,OS_CPU_C.C 还包括一系列的 Hook 函数:
- #ifOS_CPU_HOOKS_EN>0&&OS_VERSION>203
- voidOSInitHookBegin(void)
- {
- #ifOS_TMR_EN>0
- OSTmrCtr=0;
- #endif
- }
- voidOSInitHookEnd(void)
- {
- }
- #endif
- #ifOS_CPU_HOOKS_EN>0
- voidOSTaskCreateHook(OS_TCB*ptcb)
- {
- #ifOS_APP_HOOKS_EN>0
- App_TaskCreateHook(ptcb);
- #else
- (void)ptcb;
- #endif
- }
- voidOSTaskDelHook(OS_TCB*ptcb)
- {
- #ifOS_APP_HOOKS_EN>0
- App_TaskDelHook(ptcb);
- #else
- (void)ptcb;
- #endif
- }
- voidOSTaskStatHook(void)
- {
- #ifOS_APP_HOOKS_EN>0
- App_TaskStatHook();
- #endif
- }
- voidOSTaskSwHook(void)
- {
- #ifOS_APP_HOOKS_EN>0
- App_TaskSwHook();
- #endif
- }
- #endif
- #ifOS_CPU_HOOKS_EN>0&&OS_VERSION>=251
- voidOSTaskIdleHook(void)
- {
- #ifOS_APP_HOOKS_EN>0
- App_TaskIdleHook();
- #endif
- }
- #endif
- #ifOS_CPU_HOOKS_EN>0&&OS_VERSION>203
- voidOSTCBInitHook(OS_TCB*ptcb)
- {
- #ifOS_APP_HOOKS_EN>0
- App_TCBInitHook(ptcb);
- #else
- (void)ptcb;/*Preventcompilerwarning*/
- #endif
- }
- #endif
- #ifOS_CPU_HOOKS_EN>0
- voidOSTimeTickHook(void)
- {
- #ifOS_APP_HOOKS_EN>0
- App_TimeTickHook();
- #endif
- #ifOS_TMR_EN>0
- OSTmrCtr++;
- if(OSTmrCtr>=(OS_TICKS_PER_SEC/OS_TMR_CFG_TICKS_PER_SEC))
- {
- OSTmrCtr=0;
- OSTmrSignal();
- }
- #endif
- }
- #endif
代码中 OS_APP_HOOKS_EN 和 OS_TMR_EN 在v2.52 版本中还没出现,我在这里这样写是为了移植到后面版本时更轻松。
至此,移植代码就基本完成了。不过这样还不能运行,因为两个中断处理函数(OSCtxSw和OSTickISR)还没有和对应的中断产生关联。将这二者关联起来的方法有几种,比如直接在 PRM 文件中制定,我用了种比较笨的办法,从网上找了个 vector.c 文件,虽然看起来不是很优雅,但确实是正确的代码。
- /*******************************************************************
- *
- *FreescaleMC9S12DP256ISRVectorDefinitions
- *
- *FileName:vectors.c
- *Version:1.0
- *Date:Jun/22/2004
- *Programmer:EricShufro
- ********************************************************************/
- /********************************************************************
- *EXTERNALISRFUNCTIONPROTOTYPES
- *********************************************************************/
- externvoidnear_Startup(void);/*StartupRoutine.*/
- externvoidnearOSTickISR(void);/*OSTimeTickRoutine.*/
- externvoidnearOSCtxSw(void);/*OSContectSwitchRoutine.*/
- externvoidnearSCI1_ISR(void);/*SCI1Routine.*/
- externvoidnearSCI0_
μCOS-II移植笔记68HCS12核单片 相关文章:
- μC/OS-II 移植笔记 1(FreeScale 68HCS12 核单片机)(11-20)
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)