Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
rt_mq_消息队列_msg_queue
使用消息队列做 同步应用
发布于 2019-02-13 19:07:37 浏览:3060
订阅该版
**同步消息**在一般的系统设计中会经常遇到要发送同步消息的问题,这个时候就可以根据当时状态的不同选择相应的实现:两个线程间可以采用**[消息队列 + 信号量或邮箱]**的形式实现。 发送线程通过消息发送的形式发送相应的消息给消息队列,发送完毕后希望获得接收线程的收到确认, 工作示意图如下图所示: ![07msg_syn.png](https://www.rt-thread.org/document/site/programming-manual/ipc2/figures/07msg_syn.png) 看到消息队列中有提到这个,就想简单试一下: 功能改造原来的msgq_sample 中 5ms 发送20个数据到消息队列,然后50ms 以后接收。 改造成:只有收到确认信息,才发送。这里使用邮箱来确认。 代码如下:主要就是做个记录: ```c /* * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2018-08-24 yangjie the first version */ /* * 程序清单:消息队列例程 * * 这个程序会创建2个动态线程,一个线程会从消息队列中收取消息;一个线程会定时给消 * 息队列发送 普通消息和紧急消息。 */ #include
#define THREAD_PRIORITY 25 #define THREAD_TIMESLICE 5 /* 消息队列控制块 */ static struct rt_messagequeue mq; /* 邮箱控制块 */ static struct rt_mailbox mb; /* 消息队列中用到的放置消息的内存池 */ static rt_uint8_t msg_pool[2048]; /* 用于放邮件的内存池 */ static char mb_pool[128]; static char mb_str1[] = "I'm a mail!"; ALIGN(RT_ALIGN_SIZE) static char thread1_stack[1024]; static struct rt_thread thread1; struct msg { rt_uint8_t *data_ptr; /* 数据块首地址 */ rt_uint32_t data_size; /* 数据块大小 */ struct rt_mailbox ack; }; /* 线程1入口函数 */ static void thread1_entry(void *parameter) { char buf = 0; rt_uint8_t cnt = 0; while (1) { /* 从消息队列中接收消息 */ if (rt_mq_recv(&mq, &buf, sizeof(buf), RT_WAITING_FOREVER) == RT_EOK) { /* 发送 mb_str1 地址到邮箱中 */ rt_mb_send(&mb, (rt_uint32_t)&mb_str1); rt_kprintf("thread1: recv msg from msg queue, the content:%c
", buf); if (cnt == 19) { break; } } /* 延时50ms */ cnt++; rt_thread_mdelay(50); } rt_kprintf("thread1: detach mq
"); rt_mq_detach(&mq); } ALIGN(RT_ALIGN_SIZE) static char thread2_stack[1024]; static struct rt_thread thread2; /* 线程2入口 */ static void thread2_entry(void *parameter) { int result; char buf = 'A'; rt_uint8_t cnt = 0; char *str; while (1) { if (cnt == 8) { /* 发送紧急消息到消息队列中 */ result = rt_mq_urgent(&mq, &buf, 1); if (result != RT_EOK) { rt_kprintf("rt_mq_urgent ERR
"); } else { rt_kprintf("thread2: send urgent message - %c
", buf); } } else if (cnt >= 20)/* 发送20次消息之后退出 */ { rt_kprintf("message queue stop send, thread2 quit
"); break; } else { rt_kprintf("thread2: try to recv a mail
"); /* 从邮箱中收取邮件 */ if ((cnt == 0) || (rt_mb_recv(&mb, (rt_uint32_t *)&str, RT_WAITING_FOREVER) == RT_EOK)) { rt_kprintf("thread2: get a mail from mailbox, the content:%s
", str); /* 发送消息到消息队列中 */ result = rt_mq_send(&mq, &buf, 1); if (result != RT_EOK) { rt_kprintf("rt_mq_send ERR
"); } rt_kprintf("thread2: send message - %c
", buf); } } buf++; cnt++; /* 延时5ms */ rt_thread_mdelay(5); } } /* 消息队列示例的初始化 */ int msgq_sample(void) { rt_err_t result; /* 初始化消息队列 */ result = rt_mq_init(&mq, "mqt", &msg_pool[0], /* 内存池指向msg_pool */ 1, /* 每个消息的大小是 1 字节 */ sizeof(msg_pool), /* 内存池的大小是msg_pool的大小 */ RT_IPC_FLAG_FIFO); /* 如果有多个线程等待,按照先来先得到的方法分配消息 */ if (result != RT_EOK) { rt_kprintf("init message queue failed.
"); return -1; } /* 初始化一个 mailbox */ result = rt_mb_init(&mb, "mbt", /* 名称是 mbt */ &mb_pool[0], /* 邮箱用到的内存池是 mb_pool */ sizeof(mb_pool) / 4, /* 邮箱中的邮件数目,因为一封邮件占 4 字节 */ RT_IPC_FLAG_FIFO); /* 采用 FIFO 方式进行线程等待 */ if (result != RT_EOK) { rt_kprintf("init mailbox failed.
"); return -1; } rt_thread_init(&thread1, "thread1", thread1_entry, RT_NULL, &thread1_stack[0], sizeof(thread1_stack), THREAD_PRIORITY, THREAD_TIMESLICE); rt_thread_startup(&thread1); rt_thread_init(&thread2, "thread2", thread2_entry, RT_NULL, &thread2_stack[0], sizeof(thread2_stack), THREAD_PRIORITY, THREAD_TIMESLICE); rt_thread_startup(&thread2); return 0; } /* 导出到 msh 命令列表中 */ MSH_CMD_EXPORT(msgq_sample, msgq sample); ``` ![55.png](/uploads/201902/13/190729d78r8gcxzej4cdav.png)
查看更多
4
个回答
默认排序
按发布时间排序
大话西游2018
2019-02-14
这家伙很懒,什么也没写!
你这个也是一种方法,但我觉得不是RTT编程指南里说写的方法。 [attach]7491[/attach] 看一下我的帖子 - [RT Thread编程指南: 队列消息包含邮箱以及信号量](https://club.rt-thread.org/ask/question/9708809a34e23dc9.html)
小住住
认证专家
2019-02-14
这家伙很懒,什么也没写!
>你这个也是一种方法,但我觉得不是RTT编程指南里说写的方法。 我简化了,主要是如是使用msg 结构体的话,改的东西,比现在的多,为了省事,就简化处理。 想体验一下 这个同步的过程,觉得原理是一样的。
大话西游2018
2019-02-23
这家伙很懒,什么也没写!
>我简化了,主要是如是使用msg 结构体的话,改的东西,比现在的多,为了省事,就简化处理。想体验一下 这 ... 哦 哦
07lhluo
2023-01-05
这家伙很懒,什么也没写!
那请问结构体中的struct rt_mailbox ack成员,如何使用?没看到你使用这个成员。
撰写答案
登录
注册新账号
关注者
0
被浏览
3.1k
关于作者
小住住
这家伙很懒,什么也没写!
提问
129
回答
126
被采纳
2
关注TA
发私信
相关问题
1
rt_object_init中报assertion failed错误?
2
在 MDK中的NANO 里创建消息队列失败,内存堆已开启
3
如何用消息队列传递结构体数据
4
消息队列满了以后接收乱码
5
消息队列传输不定长数据
6
使用消息队列在线程中发送总失败
7
初始化第二个消息队列时发生硬件错误
8
rtthread消息队列一对多的情况
9
消息队列为什么会出现获取到的内容有旧的数据?
10
通过消息队列名称,获取消息队列句柄
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
开源共生 商业共赢 | RT-Thread 2024开发者大会议程正式发布!
2
【24嵌入式设计大赛】基于RT-Thread星火一号的智慧家居系统
3
RT-Thread EtherKit开源以太网硬件正式发布
4
如何在master上的BSP中添加配置yml文件
5
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
MicroPython
ulog
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
19
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
6
个答案
2
次被采纳
用户名由3_15位
13
个答案
1
次被采纳
本月文章贡献
程序员阿伟
9
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
RTT_逍遥
1
篇文章
5
次点赞
大龄码农
1
篇文章
5
次点赞
ThinkCode
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部