本章主要對 uC/OS-III 實時操作系統做一些概要介紹,使讀者對 uC/OS-III 有個整體的淺
認識,為后面的章節的詳細講解做一個鋪墊。
下圖是 uC/OS-III 系統從底層到上層的文件結構。
①配置文件,通過定義這些文件里宏的值可以輕易地裁剪 uC/OS-III 的功能。
②用戶應用文件, 定義和聲明應用任務。
③內核服務文件,其代碼與 CPU 無關,可以不做任何修改移植到任何 CPU。 本書主要講解這部分內容。
④底層函數庫,比如字符串的常規操作, 常用的數學計算, 等等。
⑤CPU 移植文件, 用戶如果想要移植 uC/OS-III 到不同平台上,需要修改這部分代碼。
⑥CPU 配置文件,主要是 CPU 的一些工作模式和服務函數。
⑦其他 CPU 相關文件。
uC/OS-III 數據結構
uC/OS-III 中的內核對象大多都是以結構體的形式存在的,例如出現最多的任務的任務控
制塊的數據結構如下所示,結構體中的每個成員代表任務具有的一種屬性。在結構體中,可
以看到很多宏,通過定義這些宏,就可以輕易地裁剪任務控制塊具有的屬性(任務的功能)。
不再一一列舉。
在 uC/OS-III 中,對內核對象的管理大多采用線性鏈表的數據結構,包括單向鏈表和雙
向鏈表。鏈表就是將要管理的對象按照方便管理的規則一個接一個串聯在一起,提高管理效
率。
任務
在 uC/OS-III 中,可以創建無數多個任務, 讓這些任務並發運行,就好像有多個主函數
在運行一樣。 在 uC/OS-III 初始化的時候, 至少會創建空閑任務 OS_IdleTask()和時基任務
OS_TickTask()這兩個任務, 另外還有三個可選擇的內部任務,軟件定時器任務
OS_TmrTaks() 、中斷延遲提交任務 OS_IntQTask()和統計任務 OS_StatTask()。
從用戶的角度來看, uC/OS-III 中的任務可以分為 5 種狀態, 分別是休眠態、就緒態、
運行態、掛起態和中斷態, 如下表所示。
從 uC/OS-III 任務管理的角度來看, uC/OS-III 中的任務 9 種狀態, 如下表所示。 分別是
休眠態、就緒態、運行態、掛起態和中斷態,如下表所示。
軟件定時器
軟件定時器的功能跟硬件定時器一樣,主要用於定時,但其精度達不到硬件定時器的標
准,可以用於定時一些精度要求不是特別嚴格的事件。理論上, uC/OS-III 可以創建無數個
軟件定時器,這是硬件定時器無法媲美的。
多值信號量
多值信號量主要用於管理資源和標志事件的發生。管理資源的一個常用仿例就是停車場,
把總停車位看做信號量,每次申請一個停車位信號量就減 1,如果停車位為 0,就申請不到,
但可以等待其它汽車釋放停車位。 標志事件的發生類似於裸機里常用的事件標志變量,就是
標志某事是否發生,然后通知任務。
互斥信號量
互斥信號量的作用是保護共享資源,避免共享資源正在被重寫時被其它任務讀取,這樣
讀取到的數據就有錯誤。 互斥信號量的作用跟多值信號量的作用有些重疊,多值信號量的執
行時間少於互斥信號量,但多個任務訪問共享資源時,容易出現優先級反轉的問題,這會降
低系統的可預知性, 而互斥信號量可以防止優先級反轉,所以建議在互斥信號量可以解決需
要時,就優先使用互斥信號量。
消息隊列
消息隊列是由多個消息串聯而成的一個機制,需要消息的任務就從消息隊列的出口端獲
取,如果消息隊列里沒有消息了,可以選擇等待或者不等待消息的到來。消息可以比信號量
攜帶更豐富的信息, 可以是任意長度的消息內容。
事件標志組
事件標志組用於標志若干個事件否發生的組合。這個功能可以輕易地實現鍵盤的按鍵組合。
任務信號量
任務信號量的作用與多值信號量的一樣,但多值信號量是所有任務都可以申請使用,而
任務信號量卻只能給一個特定任務使用,也就是說任務信號量是一個任務本身的屬性,但其
他任務都可以給這個任務發送任務信號量。
任務消息隊列
任務消息隊列的作用與(普通)消息隊列的一樣,但(普通)消息隊列是所有任務都可
以申請它的消息,而任務任務消息隊列的消息卻只能給一個特定任務使用,也就是說任務消
息隊列是一個任務本身的屬性,但其他任務都可以給這個任務發送任務消息。
內存管理(分區)
內存管理(分區)主要是為了盡量減少內存在不斷分配和釋放過程造成的內存碎片,避
免過多的浪費內存。 內存分區就是一次性開辟一大塊連續內存,然后將內存分區平均分成若
干個內存塊,需要使用內存時就申請一個內存塊,用完了再釋放回內存分區, 這樣就實現內
存塊的循環使用。
uC/OS-III 常用程序段
臨界段
臨界段主要是為了某段代碼在執行時避免被其它任務或中斷打斷。臨界段根據是否是使
能了中斷延遲提交(OS_CFG_ISR_POST_DEFERRED_EN) 大體可以分為兩種。當使能中斷延遲提交時,中斷級任務會轉換成任務級任務,這種情況下進入和退出臨界
段主要分別是鎖調度器和解鎖調度器。當禁用中斷延遲提交時,進入和退出臨界段的方式分
別是關中斷和開中斷。
OS_CRITICAL_ENTER()和 OS_CRITICAL_ENTER_CPU_EXIT() 為進入臨界段,
OS_CRITICAL_EXIT() 和 OS_CRITICAL_EXIT_NO_SCHED() 為 退 出 臨 界 段 ,
CPU_CRITICAL_ENTER()為關中斷, CPU_CRITICAL_EXIT()為開中斷。
為方便 uC/OS對中斷的管理,在進入中斷服務函數時需要調用 OSIntEnter() 函數將中斷嵌套計數
OSIntNestingCtr 加 1,並且在退出中斷服務函數時需要調用 OSIntExit() 函數將中斷嵌套計
數 OSIntNestingCtr 減 1