消息队列工作机制

消息队列是RT-Thread中另一种常用的进(线)程程间通信方式,消息队列是对邮箱扩展

消息队列能够接收来自线程中断服务例程(ISR)中发出的不固定长度消息,并把消息缓存在自己的内存空间中,而其他线程能够从消息队列消息链表头读取相应的消息并进行对应的处理

消息链表尾指向消息队列最后一条可用消息

线程中断服务例程(ISR)消息队列发送消息的时候,系统会从空闲链表中取出一个空闲消息框,然后将发送过来的消息,放入空闲消息框中,然后把这个消息框链接消息链表尾

消息队列支持紧急消息发送,当线程中断服务例程(ISR)发送的消息是一个紧急消息的时候,系统会直接将这个紧急消息链接消息链表头,这样子等待的线程就可以第一时间获得紧急的消息进行应急处理

消息队列已满的时候,也就是消息队列没有空闲消息框候,线程中断服务例程(ISR)还继续消息队列发送消息的时候,它们发送的这个行为会失败

image.png

消息队列控制块

在 RT-Thread 中,消息队列控制块操作系统 用于 管理消息队列 的一个数据结构

/* **消息队列控制块**结构体定义 */
struct rt_messagequeue
{
    struct rt_ipc_object parent;         /**< **继承自IPC对象基类**,包含:
                                         - 等待队列(挂起的接收线程)
                                         - 名称(调试用)
                                         - 对象类型标志 */
    
    void                *msg_pool;       /**< **消息池起始地址**(动态内存或静态数组),
                                         * 存储实际消息数据的连续内存区域 */
    
    rt_uint16_t          msg_size;       /**< **单个消息的大小**(单位:**字节**),   因为是以4字节进行对齐的,所以这个msg_size**最小的单位就是4**,所以如果把msg_size定义为1的话,系统会自动将msg_size改为4
																				 * 消息队列支持可变长度消息,但需按此大小对齐 */ //																							 如果把msg_size定义为5的话,系统会自动将msg_size改为8
                                         
    rt_uint16_t          max_msgs;       /**< **消息队列最大容量**(单位:**消息数量**),   **max_msgs = sizeof(msg_pool)/{msg_size + 指针的大小(32位系统指针大小是4字节)}**
                                         * 表示可存储的最大消息条数 */
    
    rt_uint16_t          entry;          /**< **当前队列中的有效消息数量**,entry=0 表示空,entry=max_msgs 表示满 */
    
    void                *msg_queue_head; /**< **消息链表头指针**(指向**第一个待读取**的**消息节点**),用于管理消息的先进先出(FIFO)顺序 */
    
    void                *msg_queue_tail; /**< **消息链表尾指针**(指向**最后一个待读取**的**消息节点**),新消息从此处加入链表 */
    
    void                *msg_queue_free; /**< **空闲消息节点链表指针**(指向**消息队列**中**未被使用**的**消息框**),用于快速分配和回收消息内存块 */
};
typedef struct rt_messagequeue *rt_mq_t; // 消息队列对象指针类型

**// 定义静态消息队列**
struct rt_messagequeue static_mq;

**// 定义动态消息队列**
rt_mq_t dynamic_mq;

消息队列的操作

消息队列使用示例