1. 程式人生 > >uCOS-II核心之任務排程 [轉載]

uCOS-II核心之任務排程 [轉載]

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()的更詳盡的解釋。