μC/OS-II在80196KC单片机上的移植
void OSTickISR(void)
{
asm push ?frame01;
OSIntNesting++;
hso command=0x19;
AD Timer Count+=5000;
hso time = AD Timer Count;
OSTimeTick();
OSIntExit();
asm pop?frame01;
}
还应注意,在其它中断服务程序中,如果没有定义局部变量,也应加上对框架寄存器的保护。如果有局部变量,编译器会自动对框架寄存器进行保护。在编写OSIntCtxSw()函数时应当注意,由于OS-IntCtxSw()是在OSIntExit()中调用的,且在调用OS-IntCtxSw()之前又有一个关中断的操作。因此,笔者采用push a方式来关闭中断,也就是说,切换到另一高优先级的任务后,会在当前任务中留下在OSIntC-txSw()和OSIntExit()调用的返回地址4个字节的垃圾和pusha关中断时进栈的4个字节垃圾(共8个字节)。因此,为了保证下次切换到该任务的正确性,应将SP指针加8,然后再进行任务切换。为加深对此的理解,可以做一假设:如果80196KC是24位(3个字节)寻址能力,在当前任务中会留下OSIntCtxSw()和OSIntExit()调用的返回地址的6个字节的垃圾,如果关中断直接采用asm di方式,而不牵扯到堆栈操作,此时SP应调整6个字节而不是8个字节。
5 正确性检验
图3是一个点灯程序的主任务流程。其6个灯中的每一个点灯操作都是一个单独任务。第一个灯每两个时钟节拍做一次异或操作。如果LED1每执行2次异或操作向任务2发一信号量2?每执行3次异或操作向任务3发一信号量3?每执行4次异或操作向任务4发一信号量4,每执行5次异或操作向任务5发一信号量5,每执行6次异或操作向任务6发一信号量6。那么,任务2到任务6在接到相应的信号量时将对自已控制的灯进行一次异或操作。理论分析,LED2到LED6的波形周期分别为LED1的2到6 倍。笔者曾用示波器对6 个灯的波形进行观察,其结果与理论分析相符,同时,在连续运行数天后,没有发现死机和复位,证明移植成功。
《μC/OS-II在80196KC单片机上的移植(第2页)》