学习笔记(3)RT-Thread使用消息队列

本文介绍了如何在RT-Thread操作系统中创建、发送和接收消息队列。通过rt_mq_create函数创建消息队列,rt_mq_send用于发送消息,rt_mq_recv用于接收消息。示例代码展示了消息队列的基本使用流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文参考了RT-Thread的官方文档:​​​​​​线程间通信 (rt-thread.org)

话不多说直接上代码,这里实现了一个较为简单的消息队列。

#include <rtthread.h>
#include <string.h>

static rt_mq_t message_queue;

int main()
{
    //创建消息队列
    message_queue = rt_mq_create("msg_queue", 30, 2, RT_IPC_FLAG_FIFO);
    if (message_queue == RT_NULL)
    {
        rt_kprintf("create msg_queue failed.\n");
    }

    //往消息队列发送消息
    char senddate[] = "1234567891234567";
    rt_err_t result = rt_mq_send(message_queue, &senddate, sizeof(senddate));
    if (result != RT_EOK)
    {
        rt_kprintf("failed to send message.\n");
    }

    //从消息队列中接收
    char recvbuf[30] = { 0 };
    if (rt_mq_recv(message_queue, &recvbuf, sizeof(recvbuf), 9000) == RT_EOK)
    {
        rt_kprintf("recv is %s\n", recvbuf);
    }
    else
    {
        rt_kprintf("recv message fail\n");
    }
}

 首先利用rt_mq_create函数进行消息队列的创建。该函数中的参数定义如下:

rt_mq_t rt_mq_create(const char* name, rt_size_t msg_size,
            rt_size_t max_msgs, rt_uint8_t flag);
参数描述
name消息队列的名称
msg_size消息队列中一条消息的最大长度,单位字节
max_msgs消息队列的最大个数
flag消息队列采用的等待方式,它可以取如下数值: RT_IPC_FLAG_FIFO 或 RT_IPC_FLAG_PRIO
返回——
RT_EOK发送成功
消息队列对象的句柄成功
RT_NULL失败

创建好消息队列以后,我们就可以往消息队列里发送消息了,发送消息我们使用的函数是rt_mq_send,他的定义以及参数解释如下。

rt_err_t rt_mq_send (rt_mq_t mq, void* buffer, rt_size_t size);
参数描述
mq消息队列对象的句柄
buffer消息内容
size消息大小
返回——
RT_EOK成功
-RT_EFULL消息队列已满
-RT_ERROR失败,表示发送的消息长度大于消息队列中消息的最大

 这里需要注意的是我们发送消息的大小不应该超过消息队列中一条消息的最大长度,否则消息会发送失败。即rt_mq_create函数中的msg_size要比rt_mq_send的size至少要大一个字节。

发送成功后,我们可以调用rt_mq_recv函数来接收消息队列中的消息。其中rt_mq_recv函数的定义和参数解释如下:

rt_err_t rt_mq_recv (rt_mq_t mq, void* buffer,
                    rt_size_t size, rt_int32_t timeout);
参数描述
mq消息队列对象的句柄
buffer消息内容
size消息大小
timeout指定的超时时间
返回——
RT_EOK成功收到
-RT_ETIMEOUT超时
-RT_ERROR失败,返回错误

 这样我们就实现了动态消息队列的创建、消息发送和消息接收了。

下载运行rtthreadRTrtthread如下图。

 

### RT-Thread 消息队列接收函数 `rt_mq_recv` 的工作原理解析 #### 函数原型 ```c rt_err_t rt_mq_recv(rt_mq_t mq, void* buffer, rt_size_t size, rt_int32_t timeout); ``` 此函数用于从消息队列中接收数据。参数说明如下: - `mq`: 要操作的消息队列句柄。 - `buffer`: 接收缓冲区地址,用于存储接收到的数据。 - `size`: 缓冲区大小,表示可以接收的最大字节数。 - `timeout`: 等待时间,单位为滴答数(tick),如果设置为 `RT_WAITING_FOREVER` 则一直等待直到有可用消息。 #### 工作流程 当调用 `rt_mq_recv` 时,系统会执行以下逻辑[^1]: 1. **检查输入参数的有效性** 验证传入的消息队列指针是否为空以及其他必要条件。 2. **获取当前线程控制块** 获取当前正在运行的线程对象以便后续处理超时机制或阻塞状态管理。 3. **尝试立即取走一条消息** 如果消息队列中有未读取消息,则直接复制到用户提供的缓存区内并返回成功标志;否则进入下一步骤。 4. **判断是否有足够的空间来保存新到来的信息** 若目标缓冲区不足以容纳整个消息体,则不会进行任何实际传输动作而是立刻报错退出。 5. **考虑超时期限设定情况下的行为模式** 对于设置了有限制性的等待周期的情形,在规定时间内持续监测消息队列的状态变化直至满足接收条件或是达到预设时限为止; 6. **在线程无法即时获得所需资源的情况下实施挂起措施** 当前活动单元会被暂时搁置起来让位给其他就绪态的任务继续运作,与此同时将其加入至对应同步原语所维护的等待列表之中去静候唤醒时机的到来。 7. **恢复被中断之前正常运转着的那个进程实例** 只要检测到了新的可利用项存在或者是超过了最大允许停留期限之后就会重新激活原先处于休眠中的实体,并依据实际情况给予恰当的结果反馈。 8. **最终结果汇报** 成功完成上述过程后向应用程序层面上报告此次交互的具体状况,包括但不限于错误码等重要信息。 通过以上步骤可以看出,`rt_mq_recv` 不仅实现了基本的消息传递功能,还充分考虑到多任务环境下的并发性和安全性问题,确保了系统的稳定可靠性能表现。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值