实时操作系统μC/OS-II在MCF5272上的移植
还需要为μC/OS-II编写4个简单的汇编函数。在每个硬件时钟到来后,μC/OS-II会在中断服务例程中调用OSIntCtxSw()进行任务调度;另外,当某个任务因等待资源而被挂起时,没有必要等到自己的时间片全都用完,可以自己主动放弃CPU,这可以通过调用一个任务级的任务调度函数OSCtxSw()来实现。其中相对复杂的是OSIntCtxSw()。由于OSTickISR()调用了OSIntExit(),OSIntExit()又再次调用了OSIntCtxSw(),如果进行任务切换,那么两次调用都不会返回,而不同的C编译器、不同的编译选项处理C调用时对堆栈的使用也不尽相同。因此OSIntCtxSw()是编译器相关的。GCC在使用2~4级优化时,在主调函数中会是一个jsr跳转指令,而被调函数以linkw %fp, #开始。这两条指令都会影响堆栈指针。为了实现任务切换,必须重新调整堆栈指针以补偿调用的影响。一个完整过程如下:
OSIntCtxSw:
adda.l #16,%a7 //栈补偿,GCC-O2->-O4优化
move.l (OSTCBCur),%a1
move.l %a7,(%a1) //OSTCBCur->OSTCBStkPtr=SP
jsr OSTaskSwHook //调用Hook钩子函数
/*OSTCBCur->OSTCBStkPtr=OSTCBHighRdy->OSTCBStkPtr*/
move.l (OSTCBHighRdy), %a1
move.l %a1, (OSTCBCur)
move.b (OSPrioHighRdy), %d0
move.b %d0, (OSPrioCur) //OSPrioCur=OSPrioHighRdy
move.l (%a1),%a7 //SP=OSTCBCur->OSTCBStkPtr
movem.l (%a7),%d0-%d7/%a0-%a6 //恢复CPU寄存器,切换到新任务
lea 60(%a7),%a7
rte
篇幅所限,其它三个函数就不赘述了。
3 μC/OS-II任务堆栈初始化
μC/OS-II中每个任务都有自己的任务堆栈,在任务创建初期由OSTaskStkInit()初始化。初始化堆栈的目的就是模拟一次中断。任务堆栈中保存了任务代码的起始地址和一些CPU寄存器(初值是无关紧要的),这样一旦条件满足,就可以执行该任务了。MCF5272在中断发生时,会自动保存程序指针PC、状态寄存器SR以及其它一些信息,为四字帧结构。除此以外,%d0-%d7、%a0-%a6也必须按一定顺序入栈。OSTaskStkInit()在完成堆栈初始化后,还要返回栈顶指针以用于该任务控制块TCB结构的初始化。该程序使用C语言编写。
4 μC/OS-II系统时钟
MCF5272处理器内置了4个定时器,使用TIMER0产生周期10ms的定时中断作为系统时钟。当PIVR寄存器设置为0x40时,TIMER0为69号中断,在矢量表的相应位置需填入时钟服务程序OSTickISR()的入口地址,并初始化时钟:
volatile unsigned short*pTimer;
pTimer=(unsigned short*)(0x10000000+0x200);//指向TIMER0
/* 复位时钟 */
*pTimer &= 0xFFF9; //定时器处于STOP状态
*pTimer=(*pTimer & 0x00FF) | 0xFA00;//预分频=250
*pTimer |= 0x0018; //计数满自动清零,中断方式
pTimer[2] = 165; //Set TRR = 165
*pTimer=(*pTimer & 0xFFF9) | 0x0004;CLK=Master/16, 启动
上述程序段时钟节拍的周期为:(1/66MHz)×250×165×16=0.01秒。实时性要求高的场合可以使用更为精细的时钟。TIMER0一旦完成初始化,就开始工作,但是要让中断发生,还必须设置ICR寄存器相应字段给该中断分配IPL(Interrupt Priority Level,中断优先级),并保证该中断没有被状态寄存器SR屏蔽。
该时钟初始化代码可以放在第一个μC/OS-II任务中,在OSStart()后执行。一旦内核可以进行正常的任务切换,移植工作也就基本完成了。
5 内核编译与下载
所有的C和汇编源文件经过编译、链接,最终形成一个二进制映像文件。由于μC/OS-II使用了自定义的数据类型,因此必须将其转变成为GCC(GNU C Compiler)能识别的类型,如INT8U可以定义为unsigned char。另外,还必须编写一个LD(链接脚本)文件控制编译,将程序定位到实际的ROM和RAM资源中。为了调试方便,通常是通过BDM工具将内核下载到目标板SDRAM中运行,调试通过后再固化到FLASH中。
RTOS是当前嵌入式应用的热点。应用RTOS,可以使产品更可靠、功能更强大而开发周期更短。μC/OS-II有着良好的实时性和很小的代码量,并被广泛移植到x86、68K、ColdFire、MPC 8xx、ARM、MIPS、C5409等许多处理器上。数百个成功的商业应用实例说明μC/OS-II是一个稳定可靠的内核,因此将μC/OS-II移植到MCF5272具有很强的实用前景。
- μC/OS-II下通用驱动框架的设计与实现(07-23)
- 基于μC/OS-II嵌入式系统的低功耗开发(07-08)
- 基于S3C44B0X+μcLinux的嵌入式以太网设计(07-08)
- 蓄电池化成控制系统中显示功能的实现(11-05)
- 嵌入式实时操作系统μC/OS-II 在P89V51RD2中的移植(04-09)
- LPC2292的伪中断与伪中断处理(03-25)