3.任務管理機制

任務的概念

在實際應用中一般是將工作拆分爲多個任務的,並且每個任務都是可靠的。在使用uC/OS就可以很好的解決這個問題,任務又叫線程,在對於單個CPU來說,在任何時刻,都是只能有有一個任務被執行。

uC/OS-III 支持多任務且對任務數量沒有限制,任務數僅取決於處理器內存的大小(RAM)。多任務調度是任務間佔用CPU 的過程。CPU 有根據算法切換任務。多任務調度讓人感覺到是有多個CPU在運行,並最大化利用CPU。多任務調用有助於模塊化應用,是最重要的功能之一,能幫助程序員管理複雜的實時性應用。它也使程序易於設計和維護。
任務用於監控輸入、更新輸出、計算、循環控制、顯示、讀按鈕和鍵盤、與其它系統交流等。有些應用中可能只包含少數任務,有些應用中也可能包含上百個任務。任務數多並不意味這設計有多好或者有多有效,這依賴於應用的需要。任務的功能也要根據應用設計。一個任務可能只需要工作幾微秒,然而有些任務可能就需要工作幾十毫秒了。
在大多數嵌入式系統中,任務通常是無限循環的。任務不能像C 函數那樣,它是不能return 的。

當任務第一次執行時,會傳入一個變量"p_arg"。這是一個指向void的指針。用於變量的地址、結構體地址、或者函數的地址等。只運行一次的任務結束時必須通過調用OSTaskDel()刪除自己。這樣可以使系統中的任務數減少。在任務體中,任務可以調用uC/OS-III提供的大部分函數幫助完成其所需要完成的功能。

uC/OS-III 需要通過調用函數OSTaskCreate() 創建任務。OSTaskCreate()函數的原型如下所示


關於創建任務的詳細參數,前面也有說過了創建一個任務時必須爲其分配一個TCB(Task Control Block,會存放任務優先級、任務名、任務狀態、內部消息隊列、內部信號量等),一個堆棧,一個優先級和其它一些參數。

接下來, 會調用一些定義在OS_CPU_C.C 中的函數如OSTaskCreateHook(),TCB 中有指針指向這個函數,用於擴展應用。例如,可以打印最新創建的TCB 內容到某終端(利於調試)。然後該任務被放到就緒列表(詳見第六章"就緒列表")。uC/OS-III調用調度器,並切換到優先級最高的任務。

 一.任務優先級的設置

有些時候任務的優先級是顯而易見的,多數系統中,不是所有的任務都是重要的,不重要的任務應該被設置爲低優先級。

二.堆棧空間大小的確定

堆棧的大小取決於該任務的需求。設置堆棧大小時,就需要考慮:所有可能被堆棧調用的函數及其函數的嵌套層數,相關局部變量的大小,中斷服務程序所需要的空間。另外,堆棧還需要存入CPU寄存器,如果處理浮點數單元FPU寄存器的話就還需要存入FPU寄存器。嵌入式系統的潛規則,避免寫遞歸函數。在產品的開發和測試階段,通常在運行時用調試器測量堆棧的使用情況。

三.檢測任務堆棧的溢出

比較複雜,後文再寫,因爲不是很懂

四.任務管理服務

uC/OS-III 提供了很多與任務相關的函數。這些函數可以在OS_TASK.C 中找到,它們都以以OSTask***()形式命名的。如下
分組 函數
普通的 OSTaskCreate():創建人物
OSTaskDel():刪除任務
OSTaskChangePrio():修改任務優先級
OSTaskRegSet():任務寄存器設置
OSTaskRegGet():獲取當前寄存器的值
OSTaskSuspend():取消任務
OSTaskResume():恢復任務
OSTaskTimeQuantaSet():更改任務時間片
OS_TaskInit():任務初始化
OS_TaskInitTCB():初始化堆棧的默認值
標記任務 OSTaskSemPend():等待接收任務信號量
OSTaskSemPost():表示等待任務的信號
OSTaskSemPendAbort():終止等待任務信號
OSTaskSemSet():設置清除信號計數器
OSTaskStkChk():被用來檢測堆棧後剩餘內存量
給任務發送消息 OSTaskQPend():等待接收一個消息
OSTaskQPost():發送信息給任務
OSTaskQPendAbort():中止等待消息
OSTaskQFlush():刷新內部任務消息隊列
OS_TaskResume():恢復一個已經移除的任務
在源代碼中,針對每個函數都有很詳細的解說是什麼,該怎麼用,這邊不再說明

五.內部任務管理

1任務狀態

從用戶的觀點來看,任務可以是有5 種狀態,如下。展示了任務狀態間的轉換關係。{休眠狀態,就緒狀態,運行狀態,掛起狀態,中斷狀態}


(1)處於休眠狀態的任務駐留於內存但未被uC/OS-III 使能。通過調用OSTaskCreate()函數uC/OS-III 創建任務。任務代碼是存在於ROM 的。但需要用OSTaskCreate()函數通知uC/OS-III 關於任務的相關信息。如果任務的使命完成了,就要調用OSTaskDel()刪除該任務。OSTaskDel()實際上不是刪除任務的代碼,只是讓任務不再具有使用CPU 的資格而已。
(2)就緒狀態的任務根據優先級有序地排列於就緒列表中。就緒列表中對就緒任務的個數沒有限制。
(3)正在運行的任務被置爲運行狀態。在單CPU 中,任何時刻只能有一個任務被運行。當應用程序調用OSStart() 或者調用OSIntExit() 或者調用OS_TASK_SW()時uC/OS-III 從就緒隊列中選擇優先級最高的任務去運行。正如前面所提到的,有些時候任務必須等待某些事件發生,若事件還未發生時,任務就會被設置爲掛起狀態。
(4)掛起狀態的任務被放置在掛起列表中以表明任務在等待某些事件的發生。等待的時候,任務是不會佔用CPU 的。事件發生時,該任務會被放到就緒隊列中。在這種情況下,正在運行的任務可能會被搶佔(被放回就緒列表),並由uC/OS-III 選擇優先級最高的任務去運行。換句話說,如果新的任務優先級最高,那麼它就會被立即運行。請注意,調用OSTaskSuspend()會任務無條件地停止運行。有些時候調用OSTaskSuspend()不是爲了等待某個事件的發生,而是等待另一個任務調用OSTaskResume()函數恢復這個任務。
(5)若中斷髮生,中斷會掛起正在執行的任務並去處理ISR。ISR中可能有某些任務等待的事件。一般來說,中斷用來通知任務某些事件的發生,並讓在任務級處理實際的響應操作。ISR 程序越短越好,實際響應中斷的操作應該被設置在任務級以便能讓uC/OS-III 管理這些操作。ISR 中只允許調用一些提交函數(OSFlagPost(),OSQPost()OSSemPost() , OSTaskQPost() , OSTaskSemPost()) , 除了OSMutexPost()。因爲mutex 只允許在任務級被修改。大多數處理器支持中斷嵌套。然而,如果管理不當,中斷
嵌套是很容易引起堆棧溢出的。


uC/OS-III 一直追蹤着任務的狀態如下圖。事實上,這些都是以一個變量的形式保存在每個任務的TCB 中。圖小括號中的數值表示着任務的狀態,每個任務都可以有8 種狀態。

(0)狀態0 表示任務已經就緒。每個任務在被運行之前都必須處於就緒狀態。
(1)任務可以通過調用OSTimeDly()或者OSTimeDlyHMSM()等待期滿。當期滿或者延時刪除時(通過調用OSTimeDlyResume()),任務會轉爲就緒狀態。
//////這是一天的進程,但爲了章節比較好看,只能列爲一個章節
(2)任務可以通過調用掛起函數(OSFlagPend(),OSMutexPend(),OSQPend,OSSemPend,OSTaskQPend(),OSTaskSemPend())等待某事件的發生。當事件發生時、該任務被刪除、或者被另一個任務取消等待時,等待停止。
(3)如前面所說,任務可以等待事件發生。但任務也可以被設置等待多少時間。如果在這段時間內事件沒有發生,任務也會被設爲就緒狀態,並通知這個任務是等待超時而被掛起的。{掛起函數都有一個關於函數執行結果錯誤代號,可以查看這個代號知道任務是因何被就緒的}
(4) 任務暫停自己或者被其他任務暫停( 通過調用OSTaskSuspend())。暫停中的任務只能通過調用OSTaskResume()被恢復。
(5)一個延時中的任務也可以被其它任務設置爲停止。在這種情況下,效果會被疊加。換句話說,延時需被執行、停止狀態需被解除。該任務纔會被執行。
(6)一個掛起狀態中的任務也可能被其它任務設置爲停止。同樣的,效果會被疊加。事件發生且停止狀態被移除後,任務纔會被執行。
(7)任務可以等待事件的發生,但可以給它設定一個期限。同樣的,它也可能被設爲停止,效果是疊加的。除非移除停止狀態並事件發生或等待事件超時,任務纔會被執行。

2 任務控制塊 TCB

任務控制塊是被uC/OS-III 用於維護任務的一個結構體。每個任務都必須有自己的TCB。uC/OS-III 在RAM 中分配TCB。當調用uC/OS-III 提供的與任務相關的函數(以OSTask???()形式命名)時,任務的TCB 地址需會被提供給該函數。TCB 的結構定義於OS.H 中,由於結構體太長,這邊不做截圖了,可以參見OS.H中struct os_tcb {}結構體,裏面有相對詳細的介紹。TCB 中的一些變量可以根據具體應用進行裁剪。用戶程序不應該訪問這些變量(尤其不能更改它們)。換句話說,TCB 中的變量只能被uC/OS-III 訪問
這邊要是解釋的話,需要太長的字段,實在是意義不大,源碼OS.H 文件寫的還比較好理解。

 



















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章