任務切換,又稱上下文切換(context switch)是實現操做系統的基礎。bash
基於CM3實現任務切換必需要有如下2點概念認識函數
PendSV叫作可懸起系統調用,與之相對的叫作系統服務調用(SVC)。操作系統
二者的區別是SVC異常必須在執行SVC指令後當即獲得響應,若是由於優先級或者其餘緣由沒法當即響應,就會上訪成硬fault。而PendSV則能夠像普通中斷同樣被懸起(pending),從而等待其餘優先級更高的中斷被響應完畢後執行。rest
在實現任務切換的操做系統中,每每會把PendSV的中斷優先級設爲最低。這樣在進行任務切換時,只須要將PendSV懸起寄存器置位便可。PendSV的中斷處理子程序會在全部高優先級中斷響應完後開始進行任務切換。code
在ucos中任務切換代碼十分簡單:it
OSCtxSw LDR R0, =NVIC_INT_CTRL LDR R1, =NVIC_PENDSVSET //trigger PendSV STR R1, [R0] BX LR
相對應的PendSV處理函數:class
OS_PendSV_Handler CPSID I /* 寄存器保存和恢復 */ Save & Restore registers CPSIE I BX LR
任務切換的本質是實現寄存器的保存和恢復。在CM3中經過堆棧操做能快速的進行任務切換,爲OS節約下不小的開銷。基礎
1. 中斷入棧硬件
當CM3開始響應一箇中斷時,會硬件自動把xPSR、PC、LR、R十二、R3 - R0壓入堆棧中程序
2. 手動入棧
除了自動入棧的寄存器外,在任務切換中斷子程序(PendSV ISR)中,咱們還須要手動把R4 - R11壓入堆棧中,從而實現完整現場保護。
舊SP(N - 0) 原先已壓棧的內容 (N - 4) xPSR (N - 8) PC (N - 12) LR (N - 16) R12 (N - 20) R3 (N - 24) R2 (N - 28) R1 (N - 32) R0 --------------------------- 手動入棧 (N - 36) R11 (N - 40) R10 (N - 44) R9 (N - 48) R8 (N - 52) R7 (N - 56) R6 (N - 60) R5 (N - 64) R4 ---> 新SP
在ucos能夠看到響應的實現
OS_PendSV_Handler: .......... //save SUBS R0, R0, #0x20 ;8 registers STM R0, {R4-R11} .......... //restore LDM R0, {R4-R11} ADDS R0, R0, #0x20