特別聲明:本筆記是對uc/os-ii研究做一些重要的核心思路整理和心得記錄,以日期為作為記錄塊,故沒有思路和規範可言,為此貼於工程師筆記裡面,一來方便自己溫故知新,二來希望能給初學者帶來一些方便和協助。高手別見笑^_^,偶剛起步。另外,如有錯誤和不當之處,請指正和發表您的心得體會。謝謝!
2005-12-18
1. 任務是一個無返回的無窮迴圈。uc/os-ii總是運行進入就緒狀態的最高優先順序的任務。
2. 任務是如何調度(切換)的?
因為uc/os-ii總是運行進入就緒狀態的最高優先順序的任務。所以,確定哪個任務優先順序最高,下面該哪個任務運行,這個工作就是由調度器(scheduler)來完成的。
任務級的調度是由函數OSSched()完成的,而中斷級的調度是由函數OSIntExt()完成。對於OSSched(),它內部調用的是OS_TASK_SW()完成實際的調度(人為模仿一次中斷);OSIntExt()內部調用的是OSCtxSw()實現調度。參考:P92,P106
任務切換其實很簡單,由如下2步完成:(1)將被掛起任務的處理器寄存器推入自己的任務堆棧。(2)然後將進入就緒狀態的最高優先順序的任務的寄存器值從堆棧中恢複到寄存器中。參見P92
(1)作為uc/os-ii的一條普通原則,調用uc/os-ii功能函數時,中斷總應當是開著的。
(2)任務永不返回,就算任務自我刪除,也絕對不會返回。(任務刪除並非代碼刪除,只是ucos-ii不會理會這任務。)
(3)OSTimeTick()函數是ucos-ii內建函式,使用者無需調用。
(4)ucos-ii從中斷返回之前,要判斷被中斷的任務是否還是就緒狀態任務中優先順序最高的任務。
3. OSInit()初始化
我做了一個很好的圖示,竟然粘貼不出來,沒辦法...
4. 任務的5種狀態
參見P79 圖
睡眠態(task dormat):任務駐留於程式空間(rom或ram)中,暫時沒交給ucos-ii處理。
就緒態(task ready):任務一旦建立,這個任務就進入了就緒態。
運行態(task running):調用OSStart()可以啟動多任務。OSStart()函數只能調用一次,一旦調用,系統將運行進入就緒態並且優先順序最高的任務。
等待狀態(task waiting):正在啟動並執行任務,通過延遲函數或pend(掛起)相關函數後,將進入等待狀態。
中斷狀態(ISR running):正在啟動並執行任務是可以被中斷的,除非該任務將中斷關閉或者ucos-ii將中斷關閉。
5. 任務控制塊(OS_TBC)
任務一旦建立,任務控制塊OS_TBC將被賦值。
OS_TBC是一個資料結構,當任務的CPU使用權被剝奪後,ucos-ii將把當前的任務狀態存放於OS-TBC資料結構中;當任務的CPU使用權得到恢複後,任務控制塊能確保任務能從被中斷點那一點絲毫不差地繼續執行。
每個任務都有自己的OS_TBC控制塊,OS_TBC的數量由OS_MAX_TASK決定,任務數量少,當然OS_TBC佔用RAM的空間就少。
所有的任務控制塊OS_TBC都是放在任務控制塊列表數組OSTCBTbl[]中。在ucos-ii初始化時,所有任務控制塊OS_TBC都被鏈表串連成單向空任務鏈表。
注意:OS_TBC全部駐留於RAM中。
6. 關於任務切換使用到的OS_TASK_SW()函數,其中調用非強制中斷實現寄存器的保持和彈出。開始調用含非強制中斷,ucos-ii強制處理器儲存psw、pc的當前值,最後通過執行中斷返回指令,pc和psw的值裝回到cpu中。
2005-12-21
1.中斷服務所做的事應盡量少做,應把大部分工作留給任務去做。
2.OSIntExit()和OSSched()有點相似,但OSIntExit()使中斷nestiing減1,而重新調度的條件是:中斷nesting和鎖定nesting計算機(OSLockNesting)均為0。
3.OS_TASK_SW()和OSCtxSw()的區別:後者使用於中斷服務程式中,中斷返回已經對cpu做了儲存工作。而前者需要採用模仿非強制中斷返回指令實現cpu儲存。
4.時鐘節拍
(1) ucos-ii需要提供周期性的訊號源,用於實現時間延遲和確認逾時。節拍率應為10~100Hz,時鐘節拍率越高,系統額外的負荷就越重。
(2) 系統多任務啟動時候(調用OSStart())之後,第一件初始化事情就是初始化定時中斷。
(3) ucos-ii中的時鐘節拍服務是通過在中斷服務子程式(OSTickISR())中調用OSTimeTick()實現的。OSTimeTick()跟蹤所以任務的定時器和逾時時限。時鐘節拍中斷服從一般中斷規則(含任務調度判斷)。
5.OSTCBList指向任務控制塊鏈表的開始,而且它總是指向最建立立的任務。
6.非常好的一個圖示:OSInt()之後的變數和資料結構。請參閱P112
7.啟動多任務時,執行OSStart()函數,OSStart()先從任務就緒表中找出使用者建立的優先順序最高的任務的任務控制塊,而後調用了OSStartHighRdy(),此函數實質上是將任務堆棧中的儲存內容返回到cpu寄存器中,然後執行一條中斷返回指令。
【訊號量專題】
1. 訊號量的理解
(1)uc/os-ii的訊號量是由兩個部分組成:一部分是16位的無符號整型訊號量的計數值(0~65535);另一部分是等待該訊號量的工作群組成的等待任務表。(另外參考事件控制塊ECB)
(2)訊號量可以是2值的變數(稱為二值訊號量),也可以是計數式的。根據訊號量的值,核心跟蹤那些等待訊號量的任務。
(3)建立訊號量的工作必須在任務級代碼中或者多任務啟動之前完成。
(4)任務要得到訊號量的問題。
想得到訊號量的任務,必須執行等待操作(pend)。如果訊號量有效(非0),則訊號量減1,任務得以繼續運行。如果訊號量無效,則等待訊號量的任務就被列入等待訊號量的任務表中。多少核心允許定義等待逾時,當等待時間超過了設定值,該訊號量還是無效,則等待該訊號量的任務進入就緒態,準備運行,並返回出錯代碼(等待逾時錯誤)。
(5)任務對訊號量的釋放問題。
任務執行發訊號(post)操作來釋放訊號量。如果沒有任務等待訊號量,那麼訊號量的值僅是簡單的加1(則訊號量大於0,有效);如果有任務等待該訊號量,那麼就會有另一個任務進入就緒態,訊號量的值就不加1。
之後,這個釋放的訊號量給那個等待中的任務,要看核心如何調度的。收到訊號量的任務可能是如下兩者之一:
◆等待任務中,優先順序最高的;(uc/os-ii僅支援這種方式)。
◆最早開始等待訊號量的任務(如果是按先進先出FIFO原則)。
2. 訊號量的有效與無效問題
訊號量有效:訊號量的計算機非0(.OSEventCnt!=0)。訊號量有效表示任務對資源可用。
訊號量無效:訊號量的計算機為0。訊號量無效表示任務對目前資源不可用,需要等待其他另一個任務(或者中斷服務子程式)發出該訊號量(OSSemPost)。
3. 訊號量的值(.OSEventCnt)大小表示什嗎?
二值訊號量,表示任務可以獨佔共用資源。
計數式訊號量,用於某資源可同時為N個任務所用。
4. 訊號量是如何?任務之間的通訊的?
參見第1點的(4)(5)概述。
5. 訊號量有關的三個重要函數分析
◆OSSemCreate() 建立一個訊號量 (註:由任務或啟動代碼操作)
建立工作必須在任務級代碼中或者多任務啟動之前完成。功能只要是先擷取一個事件控制塊ECB,寫入一些參數。其中調用了OS_EeventWaitListInt()函數,對事件控制塊的等待工作清單進行初始化。完成初始化工作後,返回一個該訊號量的控制代碼(Handle)。
◆OSSemPend() 等待一個訊號量 (註:只能由任務操作)
本函數應用於任務試圖獲得共用資源的使用權、任務需要與其他任務或中斷同步及任務需要等待特定事件發生的場合。
如果任務Task_A調用OSSemPend(),且訊號量的值有效(非0),那麼OSSemPend()遞減訊號量計數器(.OSEventCnt),並返回該值。換句話說,Task_A擷取到共用資源的使用權了,之後就執行該資源。
如果如果任務Task_A調用OSSemPend(),訊號量無效(為0),那麼OSSemPend()調用OS_EventTaskWait()函數,把Task_A放入等待列表中。(等待到什麼時候呢?要看OSSemPost()(或者等待逾時情況),由它釋放訊號量並檢查任務執行權,見下資料)
◆OSSemPost() 發出(釋放)一個訊號量 (註:由任務或中斷操作)
本函數其中調用OS_EventTaskRdy()函數,把優先順序最高的任務Task_A(在這假如是Task_A,另外假設當前調用OSSemPost()的任務是Task_B)從等待工作清單中去除,並使它進入就緒態。然後調用OSSched()進行任務調度。如果Task_A是當前就緒態中優先順序最高的任務,則核心執行Task_A;否則,OSSched()直接返回,Task_B繼續執行。
2006-2-10
互斥型訊號量
1.互斥型訊號量(mutex)
互斥型訊號量具備uc/os-ii訊號量的所有機制,但還具有其他一些特性。
任務可利用互斥型訊號量來實現對共用資源的獨佔處理。
Mutex是二值訊號量,1表示資源是可以使用的。
2.關於優先順序反轉
下面概述優先順序反轉原理:
假設有三個任務,分別命名為A,B,C;A的優先順序最高,C的優先順序最低。任務A和任務B處於掛起狀態(請注意這條件),等待某一事件的發生,任務C正在運行。當任務C等待到共用資源(命名為S1)並使用後,如果任務A等待得事件到來之後,由於A的優先順序最高,所以就會剝奪任務C的CPU使用權。運行過程中,任務A也要使用資源S1,但S1的訊號量還被任務C佔用著,所有任務A只能進入掛起狀態,等待任務C對S1的訊號量的釋放。此時任務C得以繼續運行。
同理,任務B的事件到來後,會剝奪任務C的CPU使用權。任務B把事情搞定以後,把CPU使用權歸還給任務B(呵呵,優先順序低就是給人欺負啊,所以做人還真的要爭口氣!)。任務B又得以繼續運行,任務B認真處理完畢資源S1後,終於可以釋放S1的訊號量。而處於等待該訊號量的任務A馬上得到訊號量並開始處理共用資源S1。
綜述上面情況,任務C和任務A的優先順序發生了反轉。
而互斥型訊號量就是具有解決優先順序反轉問題的特性。
3.uc/os-ii的互斥型訊號量由三個部分組成:
◆一個標誌,指示mutex是否可以使用(0或1)
◆一個優先順序,準備一旦高優先順序的任務需要這個mutex,賦予給佔有mutex的任務。
◆一個等待該mutex的工作清單。
http://bbs.ednchina.com/BLOG_ARTICLE_107600.HTM