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

消息隊列前端

  在瞭解消息隊列以前,先複習下數據結構的知識:隊列,插入和刪除受到限制的一種特殊線性表,只容許在後端進行插入操做,在前端進行刪除。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)
相關文章
相關標籤/搜索