消息隊列前端
在瞭解消息隊列以前,先複習下數據結構的知識:隊列,插入和刪除受到限制的一種特殊線性表,只容許在後端進行插入操做,在前端進行刪除。node
消息隊列是RTT系統中經常使用的一種通訊結構,線程能夠從隊列中讀取消息,若是隊列中沒有消息,則掛起線程。它是一種異步通訊的方式。後端
因爲隊列結構的特殊性,線程最早獲得的消息是最早進入消息隊列的消息,遵循先進先出的原則(FIFO)。在RTT系統中,隊列能夠傳遞不一樣長度的任意類型的消息,而且擁有直接向隊列頭髮送消息的緊急處理機制。消息隊列最多見的用途就是進行線程間的信息交換。數據結構
來看看它的實現,首先是RTT中的控制塊定義:異步
/*消息隊列控制塊,在rtdef.h中定義*/ struct rt_messagequeue { struct rt_ipc_object parent; /**< inherit from ipc_object */ void *msg_pool; /**< start address of message queue */ rt_uint16_t msg_size; /**< message size of each message */ rt_uint16_t max_msgs; /**< max number of messages */ rt_uint16_t entry; /**< index of messages in the queue */ void *msg_queue_head; /**< list head */ void *msg_queue_tail; /**< list tail */ void *msg_queue_free; /**< pointer indicated the free node of queue */ rt_list_t suspend_sender_thread; /**< sender thread suspended on this message queue */ }; typedef struct rt_messagequeue *rt_mq_t;
從上到下依次爲:函數
對象結構體ui
消息池開始地址this
消息大小(字節),最大消息數目spa
記錄消息個數的變量線程
表頭指針,表尾指針,空閒節點指針
發送方線程掛起節點
再來看看它的相關函數:
/*建立函數,返回一個消息隊列句柄(rt_mq_t)*/ rt_mq_t rt_mq_create(const char *name, //名字 rt_size_t msg_size, //最大長度 rt_size_t max_msgs, //最大容量 rt_uint8_t flag) //模式,RTT中宏定義了一些模式 /*刪除函數*/ rt_err_t rt_mq_delete(rt_mq_t mq) //傳入句柄 /*發送消息函數*/ rt_err_t rt_mq_send(rt_mq_t mq, const void *buffer, rt_size_t size) //傳入分別爲句柄,數據地址,數據大小(字節) /*接收消息函數*/ rt_err_t rt_mq_recv(rt_mq_t mq, //句柄 void *buffer, //讀取的位置 rt_size_t size, //接收的長度 rt_int32_t timeout) //等待時間
郵箱
郵箱是另外一種常見的IPC通訊(進程間通訊)方式,相比於其餘方式,其通訊內容被限制在每一封郵件只能容納4字節的大小,換來的是其更低的開銷,更高的效率。
一封郵件剛好能容納STM32的一個指針,這樣,能夠把指向緩衝區的指針做爲郵件發送。(緩衝區:內存中預留的指定大小的空間,用來暫存輸入/輸出的數據)。也能夠發送結構體指針。
郵箱亦遵循先進先出原則(FIFO)。
郵箱控制塊:
struct rt_mailbox { struct rt_ipc_object parent; /**< inherit from ipc_object */ rt_ubase_t *msg_pool; /**< start address of message buffer */ rt_uint16_t size; /**< size of message pool */ rt_uint16_t entry; /**< index of messages in msg_pool */ rt_uint16_t in_offset; /**< input offset of the message buffer */ rt_uint16_t out_offset; /**< output offset of the message buffer */ rt_list_t suspend_sender_thread; /**< sender thread suspended on this mailbox */ };
相關函數:
/*建立函數*/ rt_mailbox_t rt_mb_create(const char *name, rt_size_t size, rt_uint8_t flag) /*刪除函數*/ rt_err_t rt_mb_delete(rt_mailbox_t mb) /*阻塞發送,當郵箱滿時,能夠進行等待*/ rt_err_t rt_mb_send_wait(rt_mailbox_t mb, rt_ubase_t value, rt_int32_t timeout) /*非阻塞發送,不會等待,若是滿會返回錯誤值*/ rt_err_t rt_mb_send(rt_mailbox_t mb, rt_ubase_t value) /*接收*/ rt_err_t rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeout)