μC/OS-II 移植笔记 2(FreeScale 68HCS12 核单片机)
首先是函数和全局变量的声明。
- ;***************************************************************************
- ;PUBLICDECLARATIONS
- ;***************************************************************************
- xdefOSCPUSaveSR
- xdefOSCPURestoreSR
- xdefOSStartHighRdy
- xdefOSCtxSw
- xdefOSIntCtxSw
- xdefOSTickISR
- ;***************************************************************************
- ;EXTERNALDECLARATIONS
- ;***************************************************************************
- xrefOSIntExit
- xrefOSIntNesting
- xrefOSPrioCur
- xrefOSPrioHighRdy
- xrefOSRunning
- xrefOSTaskSwHook
- xrefOSTCBCur
- xrefOSTCBHighRdy
- xrefOSTimeTick
然后是临界区的相关代码。
- OSCPUSaveSR:
- tfrccr,b;Itsassumedthat8-bitreturnvalueisinregisterB
- sei;Disableinterrupts
- rts;ReturntocallerwithBcontainingthepreviousCCR
- OSCPURestoreSR:
- tfrb,ccr;BcontainstheCCRvaluetorestore,movetoCCR
- rts
下面的代码是重点部分,首先是 OSStartHighRdy 函数,虽然这个函数只在 OSStart 函数中被调用一次,在之后的程序生命周期中就再也用不到了,但这次调用至关重要,决定了用户任务是否能被调度起来。因此代码中给出的注释尽可能的详细,我想看过注释后就不需要我解释什么了。
- ;***********************************************************************
- ;STARTHIGHESTPRIORITYTASKREADY-TO-RUN
- ;
- ;Description:ThisfunctioniscalledbyOSStart()tostart
- ;thehighestprioritytaskthatwascreatedbyyour
- ;applicationbeforecallingOSStart().
- ;
- ;Arguments:none
- ;
- ;Note(s):1)Thestackframeisassumedtolookasfollows:
- ;
- ;OSTCBHighRdy->OSTCBStkPtr+0CCR
- ;+1B
- ;+2A
- ;+3X(H)
- ;+4X(L)
- ;+5Y(H)
- ;+6Y(L)
- ;+7PC(H)
- ;+8PC(L)
- ;
- ;2)OSStartHighRdy()MUST:
- ;a)CallOSTaskSwHook()then,
- ;b)SetOSRunningtoTRUE,
- ;c)Switchtothehighestprioritytaskbyloading
- ;thestackpointerofthehighestprioritytask
- ;intotheSPregisterandexecutean
- ;RTIinstruction.
- ;************************************************************************
- OSStartHighRdy:
- jsrOSTaskSwHook;4~,调用OSTaskSwHook
- ldab#$01;2~,OSRunning=1
- stabOSRunning;4~
- ldxOSTCBHighRdy;3~,将OSTCBHighRdy的地址放到寄存器X
- lds0,x;3~,将OSTCBHighRdy->OSTCBStkPtr放到SP
- nop
- rti;4~,Runtask
其实上面的代码也可以放到OS_CPU_C.C 中,下面是个示例:
- #pragmaCODE_SEGNON_BANKED
- #pragmaTRAP_PROCSAVE_NO_REGS
- voidOSStartHighRdy(void)
- {
- __asmjsrOSTaskSwHook;//OSTaskSwHook();
- __asmldab#$01;
- __asmstabOSRunning;//OSRunning=TRUE;
- __asm
- {
- ldxOSTCBHighRdy
- lds0,x
- nop
- }
- }
上面代码中 #pragma TRAP_PROC SAVE_NO_REGS 表示这是个中断处理函数,编译器不为之保存任何寄存器内容。 虽然 OSStartHighRdy 并不是个真正的中断处理函数,但它模拟却模拟了中断处理函数的行为,函数结束时调用 rti 而不是 rts 命令。
下面是任务切换的代码,注释已经足够的详细了,如果有不明白的地方建议将 Jean J.Labrosse 的书再仔细读读。
- OSCtxSw:
- ldyOSTCBCur;3~,OSTCBCur->OSTCBStkPtr=StackPointer
- sts0,y
- OSIntCtxSw:
- jsrOSTaskSwHook;4~,Callusertaskswitchhook
- ldxOSTCBHighRdy;3~,OSTCBCur=OSTCBHighRdy
- stxOSTCBCur
- ldabOSPrioHighRdy;3~,OSPrioCur=OSPrioHighRdy
- stabOSPrioCur
- lds0,x;3~,LoadSPinto68HC12
- nop
- rti;8~,Runtask
可以看到,上面两个函数公用了大部分的函数体。上面的代码也可以直接写到 OS_CPU_C.C 中,不过写成 C 函数后就不能公用函数体了。
最后一部分是时钟中断程序,我使用RTI中断作为周期性时钟源。
- OSTickISR:
- incOSIntNesting;4~,NotifyuC/OS-IIaboutISR
- ldabOSIntNesting;4~,if(OSIntNesting==1){
- cmpb#$01
- bneOSTickISR1
- ldyOSTCBCur;OSTCBCur->OSTCBStkPtr=StackPointer
- sts0,y;}
- OSTickISR1:
- BSET$37,#128;CRGFLG_RTIF=1,这句是反汇编出来的,应该没错
- jsrOSTimeTick
- jsrOSIntExit;6~+,NotifyuC/OS-IIaboutendofISR
- rti;12~,Returnfrominterrupt,nohigherprioritytasksready.
中断程序的大部分代码都比较简答,只有下面这句我下了番功夫才写出来:
BSET $37, #128
与这行代码功能相同的 C 代码是:CRGFLG_RTIF = 1
我将 C代码直接生成汇编代码的结果是:BSET _CRGFLG,#128
可是直接拿到汇编文件中却无法编译,提示说 _CRGFLG 没有定义。一番查找才确定了_CRGFLG = 0x37。
2.3 OS_CPU_C.C
由于大部分的移植代码都放到了汇编文件中,OS_CPU_C.C 中的工作就很少了。OS_CPU_C.C 最重要的工作是 OSTaskStkInit 函数,并且网上流传的大多数 68HC12 内核的移植代码的这部分都或多或少的有问题。下面先给出我的代码:
μ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)