uCOS-II核心之任務排程 [轉載]
阿新 • • 發佈:2019-01-27
uCOS-II核心學習之任務排程
實現任務切換,需要呼叫函式OSSched()。
OSSched()程式程式碼如下所示:void OSSched (void) { INT8U y; OS_ENTER_CRITICAL(); if ((OSLockNesting | OSIntNesting) == 0) //(1) { y = OSUnMapTbl[OSRdyGrp]; //(2) OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]); if (OSPrioHighRdy != OSPrioCur) //(3) { OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; //(4) OSCtxSwCtr++; //(5) OS_TASK_SW(); //(6) } } OS_EXIT_CRITICAL(); }
其基本實現原理大致是先找出優先順序最高的任務,OSTCBHighRdy指向優先順序最高任務的任務控制塊,接著呼叫巨集OS_TASK_SW(),巨集OS_TASK_SW()完成實質性任務切換工作。
下面具體瞭解下程式碼的作用。
1、首先判斷是不是在在中斷子函式中呼叫,任務排程有沒有上鎖(1)。
2、如果不是在中斷子函式中呼叫,並且任務排程沒有上鎖,找出就緒表中優先順序最高的任務(2)。
3、檢驗這個優先順序最高的任務是不是當前正在執行的任務,以此來避免不必要的任務排程(3)。
4、 如果不是,OSTCBHighRdy指向優先順序最高的那個任務控制塊OS_TCB(4)。
5、OSCtxSwCtr加1,這個值是記錄任務切換次數的。
6、最後巨集呼叫OS_TASK_SW()來完成實際上的任務切換,這個巨集是我們在移植uCOS-II 時編寫的。
任務切換很簡單,由以下兩步完成,將被掛起任務的微處理器暫存器推入堆疊,然後將較高優先順序的任務的暫存器值從棧中恢復到暫存器中。在μC/OS-Ⅱ中,就緒任務的棧結構總是看起來跟剛剛發生過中斷一樣,所有微處理器的暫存器都儲存在棧中。換句話說,μC/OS-Ⅱ執行就緒態的任務所要做的一切,只是恢復所有的CPU暫存器並執行中斷返回指令。為了做任務切換,執行OS_TASK_SW(),人為模仿了一次中斷。多數微處理器有軟中斷指令或者陷阱指令TRAP來實現上述操作。中斷服務子程式或陷阱處理(Trap hardler),也稱作事故處理(exception handler),必須提供中斷向量給組合語言函式OSCtxSw()。OSCtxSw()除了需要OS_TCBHighRdy指向即將被掛起的任務,還需要讓當前任務控制塊OSTCBCur指向即將被掛起的任務,有關於OSCtxSw()的更詳盡的解釋。