消息队列前端
在了解消息队列以前,先复习下数据结构的知识:队列,插入和删除受到限制的一种特殊线性表,只容许在后端进行插入操做,在前端进行删除。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)