Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
rt_mq_消息队列_msg_queue
关于RT-thread 消息队列的一些疑问
发布于 2024-08-16 14:32:05 浏览:281
订阅该版
#1消息队列初始化时的msg_size参数含义 ```c 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); ``` ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240816/7e30de73d9848b24e6ad3ce1a0118e39.png.webp) 我的的消息结构体是这样的,每次传递一个消息send_data[]大于2个字节,为什么消息还能发送并接收成功? ```c typedef struct { ID_t eDataID; rt_uint32_t lDataValue; }Data_t; /* 定义 2 个结构体 */ static const Data_t send_data[2] = { {eMotorSpeed, 10}, // CAN 线程发送的数据 {eSpeedSetPoint, 500} // HMI 线程 }; ``` ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240816/a00a9cdf75a288b37ab94cdf2660db14.png.webp) #2关于线程接收问题 源码见最后。接收线程是一个没有问题,若两个线程分别接收CAN数据和HMI数据,假如CAN接收数据线程的优先级高于HMI线程的话,那么CAN线程会有限读取消息队列中的数据,若读到的HMI的数据,那么这一个HMI的数据是不是就被丢掉了,因为读取消息队列中的数据时,它的head指针会变化。 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240816/029fb63a178ef2cd13769561557442cf.png.webp) #源码 ```c /* * Copyright (c) 2006-2024, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2024-08-15 RT-Thread first version */ #include
#define DBG_TAG "main" #define DBG_LVL DBG_LOG #include
#define THREAD_PRIORITY 25 #define THREAD_STACK_SIZE 512 #define THREAD_TIMESLICE 5 static rt_thread_t thread1; static rt_thread_t thread2; static rt_thread_t thread3; //static rt_thread_t thread4; /* 消息队列控制块 */ static struct rt_messagequeue mq; /* 消息队列中用到的放置消息的内存池 */ static rt_uint8_t msg_pool[2048]; /* 定义 2 种数据来源 (ID) */ typedef enum { eMotorSpeed, eSpeedSetPoint } ID_t; /* 定义在消息队列中传输的数据的格式 */ typedef struct { ID_t eDataID; rt_uint32_t lDataValue; }Data_t; /* 定义 2 个结构体 */ static const Data_t send_data[2] = { {eMotorSpeed, 10}, // CAN 线程发送的数据 {eSpeedSetPoint, 500} // HMI 线程 }; /* 线程 1 的入口函数 */ static void thread1_entry(void *parameter) { int result; Data_t *buf = parameter; while(1) { /* 发送消息 */ result = rt_mq_send(&mq, buf, sizeof(buf)); if (result == RT_EFULL) { rt_kprintf("rt_mq_send FULL\n"); } else if(result ==RT_ERROR) { rt_kprintf("rt_mq_send ERR\n"); } rt_thread_mdelay(20); } } /* 线程 3 的入口函数 */ static void thread3_entry(void *parameter) { Data_t buf; while(1) { /* 接收消息 */ if (rt_mq_recv(&mq, &buf, sizeof(buf), RT_WAITING_FOREVER) == RT_EOK) { if(buf.eDataID == eSpeedSetPoint) { rt_kprintf("From HMI = %d\r\n", buf.lDataValue); } ////若只用一个接收线程这里打开,若开启thread4,这里屏蔽 else if(buf.eDataID == eMotorSpeed) { rt_kprintf("From CAN =%d\r\n", buf.lDataValue); } } rt_thread_mdelay(10); } } ///* 线程 4 的入口函数 */ //static void thread4_entry(void *parameter) //{ // Data_t buf; // // while(1) // { // /* 接收消息 */ // if (rt_mq_recv(&mq, &buf, sizeof(buf), RT_WAITING_FOREVER) == RT_EOK) // { // if(buf.eDataID == eMotorSpeed) // { // rt_kprintf("From CAN =%d\r\n", buf.lDataValue); // } // // } // rt_thread_mdelay(10); // } //} int main(void) { rt_err_t result; /* 初始化消息队列 */ result = rt_mq_init(&mq, // 消息队列对象的句柄 "mqt", // 消息队列的名字 &msg_pool[0], // 内存池指向 msg_pool 2, // 每个消息的大小是 1 字节 sizeof(msg_pool), // 内存池的大小是 msg_pool 的大小 RT_IPC_FLAG_FIFO); // 如果有多个线程等待,按照先来先得到的方法分配消息 if (result != RT_EOK) { rt_kprintf("rt_mq_init ERR\n"); return -1; } /* 创建动态线程 thread1 ,优先级为 THREAD_PRIORIT = 15 */ thread1 = rt_thread_create("thread1", // 线程名字 thread1_entry, // 入口函数 (void *)&send_data[0], // 入口 函数参数 THREAD_STACK_SIZE, // 栈大小 THREAD_PRIORITY, // 线程优先级 THREAD_TIMESLICE); // 线程时间片大小 /* 判断创建结果 , 再启动线程 1 */ if (thread1 != RT_NULL) rt_thread_startup(thread1); /* 创建动态线程 thread2 ,优先级为 THREAD_PRIORIT = 15 */ thread2 = rt_thread_create("thread2", // 线程名字 thread1_entry, // 入口函数 (void *)&send_data[1], // 入口函数参数 THREAD_STACK_SIZE, // 栈大小 THREAD_PRIORITY, // 线程优先级 THREAD_TIMESLICE); // 线程时间片大小 /* 判断创建结果 , 再启动线程 2 */ if (thread2 != RT_NULL) rt_thread_startup(thread2); /* 创建动态线程 thread3 ,优先级为 THREAD_PRIORIT+1 = 16 */ thread3 = rt_thread_create("thread3", // 线程名字 thread3_entry, // 入口函数 RT_NULL, // 入口函数参数 THREAD_STACK_SIZE, // 栈大小 THREAD_PRIORITY + 1, // 线程优先级 THREAD_TIMESLICE); // 线程时间片大小 /* 判断创建结果 , 再启动线程 3 */ if (thread3 != RT_NULL) rt_thread_startup(thread3); // /* 创建动态线程 thread3 ,优先级为 THREAD_PRIORIT+1 = 16 */ // thread4 = rt_thread_create("thread4", // 线程名字 // thread4_entry, // 入口函数 // RT_NULL, // 入口函数参数 // THREAD_STACK_SIZE, // 栈大小 // THREAD_PRIORITY - 2, // 线程优先级 // THREAD_TIMESLICE); // 线程时间片大小 // /* 判断创建结果 , 再启动线程 4 */ // if (thread4 != RT_NULL) // rt_thread_startup(thread4); return 0; } ```
查看更多
2
个回答
默认排序
按发布时间排序
张世争
2024-08-17
学以致用
发送数据 `send_data` 为【全局变量】,造成你的误判,建议把 消息队列的数据改为局部变量,这样可以验证你的想法
sync
2024-08-17
这家伙很懒,什么也没写!
上面的源码是跑不出正确结果的 ```C /* 发送消息 */ result = rt_mq_send(&mq, buf, sizeof(buf)); ``` sizeof(buf)是指针的大小,为4字节。 正确操作应该为结构体Data_t的大小 ```C /* 发送消息 */ result = rt_mq_send(&mq, buf, sizeof(Data_t)); ``` 另外rt_mq_init没有设置正确msg_size,rt_mq_send将会返回-RT_ERROR ```C /* greater than one message size */ if (size > mq->msg_size) return -RT_ERROR; ```
撰写答案
登录
注册新账号
关注者
0
被浏览
281
关于作者
BeijiaPunk
这家伙很懒,什么也没写!
提问
1
回答
0
被采纳
0
关注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
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
2
RT-Thread 发布 EtherKit开源以太网硬件!
3
rt-thread使用cherryusb实现虚拟串口
4
《C++20 图形界面程序:速度与渲染效率的双重优化秘籍》
5
《原子操作:程序世界里的“最小魔法单位”解析》
热门标签
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
ota在线升级
UART
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
at_device
ulog
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
张世争
8
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
KunYi
6
个答案
1
次被采纳
本月文章贡献
程序员阿伟
5
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部