第5章消息管理_第1頁
第5章消息管理_第2頁
第5章消息管理_第3頁
第5章消息管理_第4頁
第5章消息管理_第5頁
已閱讀5頁,還剩29頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、嵌入式操作系統(tǒng)嵌入式操作系統(tǒng) 與程序設計與程序設計 第5章 消息管理 5.1 消息郵箱 5.1.1 建立消息郵箱 5.1.2等消息 5.1.3 發(fā)消息 5.1.4 刪除消息郵箱 5.1.5放棄郵箱等待 5.1.6 無等待請求消息 5.1.7查詢郵箱狀態(tài) 5.1.8 消息郵箱的例子 5.2 消息隊列 5.2.1 消息隊列數據結構 5.2.2 初始化消息隊列 5.2.3 建立消息隊列 5.2.4發(fā)消息到消息隊列 5.2.5等待消息隊列中的消息 5.2.6刪除消息隊列 5.2.7取得消息隊列的狀態(tài) 5.2.8消息隊列應用舉例 習題 在信號量、互斥信號量和事件標志組的內容 結束后,讀者對事件之間如何同

2、步,如何根 據不同需要設計同步程序,應該有了深入的 理解和提高。本章的消息管理中包括消息郵 箱和消息隊列兩方面的內容,適用于任務之 間的信息交流和同步。從原理上講,消息管 理也應該屬于事件管理的范疇 。 5.1 消息郵箱消息郵箱 消息郵箱是C/OS-II中的另一種通信機制,可以使一個任務或 者中斷服務子程序向另一個任務發(fā)送一個消息。傳遞這個消息 的媒體是一個指針型變量,該指針指向一個包含了“消息”的 某種數據結構。 5.1.1 建立消息郵箱建立消息郵箱 在系統(tǒng)初始化之后,并不存在一個消息郵箱。這時操作系統(tǒng)中的事件管理數 據結構事件控制塊ECB為全空,所有的事件控制塊都在ECB空閑鏈表中 排隊。

3、消息郵箱的建立函數OSMboxCreate將使用一個并配置一個ECB, 使其具備消息郵箱的屬性。 表5.2創(chuàng)建信號量函數OSMboxCreate解析 1.檢查是否這中斷服務程序中創(chuàng)建消息郵箱。 同不允許在中斷服務程序中創(chuàng)建信號量一樣,操作系統(tǒng)C/OS-II同樣不允許 在中斷服務程序中創(chuàng)建消息郵箱。 2.檢查是否有空閑的事件控制塊。 將OSEventFreeList賦值給pevent,如果pevent為空指針,表示沒有空閑的 事件控制塊,函數返回。 3.在事件控制塊空閑鏈表中取下表頭。 因為pevent現在已經是用于郵箱的事件控制塊,讀者可以直接把他理解為一 個郵箱。那么,需要執(zhí)行的操作顯然就是

4、在事件控制塊空閑鏈表中將他 刪除,這時候OSEventFreeList應該指向第二個ECB。 4.對事件控制塊賦值 假設信號量值為5,則賦值后的ECB應該如圖5-1所示 5.返回ECB地址。 5.1.2等消息等消息 等消息也稱為請求消息。含義是當消息存在的時候獲取消息,等消息也稱為請求消息。含義是當消息存在的時候獲取消息, 當消息不存在的時候就放棄對當消息不存在的時候就放棄對CPU的占有,直到有消息的時的占有,直到有消息的時 候才被喚醒。當任務后續(xù)的操作離不開消息,這時任務就不該候才被喚醒。當任務后續(xù)的操作離不開消息,這時任務就不該 死死占著死死占著CPU不讓其他的任務運行,就應該去休息,而當

5、消不讓其他的任務運行,就應該去休息,而當消 息到來的時候系統(tǒng)會將消息喚醒回就緒態(tài),任務獲得消息后繼息到來的時候系統(tǒng)會將消息喚醒回就緒態(tài),任務獲得消息后繼 續(xù)運行。續(xù)運行。 表5.3等待消息郵箱函數OSMboxPend解析 開開始始 返返回回 參參數數檢檢查查是是否否通通 過過 是是 是 否否 p pm ms sg g是是否否 不不為為空空 否 置置位位O OS ST TC CB BS St ta at t中中 等等待待消消息息標標志志 調調用用 O OS S_ _E Ev ve en nt tT Ta as sk kW Wa ai it t終終 止止當當前前任任務務,E EC CB B事事件件

6、 表表中中添添加加當當前前任任務務 執(zhí)執(zhí)行行一一次次任任務務調調度度 存存儲儲超超時時時時間間到到 O OS ST TC CB BD Dl ly y 及及等等待待狀狀 況況OSTCBStatPend 否 這這里里任任務務 又又一一次次被被調調度度 了了!從從阻阻塞塞態(tài)態(tài)回回 到到就就緒緒態(tài)態(tài)又又被被調調 度度 這這里里任任務務被被 剝剝奪奪了了C CP PU U! 進進入入阻阻塞塞態(tài)態(tài)! 等等待待標標志志 是是否否有有效效 是 如如果果是是資資源源滿滿足足而而 結結束束等等待待,只只需需要要 設設置置任任務務塊塊的的E EC CB B 指指針針為為空空 返返回回值值設設置置為為 O OS S_

7、 _T TI IM ME EO OU UT T任任務務仍仍 不不能能使使用用資資源源 是 返返回回值值設設置置為為 O OS S_ _N NO O_ _E ER RR R任任務務可可 使使用用資資源源 p pe er rr r中中填填寫寫對對 應應的的出出錯錯信信息息 是是 將將郵郵箱箱中中的的消消息息 地地址址送送p pm ms sg g 是是否否是是等等待待 超超時時 調調用用O OS S_ _E Ev ve en nt tT Ta as sk kR Re em mo ov ve e 清清除除任任務務塊塊相相關關等等待待標標志志 和和任任務務塊塊O OS ST TC CB BS St ta

8、 at t 清清除除任任務務塊塊相相關關等等待待標標志志 返返回回值值設設置置為為 O OS S_ _E ER RR R_ _P PE EN ND D_ _A AB BO OR RT T任任務務仍仍 不不能能使使用用資資源源 否 5.1.3 發(fā)消息發(fā)消息 當一個任務因為等待消息而被阻塞的時候,只有當其他 任務發(fā)出了消息,被阻塞的任務才能被恢復到就緒態(tài), 從而獲得消息后繼續(xù)運行。阻塞的函數在前一節(jié)分析過 了,發(fā)消息的函數為OSMboxPost,參數是消息類型的 ECB的指針,以及消息的地址。 表5.4發(fā)消息函數OSMboxPost解析 開開始始 返返回回 參參數數檢檢查查 是是否否通通過過 否

9、否否 將將消消息息放放入入郵郵箱箱 是是 是是否否有有任任務務等等待待 該該信信號號量量 是 調調用用 O OS S_ _E Ev ve en nt tT Ta as sk kR Rd dy y 使使等等待待該該消消息息的的 最最高高優(yōu)優(yōu)先先級級任任務務 就就緒緒 執(zhí)執(zhí)行行一一次次任任務務調調度度 返返回回值值進進行行相相 應應設設置置,提提示示 出出錯錯 返返回回值值設設置置為為 O OS S_ _N NO O_ _E ER RR R 郵郵箱箱是是否否是是滿滿的的 否 返返回回值值設設置置為為或或 O OS S_ _N NO O_ _E ER RR R 是 返返回回值值設設置置為為 O OS

10、 S_ _E ER RR R_ _M MB BO OX X _ _F FU UL LL L 5.1.4 刪除消息郵箱刪除消息郵箱 當消息郵箱不再使用了,就應該盡快歸還給系統(tǒng),即將消息占 用的ECB歸還給ECB空閑鏈表以備它用。消息郵箱的刪除函數 是OSMboxDel。刪除一個消息也要涉及方方面面,因為可能 有任務正在等待這個郵箱中的消息。 表5.5刪除消息郵箱的函數OSMboxDel解析 開開始始 返返回回 參參數數檢檢查查 是是否否通通過過 若若有有任任務務等等待待該該郵郵箱箱 T Ta as sk ks s_ _w wa ai it ti in ng g= =T TR RU UE E 否否

11、則則為為F FA AL LS SE E 是是 OS_DEL_NO_PEND 其其他他值值 否否 設設置置該該E EC CB B屬屬性性為為 未未用用 空空閑閑E EC CB B鏈鏈表表表表頭頭 插插入入該該E EC CB B 無無任任務務等等待待 該該郵郵箱箱? ? 根根據據o op pt t值值進進行行 分分支支轉轉移移 是 否否 OS_DEL_ALWAYS 使使所所有有的的等等待待該該 信信號號量量的的任任務務就就 緒緒 設設置置該該E EC CB B屬屬性性為為 未未用用 空空閑閑E EC CB B鏈鏈表表表表頭頭 插插入入該該E EC CB B 若若有有任任務務等等待待該該 信信號號量

12、量執(zhí)執(zhí)行行一一次次 任任務務調調度度 5.1.5放棄郵箱等待放棄郵箱等待 同放棄對信號量的等待類似,放棄等待郵箱也絕對不會是放棄本任務對郵箱 的等待。放棄等待郵箱函數將放棄的是所有等待某郵箱的任務對該郵箱 的等待或等待某郵箱的優(yōu)先級最高的任務對郵箱的等待。 表5.6放棄等待郵箱函數OSMboxPendAbort解析 流程如下: 1.檢查事件控制塊指針是否有效及事件控制塊類型是否有效。 2.如果pevent-OSEventGrp為0說明沒有任務等待消息郵箱,取消等待的任 務數是0,返回0。 3.否則根據參數opt(選項)進行分支轉移,如為 OS_PEND_OPT_BROADCAST,使用whil

13、e語句循環(huán)地將等待該郵箱的 每個任務用OS_EventTaskRdy來取消等待并使其就緒(除非任務還被掛 起);如果為其他值則只將最高優(yōu)先級的任務取消等待并就緒之。 4.返回取消等待信號量的任務數。 5.1.6 無等待請求消息無等待請求消息 在中斷服務程序和有些用戶任務中,需要無等待的請求消息 郵箱。也就是說,到郵箱中取郵件,如果有郵件就獲得郵件, 如果沒有并不阻塞自己,而是繼續(xù)執(zhí)行其他代碼。 OSMboxAccept就是無等待的請求消息郵箱函數,參數是請求 的消息郵箱的ECB指針。該函數的返回值是指向郵箱的指針, 如果沒有取得消息,那么就返回空指針。 表5.7無等待地請求消息郵箱函數OSMb

14、oxAccept解析 首先參數檢查ECB是否有效,如果有效,將消息郵箱中郵件 的地址OSEventPtr賦值給pmsg,然后清郵箱內容,返回獲得的 郵件的地址pmsg。這樣,如果郵箱中有郵件,那么返回郵件的 地址,如果沒有,返回值就是空地址。 5.1.7查詢郵箱狀態(tài)查詢郵箱狀態(tài) 消息郵箱狀態(tài)查詢函數OSMboxQuery的參數是ECB地址和 一個指向OS_MBOX_DATA類型的地址。ECB地址指向郵箱, OS_MBOX_DATA類型的地址指向返回結果的一個 S_MBOX_DATA類型的對象。 表5.9查詢消息郵箱狀態(tài)函數OSMboxQuery解析 Example5_1: task1任務每任務

15、每1秒記錄運行次數,發(fā)送到消息郵箱;秒記錄運行次數,發(fā)送到消息郵箱; task2任務每任務每1秒從消息郵箱接收消息并打印。秒從消息郵箱接收消息并打印。 消息郵箱例程消息郵箱例程 5.1.8 消息郵箱的例子消息郵箱的例子 假設有任務TaskMessageSen和TaskMessageRec, TaskMessageSen在事件片1創(chuàng) 建一個郵箱,如果郵箱中已沒有郵件,每秒向郵箱發(fā)送一個消息,消息內容為從0 開始的計數值,該計數值每秒加1。任務TaskMessageRec從時間1開始,做的事情 就是查看郵箱,然后把郵件打印出來。 現在我們采用郵件管理完成這兩個任務的設計。 5.2 消息隊列消息隊列

16、 消息郵箱中只能存放一則消息,太少了,能不能像電子郵件一樣,管理多 條消息呢? C/OS為實現這一目的,設計了消息隊列管理。使用消息隊列管理,就允 許使用可以容納多條信息的大郵箱,按照先進先出(FIFO)的原則,發(fā)送和 接收郵件。需要注意的是,這樣的郵箱不是操作系統(tǒng)提供的,而是要由用戶 任務來提供。操作系統(tǒng)提供的是對其進行管理的程序。另外,郵箱中的內容 仍然是郵件的地址。 消息隊列的代碼單獨存放在os_q.c中 5.2.1 消息隊列數據結構消息隊列數據結構 1消息隊列及其控制塊消息隊列及其控制塊 typedef struct os_q /* 隊列控制塊隊列控制塊QCB*/ struct os_

17、q *OSQPtr; /*在空閑在空閑QCB鏈表中,指示下一個鏈表中,指示下一個QCB*/ void *OSQStart; /*隊列數據的首地址隊列數據的首地址*/ void *OSQEnd; /*隊列數據的末地址隊列數據的末地址*/ void *OSQIn; /*指示下次插入消息的位置指示下次插入消息的位置 */ void *OSQOut; /* 指示下次提取消息的位置指示下次提取消息的位置*/ INT16U OSQSize; /*隊列的最大容量隊列的最大容量*/ INT16U OSQEntries; /*隊列中當前的消息量隊列中當前的消息量*/ OS_Q; 2消息控制塊實體消息控制塊實體

18、OS_Q OSQTblOS_MAX_QS; 3空閑消息隊列鏈表 消息控制塊QCB中OSQWaitList用來指示空閑消息控制塊QCB鏈表中的下一個消息 控制塊QCB。 5.2.2 初始化消息隊列初始化消息隊列 消息隊列初始化函數在操作系統(tǒng)初始化時被調用,主要用于 初始化消息隊列使用的數據結構。消息隊列初始化函數的名稱 為OS_QInit 表5.13消息隊列初始化函數OS_QInit解析 1. 將所有QCB全部清為全0。 2. 使用for循環(huán)將除最后一個消息控制塊 OSQTblOS_MAX_QS - 1之外的所有消息控制塊初始化,構 建了單向的消息隊列空閑鏈表。 3.初始化最后一個QCB,將消息

19、隊列空閑鏈表完善。 5.2.3 建立消息隊列建立消息隊列 創(chuàng)建消息隊列就是將從ECB空閑鏈表中取下一個事件控制塊ECB來,將其用于 消息隊列管理。并從QCB空閑鏈表的表頭取下一個消息控制塊QCB,將其各種屬 性進行設置,用于指示消息的位置以及提取和插入消息的位置。 創(chuàng)建消息隊列的函數名稱為OSQCreate。 表5.14消息隊列創(chuàng)建函數OSQCreate分析 1. 判斷是否在中斷服務程序中調用本函數,如果是就返回。 2. 取得消息隊列的鏈表首地址送pevent。 3. 判斷pevent是否為空指針,如果是則說明是系統(tǒng)已經沒有空閑的ECB可供使用, 填寫錯誤信息,返回空指針。 4. 從空閑ECB

20、鏈表取下表頭。 5. 空閑QCB鏈表首地址送pq。 6. 如果沒有有效的空閑QCB鏈表,恢復空閑ECB鏈表,返回空ECB指針。 7. 在空閑QCB鏈表中取一個pq指向的QCB,對其進行初始化。設置OSQStart為消息 指針數組的首地址start。OSQEnd值為&startsize即消息指針數組(消息隊列)中 最后一個指針后面的一個地址。OSQIn和OSQOut也設置為start。OSQSize的值為 size。OSQEntries為0表示該隊列中還沒有消息。 8. 接下來對pevent指向的ECB進行初始化。OSEventType為OS_EVENT_TYPE_Q 表示用于消息隊列管理。OS

21、EventCnt在這里沒有用,設置為0。OSEventPtr指向 QCB,即設置為pq。調用OS_EventWaitListInit初始化ECB中的事件等待表和事件等 待組。 9.返回ECB指針。 5.2.4發(fā)消息到消息隊列發(fā)消息到消息隊列 發(fā)消息到消息隊列的函數名稱為OSQPost。參數是事件控制塊ECB的地 址pevent和消息的地址pmsg。 表5.15發(fā)消息到消息對列函數OSQPost分析 1.首先進行參數檢查,如果參數檢查失敗則返回。 2. 如果有任務等待消息隊列中的消息,那么消息隊列現在必然是空的。不 需要將消息存入隊列,而直接將消息給在等待的優(yōu)先級最高的消息,并將 其就緒。執(zhí)行一

22、次任務調度然后返回。 3. 如果沒有任務等待消息隊列中的消息,那么就需要將該消息加入消息隊 列。如果消息隊列是滿的,不能容納更多的消息,返回出錯信息。否則, 在消息控制塊QCB的OSQIn所指示的消息指針數組位置存入該消息,然后 將OSQIn 指向下一個單元以便下次使用。判斷OSQIn是否到超過了表尾, 如果超過了,將其指向隊首。然后返回。 5.2.5等待消息隊列中的消息等待消息隊列中的消息 等待消息隊列的消息是消息隊列管理中的又一核心函數。如果消息隊列中有消息, 那么就取出消息,然后返回;如果沒有消息,只有在ECB中標記自己的等待,然后 阻塞。 等待消息隊列的函數的名稱為OSQPend,參數

23、是ECB的指針、等待超時時間和返 回函數執(zhí)行信息的指針的perr。函數的返回值是指向消息的指針。 表5.16消息隊列等待函數OSQPend分析 1.首先進行參數、ECB類型、中斷、調度鎖檢查,失敗則返回。 2. 取得ECB中的QCB指針,查詢消息隊列中是否有消息。如果有消息,那么請求 直接成功,取得消息隊列中OSQOut所指的消息,將OSQOut指向消息隊列中的下 一個元素以備下一次的消息提取。如果OSQOut指向了消息隊列之外,就指向消息 隊列的首地址。將OSQEntries減1表示消息數量減少了一個。然后返回消息的指針。 3. 如果沒有消息,那么任務就只有被阻塞。首先在TCB中的STCBS

24、tat中添加消息 隊列等待標志,任務延時時間,初始化等待狀態(tài),然后調用OS_EventTaskWait 添 加等待標志和取消就緒標志,接著調用OS_Sched執(zhí)行一次任務調度。 4. 任務恢復運行后,根據TCB中的等待狀態(tài)OSTCBStatPend決定程序走向。如果 獲得了消息,進行一些處理后返回該消息。如果是退出等待,或是等待超時,分別 填寫沒有取得消息的原因,然后返回空指針。 5.2.6刪除消息隊列刪除消息隊列 當消息隊列不再使用了,就應該盡快歸還給系統(tǒng),即將消息占用的 ECB歸還給ECB空閑鏈表以備它用,將QCB也歸還給空閑QCB鏈表。 刪除消息隊列的函數的名稱為OSQDel,參數是EC

25、B的指針、刪除操作的 選項opt和返回函數執(zhí)行信息的指針的perr。 其中opt的值為 OS_DEL_NO_PEND 表示只有當沒有任務等待該消息隊列的時候才允 許刪除,opt的值為OS_DEL_ALWAYS 表示無論如何都刪除。 如果成功刪除,返回空指針;否則返回ECB的指針。 表5.17消息隊列刪除函數OSQDel解析 1.首先進行參數的檢查。 2. 根據選項opt決定程序的分支 3. 如果opt不是這兩個值當中的一個,那就是說明是錯誤的選項,也屬于參 數檢查失敗。因此,標記錯誤信息perr為OS_ERR_INVALID_OPT后, 直接返回原來ECB指針pevent。 5.2.7取得消息隊列的狀態(tài)取得消息隊列的狀態(tài) 消息隊列數據OS_Q_DATA是為返回消息隊列信息而提供的,因此用戶 程序如果想了解消息隊列的信息,要先創(chuàng)建OS_Q_DATA的實例。然后以 消息隊列所在ECB地址及該實例的地址為指針為參數調用獲取消息隊列的 狀態(tài)函數OSQQuery 表5.19獲取消息隊列的狀態(tài)函數OSQQuery解析 5.2.8消息隊列應用舉例消息隊列應用舉例 假設有任務假設有任務TaskQSen和和

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論