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)
相关文章
相关标签/搜索