Rt-thread: 消息隊列


Message queue的結構如下:

 

 1 Parent屬於內核對象,通過這個成員可以將消息隊列掛到系統對象容器里面. Parent其實是一個ipc結構體,里面包含了掛起的線程

 

 

初始化狀態如下:

 

2 msg_pool 是存放消息池的開始地址

3 msg_size 是每條消息的大小

4 max_msg 是最多的消息個數

5 entry:隊列中的消息索引,記錄消息隊列的消息個數

6 msg_queue_head/msg_queue_tail/msg_queue_free 鏈表頭,尾指針,以及指向空閑節點的指針

消息隊列初始化后狀態參考下圖。

 

 

消息發送

線程或者中斷服務程序都可以給消息隊列發送消息。當發送消息時,消息隊列對象先從空閑消息鏈表上取下一個空閑消息塊,把線程或者中斷服務程序發送的消息內容復制到消息塊上,然后把該消息塊掛到消息隊列的尾部。當且僅當空閑消息鏈表上有可用的空閑消息塊時,發送者才能成功發送消息;當空閑消息鏈表上無可用消息塊,說明消息隊列已滿,此時,發送消息的的線程或者中斷程序會收到一個錯誤碼(-RT_EFULL)

 

(a)      首先從空閑隊列中取出一個消息,如果空閑隊列中沒有可用信息塊了,消息隊列已滿,則返回-RT_EFULL。每次申請后msg_queue_free指針則后移

 

 

示意圖如下

 

 

(b)      取出消息后,將消息放到msg_queue_tail中去。並同時更新msg_queue_head的值

 

 

示意圖如下

 

 

(c)     此時在消息隊列中已經發送了消息。則看等待隊列是否有任務在等待消息。如果有的話則將任務從掛起列表中恢復,並開啟一次調度

 

 

消息接受

(a)     檢查隊列的消息是否為0,如果沒有消息且timeout ==0 則立即返回

 

 (b)  如果消息隊列為空,但是等待時間大於0,則將當前任務掛起,並啟動一個定時器並發起一個線程調度

 

 

(c)     如果隊列中有消息。則從消息隊列頭部msg_queue_head中取出消息。並拷貝到指定的存儲地址buffer。拷貝消息的大小為size,大小不能超過創建消息隊列時候已經定義的消息大小msg_size.

 

 

示意圖如下:

 

 

獲取一個消息后,消息隊列上的頭鏈表消息被轉移到空閑消息鏈表中,這樣就可以保證消息隊列的循環利用。而不會導致頭鏈表指針移動到隊列尾部時沒有可用的消息節點。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM