RTThread學習筆記——線程間通信學習(二)


消息隊列

  在了解消息隊列之前,先復習下數據結構的知識:隊列,插入和刪除受到限制的一種特殊線性表,只允許在后端進行插入操作,在前端進行刪除。

  消息隊列是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;

 

  從上到下依次為:

  對象結構體

  消息池開始地址

  消息大小(字節),最大消息數目

  記錄消息個數的變量

  表頭指針,表尾指針,空閑節點指針

  發送方線程掛起節點

 

  再來看看它的相關函數:

/*創建函數,返回一個消息隊列句柄(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)

 

  


免責聲明!

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



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