RTT-消息队列

本文详细介绍了RT-Thread操作系统中的消息队列概念和接口,包括创建、删除消息队列,以及发送和接收消息的方法。通过示例代码展示了如何在STM32上创建静态和动态消息队列,并在按键触发下发送不同数据到消息队列,接收线程则持续从队列接收并打印数据。
摘要由CSDN通过智能技术生成

RTT-消息队列

参考:《[野火®]《RT-Thread 内核实现与应用开发实战—基于STM32》

概念

消息队列就是一个线程给另一个线程发消息,收到消息就处理,没收到就挂起。
用户还可以指定挂起的线程时间 timeout;当队列中有新消息时,挂起的读取线程被唤醒并处理新消息。
当有多个消息发送到消息队列时,通常是将先进入消息队列的消息先传给线程,,即先进先出原则(FIFO)。
同时 RT-Thread 中的消息队列支持优先级,也就是说在所有等待消息的线程中优先级最高的会先获得消息。
内部的实现,是将消息内容从一个地址复制到另一个地址。

接口

创建静态消息队列

rt_err_t rt_mq_init (rt_mq_t mq, const char *name, void *msgpool, rt_size_t msg_size, rt_size_t pool_size, rt_uint8_t flag)

删除静态消息队列

rt_err_t rt_mq_detach (rt_mq_t mq)

创建动态消息队列

rt_mq_t rt_mq_create (const char *name, rt_size_t msg_size, rt_size_t max_msgs, rt_uint8_t flag)

删除动态消息队列

rt_err_t rt_mq_delete (rt_mq_t mq)

发送消息

rt_err_t rt_mq_send (rt_mq_t mq, void *buffer, rt_size_t size)

发送紧急消息

rt_err_t rt_mq_urgent (rt_mq_t mq, 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)

用法

  1. 定义消息队列控制块
  2. 创建消息
  3. 发送消息
  4. 接收消息
/* 定义线程控制块指针 */
static rt_thread_t key0_thread = RT_NULL;
static rt_thread_t receive_thread = RT_NULL;
/* 定义消息队列控制块 */
static rt_mq_t test_mq = RT_NULL;

/* 创建消息队列 */
test_mq = rt_mq_create("test_mq",/* 消息队列名字 */
                           4,     /* 消息的最大长度 */
                           20,    /* 消息队列的最大容量 */
                           RT_IPC_FLAG_FIFO);/* 队列模式 FIFO(0x00)*/
if (test_mq != RT_NULL)
    rt_kprintf("creat message line success\r\n");

/* 按键发送消息 */
static void key0_thread_entry(void *parameter)
{
    rt_err_t uwRet = RT_EOK;
    uint32_t send_data1 = 1;
    uint32_t send_data2 = 2;
    while (1)
    {
        if (Key_Scan(KEY1_GPIO_PORT, KEY1_GPIO_PIN) == KEY_ON)/* K1 被按下 */
        {
            /* 将数据写入(发送)到队列中,等待时间为 0  */
            uwRet = rt_mq_send(test_mq,  /* 写入(发送)队列的ID(句柄) */
                               &send_data1,            /* 写入(发送)的数据 */
                               sizeof(send_data1));            /* 数据的长度 */
            if (RT_EOK != uwRet)
            {
                rt_kprintf("send1 failed:%lx\n", uwRet);
            }
        }
        if (Key_Scan(KEY2_GPIO_PORT, KEY2_GPIO_PIN) == KEY_ON)/* K1 被按下 */
        {
            /* 将数据写入(发送)到队列中,等待时间为 0  */
            uwRet = rt_mq_send(test_mq,  /* 写入(发送)队列的ID(句柄) */
                               &send_data2,            /* 写入(发送)的数据 */
                               sizeof(send_data2));            /* 数据的长度 */
            if (RT_EOK != uwRet)
            {
                rt_kprintf("send2 failed:%lx\n", uwRet);
            }
        }
        rt_thread_delay(20);
    }


}

/* 接收消息 */
static void receive_thread_entry(void *parameter)
{
    rt_err_t uwRet = RT_EOK;
    uint32_t r_queue;
    /* 任务都是一个无限循环,不能返回 */
    while (1)
    {
        /* 队列读取(接收),等待时间为一直等待 */
        uwRet = rt_mq_recv(test_mq, /* 读取(接收)队列的ID(句柄) */
                           &r_queue,           /* 读取(接收)的数据保存位置 */
                           sizeof(r_queue),        /* 读取(接收)的数据的长度 */
                           RT_WAITING_FOREVER);    /* 等待时间:一直等 */
        if (RT_EOK == uwRet)
        {
            rt_kprintf("rev:%d\n", r_queue);
        }
        else
        {
            rt_kprintf("rev failed:0x%lx\n", uwRet);
        }
        rt_thread_delay(200);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tangYi0_0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值