UCOS-II移植ARM的讀書筆記(12.17)續

 內核結構
1臨界段,OS_ENTER_CRITICAL和OS_EXIT_CRITICAL
  開關中斷的實現方法分三種:
  1)直接用處理器指令
  2)在堆棧中保存中斷的開關狀態,然後再關中斷。
  3)通過編譯器提供的c函數來保存處理器狀態字的值。
 
2任務
 
3任務狀態
  睡眠態:在ROM或RAM中,交給UCOS要調用下面兩個函數之一:OSTaskCreate或者OSTaskCreateExt,調用之後告訴了UCOS任務的起始地址,優先級,要使用多少棧空間。
  就緒態:建立了任務之後,就進入就緒態。如果是由任務建立的新任務且優先級更高,那麼新建的任務將立即得到CPU使用權。通過OSTaskDel將一個任務返回到睡眠態。
  運行態:調用OSStart可以啓動多任務,該函數運行用戶初始化代碼中已建的優先級最高的任務。
  等待態:正在運行的任務通過兩個函數將自己延遲即進入等待狀態。OSTimeDly或者OSTimeDlyHMSM。這兩個函數將會立即執行強制任務切換,讓下一個優先級最高且進入就緒態的任務運行。當延時時間到後,系統服務函數OSTimeTick將會讓等待的任務進入就緒態。在運行中的任務如果調用OSFlagPend、OSSemPend、OSMutexPend、OSMboxPend或者OSQPend時時間並沒有發生,那麼該任務就進入等待態,此時最高優先級的就緒態任務進入運行態。當等待事件發生或者等待超時,該任務就從等待態進入就緒態。
  中斷服務態:正在運行的任務可以被中斷。被中斷了的任務進入中斷服務態。響應中斷時該任務被掛起,中斷服務子程序可能報告多個事件發生,從而使得更高優先級的任務進入就緒態,當中斷返回時會重新判斷優先級,讓最高優先級的任務運行,如果由更高優先級的任務那麼先執行,直到被掛起的任務的優先級最高才會返回到被中斷掛起的任務。
 
4任務控制塊TCB
  當任務建立的時候一個任務控制塊TCB就被賦值,任務控制塊能確保任務從被中斷的那一點絲毫不差的繼續運行。OS_TCB全部駐留在RAM中。OS_TCB中包括:指向當前任務堆棧棧頂的指OSTCBStkPtr、指向用戶定義的任務控制塊擴展OSTCBExtPtr(該擴展數據結構包含任務名字、跟蹤某個任務的執行事件、跟蹤切換到某個任務的次數)、指向任務堆棧棧底的指針OSTCBStkBottom(如果堆棧指針遞減則指向任務使用的棧空間的最低地址)、存有棧中可容納的指針元數目OSTCBStkSize(是指針元數目,乘以地址寬度即爲實際棧容量)、選擇項OSTCBOpt(傳給OSTaskCreateExt)、用於存儲任務的識別碼OSTCBId、用於任務控制塊雙向鏈表的前後鏈接OSTCBNext/OSTCBPrev、指向事件控制塊的指針OSTCBEventPtr、指向傳遞給任務的消息的指針OSTCBMsg、指向事件標誌節點的指針OSTCBFlagNode、使任務進入就緒態的事件標誌OSTCBFlagsRdy、延時或者掛起一段事件時用來計時的變量OSTCBDly、任務的狀態字OSTCBStat(OS_STAT_READY-就緒態)、任務的優先級OSTCBPrio、用於加速任務進入就緒態的過程或進入等待事件發生狀態的過程OSTCBX/OSTCBY/OSTCBBitX/OSTCBBitY、一個表示該任務是否須刪除的布爾量OSTCBDelReq。所有的任務控制塊OS_TCB都是放在任務控制塊列表數組OSTCBTbl【】中。所有任務控制塊OS_TCB都被鏈接成單向空任務鏈表。任務一旦建立,空任務控制塊指針OSTCBFreeList指向的任務控制塊便賦給了該任務。任務建立時,任務建立函數調用任務控制塊初始化函數OS_TCBInit。在初始化OS_TCB的時候調用了用戶自定義的函數OSTCBInitHook和OSTaskCreateHook函數。兩個函數都是擴展作用的。當新建的任務塊要插入表中時先要關中斷,新任務的控制塊總是插在OSTCBList表的開頭。
 
5就緒表
  每個就緒的任務都放在就緒表中,就緒表中有2個變量OSRdyGrp和OSRdyTbl【】。OSRdyGrp中任務按優先級分組,8個任務一組,8位表示8組任務中每組是否有進入就緒態的任務。進入就緒態後,就緒表OSRdyTbl【】中相應元素的相應位置1。因此,使任務進入就緒態的程序爲:
OSRdyGrp                 |=  OSMapTbl[prio>>3];
OSRdyTbl[prio>>3]  |=  OSMapTbl[prio & 0x07];  OSMapTbl[]是屏蔽字,將0-7的下標轉換成各自位置1的8位值
  通過優先級判定表OSUnMapTbl查找任務的優先級,即OSUnMapTbl[OSRdyGrp]×8+OSUnMapTbl[OSRdyTbl[OSUnMapTbl[OSRdyGrp]]]。得到優先級後,查任務控制塊優先級表OSTCBPrioTbl【】得到指向相應任務的任務控制塊OS_TCB。
 
6任務調度
  任務級的調度是由OSSched完成,中斷級的調度是由函數OSIntExt完成的。任務調度函數將找出優先級最高的進入就緒態的任務,檢查該任務是否是當前正在運行的任務,如果不是才進行任務調度。爲了實現任務的切換將該任務的控制塊從任務控制塊優先級表中取出並賦給OSTCBHighRdy,將統計切換次數的變量加1來跟蹤任務切換次數。最後就可以使用宏調用OS_TASK_SW完成實際上的任務切換
  任務切換:將被掛起任務的寄存器推入堆棧再將準備運行的任務的寄存器從棧中恢復到寄存器。因此UCOS運行就緒態任務要做的就是恢復所有的CPU寄存器並運行中斷返回指令。這裏是一段重點,爲了實現任務切換,運行OS_TASK_SW人爲模仿了一次中斷。在ARM中由軟中斷指令來實現上述操作。必須給彙編語言函數OSCtxSw提供中斷向量。OSCtxSw除了需要OS_TCBHighRdy指向即將被掛起的任務,還需讓當前任務控制塊OSTCBCur指向即將被掛起的任務。OSCtxSw掛起了正在執行的任務而讓CPU執行更重要的任務。
 
7任務級的任務切換OSCtxSw
  OSCtxSw是宏調用通常含有軟中斷指令,切換是靠中斷級代碼完成的。UCOS將與實際處理器相關的軟件中斷機制封裝起來易於移植。P93-P95詳細介紹了整個過程。恩。。大概明白了任務切換的實現方式,爲我理解移植工作打下了不小的基礎啊。。。。
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章