OSCtxSw:
pushn %r15 ; 将r1~r15寄存器压入当前任务堆栈,(r1~r15是C33中的CPU寄存器)
ld.w %r0,%ahr ; 将状态寄存器的内容转存入r0,r1寄存器
ld.w %r1,%alr ;
pushn %r1 ; 将状态寄存器压入堆栈
ld.w %r4,%sp ; 将当前的SP指针内容保存入r4
xld.w %r5,[OSTCBCur] ; 将当前SP指针内容存入uc/OS-II的一个数据结构:
ld.w [%r5],%r4 ;OSTCBCur->OSTCBStkPtr中
xcall OSTaskSwHook ; 调用用户接口函数,允许用户在任务切换时做一些工作
xld.w %r4,[OSTCBHighRdy] ; 得到要切换的任务的TCB块
xld.w %r5,OSTCBCur ; 将要切换到的任务TCB块放到当前TCB块
xld.w [%r5], %r4 ;
xld.w %r5,OSPrioHighRdy ; OSPrioCur =OSPrioHighRdy,保存要切换到的任务优先级
ld.b %r4,[%r5]
xld.w %r5,OSPrioCur
xld.b [%r5],%r4
xld.w %r5,[OSTCBHighRdy] ; SP =OSTCBHighRdy->OSTCBStkPtr,得到要切换到的
ld.w %r4,[%r5] ; 任务SP指针
ld.w %sp, %r4
popn %r1
ld.w %alr,%r1 ; 从要切换到的任务SP指针中恢复状态寄存器
ld.w %ahr,%r0
<span style="font-size:18px">popn %r15 ; 从要切换到的任务SP指针中恢复r1~r15寄存器</span>
<p><span style="font-size:18px"> </span></p>
<p><span style="font-size:18px">reti ; 从要切换到的任务SP指针中中断返回,这时自然就回到了要切换到的任务</span></p>
该函数是用汇编写的,这就很直接的说明了一个问题——这个函数和uCOS-II的移植直接相关。OSCtxSw()人为的模仿了一次中断,大多数MCU提供软件中断或陷阱指令来实现这样的操作。必须提供中断向量给汇编语言函数OSCtxSw()。任务切换很简单,将被挂起任务的微处理器寄存器推入堆栈,然后将较高优先级的任务的寄存器值从堆栈中恢复到寄存器中。在uCOS-II中,就绪任务的堆栈结构总是看起来跟刚刚发生过中断一样,所有的微处理器的寄存器都保存在堆栈中。
|