RT Thread的訊息佇列

2021-09-26 14:19:28 字數 3058 閱讀 2846

1.訊息佇列控制塊的組成(結構體)

通過下圖可以很容易發現訊息佇列有8個元素.msg_pool、.msg_size、max_msgs、.entry、.msg_queue_head、.msg_queue_tail、.msg_queue_free和.parent,其中.msg_pool為訊息佇列的起始位址;.msg_size為每條訊息的大小;.max_msgs為訊息佇列的條目數;.entry佇列內的訊息索引;.msg_queue_head煉表頭; .msg_queue_tail鍊錶尾; .msg_queue_free指向訊息佇列空閒節點;.parent.suspend_thread為獲取訊息而掛起的執行緒鍊錶(執行緒控制塊.tlist元素根據執行緒的狀態被掛接在不同的鍊錶中——比如就緒表、掛起錶等)。

圖1 訊息佇列結構體成員

/**

* 訊息佇列結構體

*/struct rt_messagequeue

;/**

* ipc object物件結構體

*/struct rt_ipc_object

;/**

* object物件結構體

*/struct rt_object

;

2.ipc物件的操作:

這裡ipc物件包括訊號量、互斥量、事件標誌組、訊息郵箱和訊息佇列,將共享以下操作。

2.1初始化ipc物件

ipc物件成員.suspend_thread是乙個雙向鍊錶指標,用於為等待ipc物件的執行緒構建一條掛起執行緒鍊錶。

圖2.1-1 ipc物件初始化

圖2.1-2 等待ipc物件掛起鍊錶

2.2因等待ipc物件而掛起執行緒——rt-thread提供了兩種掛起執行緒機制。

2.2.1按先進先出方式掛起執行緒,這個比較好理解,等待ipc物件的執行緒按照程式執行的先後順序掛在鍊錶當中——當等待的資源(ipc物件)到來時,最先進入等待ipc物件的執行緒優先獲得資源。

2.2.2按等待執行緒的優先順序掛起執行緒,等待ipc物件的執行緒按照優先順序高低掛在鍊錶當中——當等待的資源(ipc物件)到來時,等待ipc物件優先順序最高的執行緒優先獲得資源。

2.3恢復等待ipc物件的執行緒,當等待的ipc物件到來,執行緒便從掛起態進入就緒態,這裡的操作就是把xx.parent.suspend_thread->next指向的執行緒從中刪除,然後再將執行緒控制塊的tlist節點掛接到就緒表當中。

3.訊息佇列

3.1訊息佇列初始化

3.1.1將訊息佇列物件掛接到物件容器中,並設定訊息佇列物件的標誌為rt_ipc_flag_fifo或rt_ipc_flag_prio,用來設定等待訊息佇列物件的執行緒的掛起順序。

圖3.1-1 掛接訊息佇列物件到物件容器中

3.1.2初始化ipc物件;

3.1.3設定儲存訊息緩衝區的起始位址及訊息的大小,並計算出記憶體池能存放多少條訊息;

3.1.4初始化訊息佇列物件元素頭、尾指標及空閒指標;

3.1.5將max_msgs條訊息組成一條空閒鍊錶。

圖3.1-2 訊息佇列的初始狀態

3.2從資源管理器中解依附訊息佇列物件

3.2.1恢復等待訊息佇列的所有執行緒,將所有掛起的執行緒恢復到就緒態;

3.2.2將訊息佇列物件從物件容器的訊息佇列鍊錶中刪除(只刪除此節點)。

3.3向訊息佇列物件傳送普通資訊

3.3.1從空閒鍊錶當中取出首節點;

圖3.3-1 取出空閒鍊錶的首節點

3.3.2將訊息複製到msg指向的位址空間;

3.3.3將msg訊息插入msg_queue_tail鍊錶(如果msg_queue_head指向空位址,msg_queue_head也將指向msg訊息),並增加訊息的條目數;

圖3.3-2 向尾部鍊錶插入一條訊息

3.3.4恢復因等待訊息佇列而掛起的執行緒,然後進行排程。

3.4向訊息佇列物件傳送緊急訊息

3.4.1從空閒鍊錶當中取出首節點;

3.4.2將msg訊息插入msg_queue_head鍊錶(如果msg_queue_tail指向空位址,msg_queue_tail也將指向msg訊息),並增加訊息的條目數;

圖3.4-1 向尾部鍊錶插入一條訊息

3.4.3恢復因等待訊息佇列而掛起的執行緒,然後進行排程。

3.5從訊息佇列物件獲取訊息

3.5.1取出當前執行緒控制代碼;

3.5.2若訊息佇列中沒有訊息,1)若不等待則直接返回;2)否則按照訊息佇列物件定義的方式(按先進先出方式或者按執行緒優先順序方式)掛起當前執行緒;3)復位當前執行緒定時器並重新啟動;4)進行排程;5)恢復到當執行緒,重新計算超時時間是否到達,沒到則重複上述步聚,超時時間到則往下執行;

3.5.3從訊息佇列頭部鍊錶取出一條訊息,並移動訊息佇列頭部指標;

圖3.5-1 從頭部鍊錶取出一條訊息

3.5.4把取出的訊息複製到訊息緩衝區中;

3.5.5把訊息指標掛接到訊息佇列空閒鍊錶當中。

圖3.5-2 把msg訊息指標掛接到空閒鍊錶中

RT Thread應用5 訊息佇列1

一 訊息佇列概念 用於執行緒間通訊的資料結構 當佇列中的訊息是空時,掛起讀取執行緒,使用者還可以指定掛起的執行緒時間 timeout 當佇列中有新訊息時,掛起的讀取執行緒被喚醒並處理新訊息,訊息佇列是一種非同步的通訊方式。二 訊息佇列的運作機制 要點 三 訊息佇列的阻塞機制 阻塞機制 目的 為了保護...

訊息佇列 訊息佇列

輪詢排程 一次性分發所有訊息,保證訊息平均分配,不管消費者是否能正常消費 訊息應答 保證消費端能確實消費,不丟失 公平 乙個乙個分發所有訊息,在保證分發到的執行緒確認回覆後,才分發下個訊息給下個空閒的消費者,訊息持久化 保證佇列中的訊息不丟失,包括3要素 交換器 訊息佇列 訊息都必須宣告持久化 發布...

rtthread之工作佇列

中斷處理分為上半部和下半部 一般來說中斷處理的上半部和下半部都是不允許出現睡眠和阻塞的。但是對於下半部,並不是一刀切,下半部的實現方式有軟中斷和tasklet 不允許睡眠和阻塞 以及工作佇列 允許睡眠和阻塞 上半部 一般中斷的中斷處理函式為上半部,要求做耗時少的動作,盡量迅速,一定不能休眠和阻塞。下...