原创 UCOS-II中软中断实现任务切换

2010-7-28 10:57 3102 6 6 分类: MCU/ 嵌入式
以前用8位单片机时,中断分内部中断和外部中断,内部中断是定时器产生的。UCOS中涉及到了软中断。通过这段时间的学习,我觉得只有理解了软中断,才算了解了UCOS任务调度的基础。
UCOS中任务调度是调用OS_SCHED()函数实现的,当有优先级更高的任务就绪时,就会进行任务调度,在OS_SCHED()函数最后通过调用宏OS_TASK_SW()来完成任务切换。
在OS_CPU.H中定义了
#define  OS_TASK_SW()         OSCtxSw()
OSCtxSw()是在OS_CPU_A.ASM中定义的。
_OSCtxSw    PROC   FAR
;
            PUSHA                                  ; Save current task's context
            PUSH   ES                              ;
            PUSH   DS                              ;
;
            MOV    AX, SEG _OSTCBCur               ; Reload DS in case it was altered
            MOV    DS, AX                          ;
;
            LES    BX, DWORD PTR DS:_OSTCBCur      ; OSTCBCur->OSTCBStkPtr = SS:SP
            MOV    ES:[BX+2], SS                   ;
            MOV    ES:[BX+0], SP                   ;
;
            CALL   FAR PTR _OSTaskSwHook           ; Call user defined task switch hook
;
            MOV    AX, WORD PTR DS:_OSTCBHighRdy+2 ; OSTCBCur = OSTCBHighRdy
            MOV    DX, WORD PTR DS:_OSTCBHighRdy   ;
            MOV    WORD PTR DS:_OSTCBCur+2, AX     ;
            MOV    WORD PTR DS:_OSTCBCur, DX       ;
;
            MOV    AL, BYTE PTR DS:_OSPrioHighRdy  ; OSPrioCur = OSPrioHighRdy
            MOV    BYTE PTR DS:_OSPrioCur, AL      ;
;
            LES    BX, DWORD PTR DS:_OSTCBHighRdy  ; SS:SP = OSTCBHighRdy->OSTCBStkPtr
            MOV    SS, ES:[BX+2]                   ;
            MOV    SP, ES:[BX]                     ;
;
            POP    DS                              ; Load new task's context
            POP    ES                              ;
            POPA                                   ;
;
            IRET                                   ; Return to new task
;
_OSCtxSw    ENDP
程序调用OSCtxSw()函数时,就产生软件中断,强制处理器保存当前任务的状态寄存器和PC值到当前任务的堆栈,然后在_OSCtxSw程序中把CPU的重要寄存器内容都保存进当前任务的堆栈。
然后把高优先级任务堆栈中的寄存器值送到对应的CPU寄存器,最后执行中断返回指令,把高优先级任务堆栈中的状态寄存器和PC值送到CPU的状态寄存器和PC寄存器中。程序就从当前PC寄存器指向的地址开始执行。这就完成了任务切换。
执行OSCtxSw()函数就类似于51中产生了一次中断,不同的是,51产生中断后,执行完中断程序,退出中断,然后从产生中断的地方继续往下执行。UCOS中,调用完OSCtxSw()后,执行的是另外一个优先级更高的任务.
UCOS-II假定任务切换是靠中断级代码完成的。一种任务切换是调用OSCtxSw()函数产生软件中断。还有一种任务切换是硬件产生中断,执行完硬件中断程序后,如果有更高优先级的任务就绪。就进行任务切换。原理和上面说的类似。

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
6
关闭 站长推荐上一条 /7 下一条