0517

来源:互联网 发布:数据库学籍管理系统 编辑:程序博客网 时间:2024/06/14 02:53

OSCtxSw()

  1. OSCtxSw()是一个任务级的任务切换函数(在任务中调用,区别于在中断程序中调用的OSIntCtxSw())。在80x86系统上,它通过执行一条软中断的指令来实现任务切换。软中断向量指向OSCtxSw()。在µC/OS-II中,如果任务调用了某个函数,而该函数的执行结果可能造成系统任务重新调度(例如试图唤醒了一个优先级更高的任务),则在函数的末尾会调用OSSched(),如果OSSched()判断需要进行任务调度,会找到该任务控制块OS_TCB的地址,并将该地址拷贝到OSTCBHighRdy,然后通过宏OS_TASK_SW()执行软中断进行任务切换。注意到在此过程中,变量OSTCBCur始终包含一个指向当前运行任务OS_TCB的指针。程序清单L9.4为OSCtxSw()的代码。  
  2. 图F9.4是任务被挂起或被唤醒时的堆栈结构。在80x86处理器上,任务调用OS_TASK_SW()执行软中断指令后[图F9.4/程序清单L9.4(1)],先向堆栈中压入返回地址(段地址和偏移量),然后是状态字寄存器SW。紧接着用PUSHA [图F9.4/程序清单L9.4(2)], PUSH ES [图F9.4/程序清单L9.4(3)],和 PUSH DS [图F9.4/程序清单L9.4(4)]保存任务运行环境。最后用OSCtxSw()在任务OS_TCB中保存SS和SP寄存器。  
  3. 任务环境保存完后,将调用用户定义的对外接口函数OSTaskSwHook()[程序清单L9.4(6)]。请注意,此时OSTCBCur指向当前任务OS_TCB,OSTCBHighRdy指向新任务的OS_TCB。在OSTaskSwHook()中,用户可以访问这两个任务的OS_TCB。如果不使用对外接口函数,请在头文件中把相应的开关选项关闭,加快任务切换的速度。  
  4.   
  5. 程序清单L 9.4   OSCtxSw().  
  6. _OSCtxSw    PROC   FAR                      (1)  
  7. ;  
  8.     PUSHA                                 ; 保存当前任务环境    (2)  
  9.     PUSH ES                                 (3)  
  10.     PUSH DS                                 (4)  
  11. ;  
  12.     MOV  AX, SEG _OSTCBCur                ; 载入DS  
  13.     MOV  DS, AX                              
  14. ;  
  15.     LES  BX, DWORD PTR DS:_OSTCBCur       ; OSTCBCur->OSTCBStkPtr = SS:S (5)  
  16.     MOV  ES:[BX+2], SS                       
  17.     MOV  ES:[BX+0], SP                       
  18. ;  
  19.     CALL FAR PTR _OSTaskSwHook  (6)  
  20. ;  
  21.     MOV  AX, WORD PTR DS:_OSTCBHighRdy+2  ; OSTCBCur = OSTCBHighRdy (7)  
  22.     MOV  DX, WORD PTR DS:_OSTCBHighRdy         
  23.     MOV  WORD PTR DS:_OSTCBCur+2, AX           
  24.     MOV  WORD PTR DS:_OSTCBCur, DX              
  25. ;  
  26.     MOV  AL, BYTE PTR DS:_OSPrioHighRdy   ; OSPrioCur = OSPrioHighRdy   (8)  
  27.     MOV  BYTE PTR DS:_OSPrioCur, AL              
  28. ;  
  29.     LES  BX, DWORD PTR DS:_OSTCBHighRdy   ; SS:SP = OSTCBHighRdy->OSTCBStkPtr    (9)  
  30.     MOV  SS, ES:[BX+2]                      
  31.     MOV  SP, ES:[BX]                        
  32. ;  
  33.     POP  DS                               ; 载入新任务的CPU环境 (10)  
  34.     POP  ES                             (11)  
  35.     POPA                                    (12)  
  36. ;  
  37.     IRET                                  ; 返回新任务   (13)  
  38. ;  
  39. _OSCtxSw    ENDP  
  40.   
  41. 从对外接口函数OSTaskSwHook()返回后,由于任务的更替,变量OSTCBHighRdy被拷贝到OSTCBCur中[程序清单L9.4(7)],同样,OSPrioHighRdy被拷贝到OSPrioCur中[程序清单L9.4(8)]。OSCtxSw()将载入新任务的CPU环境,首先从新任务OS_TCB中取出SS和SP寄存器的值[图F9.4(6)/程序清单L9.4(9)],然后运行POP DS [图F9.4(7)/程序清单L9.4(10)], POP ES [图F9.4(8)/程序清单L9.4(11)], POPA [图F9.4(9)/程序清单L9.4(12)]取出其他寄存器的值,最后用中断返回指令IRET [图F9.4(10)/ L9.4(13)]完成任务切换。  
  42. 需要注意的是在运行OSCtxSw()和OSTaskSwHook()函数期间,中断是禁止的。

原创粉丝点击