1 UCOS知識點
(1) UCOS是可剝奪型的多任務內核。當一個高優先級的任務准備就緒,並且此時發生了任務調度,那么高優先級的任務就會獲得CPU的使用權。
(2) 任務調度就是終止當前正在運行的任務轉而去執行其他的任務。
(3) 每個任務都有自己的任務控制塊:OS_TCB類型(結構體類型)。用來維護任務相關的信息,比如任務棧頂地址、棧的容量、任務當前狀態等信息。OS_TCB存儲於RAM中。
(4) 每個任務都有自己的棧:OS_STK類型(數組)。棧可以靜態分配,也可以使用malloc()函數從堆中動態分配。由於頻繁創建和刪除任務會導致內存碎片產生,因此一般棧空間不需要被釋放掉。棧作用一是保存任務的局部變量;二是當任務掛起時保存CPU寄存器的值(也就是現場)。
(5) 任務可以訪問全局變量,但是全局變量會被多個任務共享,且任務是可剝奪型的,因此這樣做不安全,UCOS提供了保護機制(信號量,互斥信號量)。
2 UCOS任務切換
(1) 任務處於休眠態(指任務已存在存儲器中,但還不受UCOS管理);
(2) 通過OSTaskCreate()函數,任務處於就緒態;任務就緒表保存已經就緒的的任務。
(3) 此時發生了任務調度。任務調度有兩種:1.任務級調度器OSSched();2.中斷級調度器OSIntExit()
OSSched():
(1)掃描就緒任務表中就緒任務中優先級最高的任務;
(2)獲取到優先級最高任務的控制塊;
(3)把當前任務CPU寄存器里的值保存到棧里面,並把CPU堆棧指針寄存器(TSP)的值存放到OS_TCB中;
(4)把新任務OS_TCB中保存的TSP值載入到CPU堆棧指針寄存器(TSP);
(5)從新的堆棧中恢復CPU寄存器的值,此時新的任務就運行了。
OSIntExit():
(1)中斷嵌套計數器OSIntNestingCtr減1
(2)如果OSIntNestingCtr=0,也就是最后一層嵌套的中斷(再返回就到任務級了),並且調度器沒有上鎖
(3)獲取到優先級最高任務的控制塊;
(4)因為在進入中斷服務程序前任務的現場已經保存了,因此這里不用再保存;
(5)把新任務OS_TCB中保存的TSP值載入到CPU堆棧指針寄存器(TSP);
(6)從新的堆棧中恢復CPU寄存器的值,此時新的任務就運行了。
備注:
OSSched()實際是調用了OS_TASK_SW(),OS_TASK_SW()是調用了OSCtxSw(),而OSCtxSw()實質是進入異常中斷服務程序OS_CPU_PendSVHandler
3 任務調度點
3.1 會調用OSSched()的情況:
(1)給另一個任務發送消息或信號量,OS??? Post()
(2)任務調用延時函數OSTimeDly()或OSTimeDlyHMSM()
(3)任務在等待一個時間的發生(消息或者信號量)OS??? Pend()
(4)任務取消等待OS??? PendAbord()
(5)創建一個更高優先級的任務OSTaskCreate()
(6)當前任務被刪除OSTaskDel()
(7)任務自身被掛起OSTaskSuspend()
(8)用戶直接調用OSSched()
3.2 會調用OSIntExit()的情況:
當所有的中斷嵌套結束時,在返回任務前要調用OSIntExit()函數