核心結構
多任務系統中,核心負責管理各個任務,或者說為每個任務分配CPU 時間,並且負責任務之間的通訊。
核心提供的基本服務是任務切換。μC/OS-II可以管理多達64個任務。由於它的作者占用和保留了8個任務,所以留給用戶應用程式最多可有56個任務。賦予各個任務的
優先權必須是不相同的。這意味著μC/OS-II不支持
時間片輪轉調度法(round-robin scheduli ng)。μC/OS-II為每個任務設定獨立的
堆疊空間,可以快速實現任務切換 。μC/OS-II近似地每時每刻總是讓優先權最高的就緒任務處於運行狀態,為了保證這一點,它在調用系統API 函式、中斷結束、定時中斷結束時總是執行
調度算法,μC/OS-II通過事先計算好數據簡化了運算量,通過精心設計就緒表結構使得延時可預知。
特點
1、原始碼:µC/OS-II全部以原始碼的方式提供給使用者(約5500行)。該源碼清晰易讀,結構協調,且註解詳盡,組織有序;
2、可移植(portable): µC/OS-II的原始碼絕大部分是用移植性很強的ANSI C寫的,與微處理器硬體相關的部分是用
彙編語言寫的。µC/OS-II可以移植到許許多多不同的微處理器上,條件是:該微處理器具有堆疊指針,具有CPU內部暫存器入棧、出棧指令,使用的C編譯器必須支持內嵌彙編,或者該C語言可擴展和可連結彙編模組,使得關中斷和開中斷能在C語言程式中實現;
3、可固化(ROMable): µC/OS-II是為嵌入式套用而設計的,意味著只要具備合適的系列軟體工具(C編譯、彙編、連結以及下載/固化)就可以將µC/OS-II嵌入到產品中作為產品的一部分;
4、可裁減(scalable): 可以只使用µC/OS-II中應用程式需要的系統服務。可裁減性是靠
條件編譯實現的,只需要在用戶的應用程式中定義那些µC/OS-II中的功能應用程式需要的部分就可以了;
5、可搶占性(preemptive): µC/OS-II是完全可搶占型的實時核心,即µC/OS-II總是運行就緒條件下
優先權最高的任務;
6、多任務: µC/OS-II可以管理64個任務。賦予每個任務的優先權必須是不相同的,這就是說µC/OS-II不支持
時間片輪轉調度法(該調度法適用於調度優先權平等的任務);
7、可確定性: 絕大多數µC/OS-II的
函式調用和服務的執行時間具有可確定性。也就是說用戶能知道µC/OS-II的函式調用與服務執行了多長時間。進而可以說,除了函式OSTimeTick()和某些事件標誌服務,µC/OS-II系統服務的執行時間不依賴於用戶應用程式任務數目的多少;
8、任務棧: 每個任務都有自己單獨的棧。µC/OS-II允許每個任務有不同的棧空間,以便降低應用程式對RAM的需求;
9、系統服務: µC/OS-II提供許多系統服務,比如
信號量、互斥信號量、事件標誌、
訊息信箱、
訊息佇列、時間管理等等;
10、中斷管理: 中斷可以使正在執行的任務暫時掛起。如果
優先權更高的任務被該中斷喚醒,則高優先權的任務在
中斷嵌套全部退出後立即執行,中斷嵌套層數可以達255層;
11、穩定性和可靠性: µC/OS-II的每一種功能、每一個函式以及每一行代碼都經過了考驗和測試,具有足夠的安全性與穩定性,能用於與人性命攸關、安全性條件極為苛刻的系統中。
μC/OS-II API 介紹
任何一個作業系統都會提供大量的API供程式設計師使用,μC/OS-II 也不例外。由於μC/OS-II 面向的是
嵌入式開發,並不要求大而全,所以核心提供的API也就大多和多任務息息相關。主要有以下幾類:
1)任務類
2)訊息類
3)同步類
4)時間類
實驗內容簡介
任務管理實驗
此實驗的目的是讓讀者理解嵌入式作業系統中任務管理的基本原理,了解任務的各個基本狀態及其變遷過程;掌握µC/OS-II中任務管理的基本方法(創建、啟動、掛起和解掛任務);熟練使用µC/OS-II任務管理的基本
系統調用。
優先權反轉實驗
通過此實驗讀者可以了解在基於
搶占式嵌入式實時作業系統並有共享資源的套用中,出現
優先權反轉現象的原理。優先權反轉發生在有多個任務共享資源的情況下,高優先權任務被低優先權任務阻塞,並等待低優先權任務執行的現象。
優先權繼承實驗
通過此實驗讀者可以了解嵌入式實時作業系統µC/OS-II解決
優先權反轉的策略——優先權繼承的原理,以此解決低優先權任務在占用了共享資源的情況下,被高優先權任務搶占了CPU使用權而導致的優先權反轉的問題。
哲學家就餐實驗
通過經典的哲學家就餐套用,讀者可以了解如何利用嵌入式實時作業系統µC/OS-II的
信號量機制來對共享資源進行互斥訪問。
記憶體管理實驗
通過此實驗讀者可以了解嵌入式實時作業系統µC/OS-II中的
記憶體管理的原理,包括對記憶體的分配和回收。
時鐘中斷實驗
通過此實驗讀者可以了解嵌入式實時作業系統µC/OS-II中,
時鐘中斷的使用情況。
訊息佇列實驗
通過此實驗讀者可以了解嵌入式實時作業系統µC/OS-II中的
訊息佇列機制。讀者可以了解一個套用中的任務是如何進行通信的,如何能使它們相互協調工作。
μC/OS-Ⅱ中的任務描述
一個任務通常是一個無限的循環,由於任務的執行是作業系統核心調度的,因此務是絕不會返回的,其返回參數必須定義成
void。在
μC/OS-Ⅱ中,當一個運行著的任務使一個比它優先權高的任務進入了就緒態,當前任務的CPU使用權就會被搶占,高優先權任務會立刻得到CPU的控制權(在系統允許調度和任務切換的前提下)。μC/OS-Ⅱ可以管理多達64個任務,但目前版本的μC/OS-Ⅱ有兩個任務已經被系統占用了(即空閒任務和統計任務)。必須給每個任務賦以不同的優先權,任務的優先權號就是任務編號(ID),優先權可以從0到OS_LOWEST_PR10-2。
優先權號越低,任務的優先權越高。
μC/OS-Ⅱ總是運行進入就緒態的優先權最高的任務。
配置手冊
本章將介紹μC/OS-II中的初始化配置項。由於μC/OS-II向用戶提供
原始碼,初始化配置項由一系列#define constant語句構成,都在檔案OS_CFG.H中。用戶的工程
檔案組中都應該包含這個檔案。
本節介紹每個用#define constant定義的常量,介紹的順序和它們在OS_CFG.H中出現的順序是相同的。表12.1列出了常量控制的μC/OS-II函式。“類型”為函式所屬的類型,“置1”表示當定義常量為1時可以打開相應的函式,“其他常量”為與這個函式有關的其他控制常量。
注意編譯工程檔案時要包含OS_CFG.H,使定義的常量生效。
雜相
OSInit()無OS_MAX_EVENTS
OS_Q_EN and OS_MAX_QS
OS_MEM_EN
OS_TASK_IDLE_STK_SIZE
OS_TASK_STAT_EN
OS_TASK_STAT_STK_SIZE
OSSchedLock()無無
OSSchedUnlock()無無
OSStart()無無
OSStatInit()OS_TASK_STAT_EN &&
OS_TASK_CREATE_EXT_ENOS_TICKS_PER_SEC
OSVersion()無無
中斷處理
OSIntEnter()無無
OSIntExit()無無
訊息信箱
OSMboxAccept()OS_MBOX_EN無
OSMboxCreate()OS_MBOX_ENOS_MAX_EVENTS
OSMboxPend()OS_MBOX_EN無
OSMboxPost()OS_MBOX_EN無
OSMboxQuery()OS_MBOX_EN無
記憶體塊管理
OSMemCreate()OS_MEM_ENOS_MAX_MEM_PART
OSMemGet()OS_MEM_EN無
OSMemPut()OS_MEM_EN無
OSMemQuery()OS_MEM_EN無
訊息佇列
OSQAccept()OS_Q_EN無
OSQCreate()OS_Q_ENOS_MAX_EVENTS
OS_MAX_QS
OSQFlush()OS_Q_EN無
OSQPend()OS_Q_EN無
OSQPost()OS_Q_EN無
OSQPostFront()OS_Q_EN無
OSQQuery()OS_Q_EN無
信號量管理
OSSemAccept()OS_SEM_EN無
OSSemCreate()OS_SEM_ENOS_MAX_EVENTS
OSSemPend()OS_SEM_EN無
OSSemPost()OS_SEM_EN無
OSSemQuery()OS_SEM_EN無
任務管理
OSTaskChangePrio()OS_TASK_CHANGE_PRIO_ENOS_LOWEST_PRIO
OSTaskCreate()OS_TASK_CREATE_ENOS_MAX_TASKS
OS_LOWEST_PRIO
OSTaskCreateExt()OS_TASK_CREATE_EXT_ENOS_MAX_TASKS
OS_STK_GROWTH
OS_LOWEST_PRIO
OSTaskDel()OS_TASK_DEL_ENOS_LOWEST_PRIO
OSTaskDelReq()OS_TASK_DEL_ENOS_LOWEST_PRIO
OSTaskResume()OS_TASK_SUSPEND_ENOS_LOWEST_PRIO
OSTaskStkChk()OS_TASK_CREATE_EXT_ENOS_LOWEST_PRIO
OSTaskSuspend()OS_TASK_SUSPEND_ENOS_LOWEST_PRIO
OSTaskQuery()OS_LOWEST_PRIO
時鐘管理
OSTimeDly()無無
OSTimeDlyHMSM()無OS_TICKS_PER_SEC
OSTimeDlyResume()無OS_LOWEST_PRIO
OSTimeGet()無無
OSTimeSet()無無
OSTimeTick()無無
用戶定義函式
OSTaskCreateHook()OS_CPU_HOOKS_EN無
OSTaskDelHook()OS_CPU_HOOKS_EN無
OSTaskStatHook()OS_CPU_HOOKS_EN無
OSTaskSwHook()OS_CPU_HOOKS_EN無
OSTimeTickHook()OS_CPU_HOOKS_EN無
OS_MAX_EVENTS
OS_MAX_EVENTS定義系統中最大的事件控制塊的數量。系統中的每一個
訊息信箱,
訊息佇列,
信號量都需要一個事件控制塊。例如,系統中有10個訊息信箱,5個訊息佇列,3個信號量,則OS_MAX_EVENTS最小應該為18。只要程式中用到了訊息信箱,訊息佇列或是信號量,則OS_MAX_EVENTS最小應該設定為2。
OS_MAX_MEM_PARTS
OS_MAX_MEM_PARTS定義系統中最大的記憶體塊數,記憶體塊將由
記憶體管理函式操作(定義在檔案OS_MEM.C中)。如果要使用記憶體塊,OS_MAX_MEM_PARTS最小應該設定為2,常量OS_MEM_EN也要同時置1。
OS_MAX_QS
OS_MAX_QS定義系統中最大的訊息佇列數。要使用
訊息佇列,常量OS_Q_EN也要同時置1。如果要使用訊息佇列,OS_MAX_ QS最小應該設定為2。
OS_MAX_TASKS
OS_MAX_MEM_TASKS定義
用戶程式中最大的任務數。OS_MAX_MEM_TASKS不能大於62,這是由於μC/OS-II保留了兩個系統使用的任務。如果設定OS_MAX_MEM_TASKS剛好等於所需任務數,則建立新任務時要注意檢查是否超過限定。而OS_MAX_MEM_TASKS設定的太大則會浪費記憶體。
OS_LOWEST_PRIO
OS_LOWEST_PRIO設定系統中的任務最低
優先權(最大優先權數)。設定OS_LOWEST_PRIO可以節省用於任務控制塊的記憶體。μC/OS-II中優先權數從0(最高優先權)到63(最低優先權)。設定OS_LOWEST_PRIO小於63意味著不會建立優先權數大於OS_LOWEST_PRIO的任務。μC/OS-II中保留兩個優先權系統自用:OS_LOWEST_PRIO和OS_LOWEST_PRIO-1。其中OS_LOWEST_PRIO留給系統的空閒任務(Idle task)(OSTaskIdle())。OS_LOWEST_PRIO-1留給統計任務(OSTaskStat())。用戶任務的
優先權可以從0到OS_LOWEST_PRIO-2。OS_LOWEST_PRIO和OS_MAX_TASKS之間沒有什麼關係。例如,可以設OS_MAX_TASKS為10而OS_LOWEST_PRIO為32。此時系統最多可有10個任務,用戶任務的優先權可以是0到30。當然,OS_LOWEST_PRIO設定的優先權也要夠用,例如設OS_MAX_TASKS為20,而OS_LOWEST_PRIO為10,優先權就不夠用了。
OS_TASK_IDLE_STK_SIZE
OS_TASK_IDLE_STK_SIZE設定μC/OS-II中空閒任務(Idle task)
堆疊的容量。注意堆疊容量的單位不是位元組,而是OS_STK(μC/OS-II中堆疊統一用OS_STK聲明,會根據不同的硬體環境,OS_STK可為不同的長度----譯者注)。空閒任務堆疊的容量取決於所使用的處理器,以及預期的最大中斷嵌套數。雖然空閒任務幾乎不做什麼工作,但還是要預留足夠的堆疊空間保存CPU暫存器的內容,以及可能出現的
中斷嵌套情況。
OS_TASK_STAT_EN
OS_TASK_STAT_EN設定系統是否使用μC/OS-II中的統計任務(statistic task)及其初始化函式。如果設為1,則使用統計任務OSTaskStat()。統計任務每秒運行一次,計算當前系統CPU使用率,結果保存在8位變數OSCPUUsage中。每次運行,OSTaskStat()都將調用OSTaskStatHook()函式,用戶自定義的統計功能可以放在這個函式中。詳細情況請參考OS_CORE.C檔案。統計任務OSTaskStat()的優先權總是設為OS_LOWEST_PRIO-1。
當OS_TASK_STAT_EN設為0的時候,全局變數OSCPUUsage,OSIdleCtrMax,OSIdleCtrRun和OSStatRdy都不聲明,以節省記憶體空間。
OS_TASK_STAT_STK_SIZE
OS_TASK_STAT_STK_SIZE設定μC/OS-II中統計任務(statistic task)
堆疊的容量。統計任務堆疊的容量取決於所使用的處理器類型,以及如下的操作:
進行32位算術運算所需的堆疊空間。
調用
OSTimeDly()所需的堆疊空間。
調用OSTaskStatHook()所需的堆疊空間。
預計最大的中斷嵌套數。
如果想在統計任務中進行堆疊檢查,判斷實際的堆疊使用,用戶需要設OS_TASK_CREATE_EXT_EN為1,並使用OSTaskCreateExt()函式建立任務。
OS_CPU_HOOKS_EN
此常量設定是否在檔案OS_CPU_C.C中聲明對外
接口函式(hook function),設為1為聲明。μC/OS-II中提供了5個對外接口函式,可以在檔案OS_CPU_C.C中聲明,也可以在用戶自己的代碼中聲明:
OSTaskCreateHook()
OSTaskDelHook()
OSTaskStatHook()
OSTaskSwHook()
OSTimeTickHook()
OS_MBOX_EN
OS_MBOX_EN控制是否使用μC/OS-II中的
訊息信箱函式及其相關數據結構,設為1為使用。如果不使用,則關閉此常量節省記憶體。
OS_MEM_EN
OS_MEM_EN控制是否使用μC/OS-II中的記憶體塊管理函式及其相關數據結構,設為1為使用。如果不使用,則關閉此常量節省記憶體。
OS_Q_EN
OS_Q_EN控制是否使用μC/OS-II中的
訊息佇列函式及其相關數據結構,設為1為使用。如果不使用,則關閉此常量節省記憶體。如果OS_Q_EN設為0,則語句#define constant OS_MAX_QS無效。
OS_SEM_EN
OS_SEM_EN控制是否使用μC/OS-II中的
信號量管理函式及其相關數據結構,設為1為使用。如果不使用,則關閉此常量節省記憶體。
OS_TASK_CHANGE_PRIO_EN
此常量控制是否使用μC/OS-II中的OSTaskChangePrio()函式,設為1為使用。如果在應用程式中不需要改變運行任務的優先權,則將此常量設為0節省記憶體。
OS_TASK_CREATE_EN
此常量控制是否使用μC/OS-II中的OSTaskCreate()函式,設為1為使用。在μC/OS-II中推薦用戶使用OSTaskCreateExt()函式建立任務。如果不使用OSTaskCreate()函式,將OS_TASK_CREATE_EN設為0可以節省記憶體。注意OS_TASK_CREATE_EN和OS_TASK_CREATE_EXT_EN至少有一個要為1,當然如果都使用也可以。
OS_TASK_CREATE_EXT_EN
此常量控制是否使用μC/OS-II中的OSTaskCreateExt()函式,設為1為使用。該函式為擴展的,功能更全的任務建立函式。如果不使用該函式,將OS_TASK_CREATE_EXT_EN設為0可以節省記憶體。注意,如果要使用
堆疊檢查函式OSTaskStkChk(),則必須用OSTaskCreateExt()建立任務。
OS_TASK_DEL_EN
此常量控制是否使用μC/OS-II中的OSTaskDel()函式,設為1為使用。如果在應用程式中不使用刪除任務函式,將OS_TASK_DEL_EN設為0可以節省記憶體。
OS_TASK_SUSPEND_EN
此常量控制是否使用μC/OS-II中的
OSTaskSuspend()和OSTaskResume()函式,設為1為使用。如果在應用程式中不使用任務掛起-喚醒函式,將OS_TASK_SUSPEND_EN設為0可以節省記憶體。
OS_TICKS_PER_SEC
此常量標識調用OSTimeTick()函式的頻率。用戶需要在自己的初始化程式中保證OSTimeTick()按所設定的頻率調用(即系統硬體
定時器中斷髮生的頻率----譯者注)。在函式OSStatInit(),OSTaskStat()和
OSTimeDlyHMSM()中都會用到OS_TICKS_PER_SEC。