Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
Kernel
使用消息队列发送不定长数据一些小疑问
发布于 2019-02-13 16:15:42 浏览:2362
订阅该版
* 本帖最后由 小住住 于 2019-2-13 17:18 编辑 * 按下面的说法:我在onenet线程中 的命令响应回掉函数中,增加发送消息队列到打印线程,但打印的是乱码,不是自己下发的命令。这块的处理,有什么要注意的吗?到打印的时候,原来指针所指的内容好像已经变了。最终测试,这种场合,还是需要源数据是固定不变的的场合。原先的局部变量,执行完回掉函数后,原来的数就变了。所以这种场合还是需要全局变量或者一个静态变量。 ```/* onenet mqtt command response callback function */ static void onenet_cmd_rsp_cb(uint8_t *recv_data, size_t recv_size, uint8_t **resp_data, size_t *resp_size) { char res_buf[] = { "cmd is received!
" }; log_d("recv data is %.*s
", recv_size, recv_data); rs485_transport(recv_data,recv_size); /* user have to malloc memory for response data */ *resp_data = (uint8_t *) ONENET_MALLOC(strlen(res_buf)); strncpy(*resp_data, res_buf, strlen(res_buf)); *resp_size = strlen(res_buf); }``` ```static rt_uint8_t temp_data[20]; void rs485_transport(uint8_t *recv_data, size_t recv_size) { int result; struct msg msg_ptr; //增加一句 先 把数据复制到静态变量中。 strncpy(temp_data, recv_data, recv_size); msg_ptr.data_ptr = temp_data;//recv_data; msg_ptr.data_size = recv_size; rt_pin_write(RS485_RE_DE_Pin, PIN_HIGH); /* 发送消息到消息队列中 */ result = rt_mq_send(&mq,(void*)&msg_ptr,sizeof(struct msg)); if (result != RT_EOK) { rt_kprintf("rt_mq_send ERR
"); } rt_kprintf("thread onenet: send message - %s
", msg_ptr.data_ptr); //rt_pin_write(RS485_RE_DE_Pin, PIN_LOW); } 接收处理: static void serial_thread_entry(void *parameter) { char buf; rt_uint8_t k; struct msg msg_prt; while (1) { /* 从消息队列中接收消息 */ if (rt_mq_recv(&mq, (void*)&msg_prt, sizeof(struct msg), RT_WAITING_FOREVER) == RT_EOK) { rt_device_write(serial, 0, (void*)msg_prt.data_ptr, msg_prt.data_size); } } } ``` ![1.png](/uploads/201902/13/161302arsbb08rqjhxxsxs.png) ![2.png](/uploads/201902/13/161331yef7zxr7xhilxipd.png) 修改添加静态变量后的结果: ![3.png](/uploads/201902/13/171807s4u816h6gupbhugc.png) ```发送消息 消息队列和邮箱的明显不同是消息的长度并不限定在 4 个字节以内;另外,消息队列也包括了一个发送紧急消息的函数接口。但是当创建的是一个所有消息的最大长度是 4 字节的消息队列时,消息队列对象将蜕化成邮箱。这个不限定长度的消息,也及时的反应到了代码编写的场合上,同样是类似邮箱的代码: struct msg { rt_uint8_t *data_ptr; /* 数据块首地址 */ rt_uint32_t data_size; /* 数据块大小 */ }; 和邮箱例子相同的消息结构定义,假设依然需要发送这样一个消息给接收线程。在邮箱例子中,这个结构只能够发送指向这个结构的指针(在函数指针被发送过去后,接收线程能够正确的访问指向这个地址的内容,通常这块数据需要留给接收线程来释放)。而使用消息队列的方式则大不相同: void send_op(void *data, rt_size_t length) { struct msg msg_ptr; msg_ptr.data_ptr = data; /* 指向相应的数据块地址 */ msg_ptr.data_size = length; /* 数据块的长度 */ /* 发送这个消息指针给 mq 消息队列 */ rt_mq_send(mq, (void*)&msg_ptr, sizeof(struct msg)); } 注意,上面的代码中,是把一个局部变量的数据内容发送到了消息队列中。在接收线程中,同样也采用局部变量进行消息接收的结构体: void message_handler() { struct msg msg_ptr; /* 用于放置消息的局部变量 */ /* 从消息队列中接收消息到 msg_ptr 中 */ if (rt_mq_recv(mq, (void*)&msg_ptr, sizeof(struct msg)) == RT_EOK) { /* 成功接收到消息,进行相应的数据处理 */ } } 因为消息队列是直接的数据内容复制,所以在上面的例子中,都采用了局部变量的方式保存消息结构体,这样也就免去动态内存分配的烦恼了(也就不用担心,接收线程在接收到消息时,消息内存空间已经被释放)。```
查看更多
4
个回答
默认排序
按发布时间排序
小住住
认证专家
2019-02-13
这家伙很懒,什么也没写!
>楼主是想使用消息队列发送不定长度的数据吗? 可以看看这个帖子 https://www.rt-thread.org/qa/forum.php?m ... --- 好帖。谢谢。内存池的使用。哈哈。
朝雨绫萧
2019-02-14
这家伙很懒,什么也没写!
消息队列内部有memcpy的操作,不需要拷贝到全局变量里,你通过消息队列发送消息内容就好了,如果发送的是指向消息内容的指针,而这个指针又是指向局部变量的,那么就会出现数据不对的情况
小住住
认证专家
2019-02-14
这家伙很懒,什么也没写!
>消息队列内部有memcpy的操作,不需要拷贝到全局变量里,你通过消息队列发送消息内容就好了,如果发送的是指 ... --- 是这样的,指针指向局部变量,所以数据不对了。
还没想好
2019-02-13
这家伙很懒,什么也没写!
楼主是想使用消息队列发送不定长度的数据吗? 可以看看这个帖子 [https://www.rt-thread.org/qa/forum.php?mod=viewthread&tid=7046&page=1#pid34428](https://www.rt-thread.org/qa/forum.php?mod=viewthread&tid=7046&page=1#pid34428)
撰写答案
登录
注册新账号
关注者
0
被浏览
2.4k
关于作者
小住住
这家伙很懒,什么也没写!
提问
129
回答
126
被采纳
2
关注TA
发私信
相关问题
1
请教cpu使用率分析
2
选择FreeRTOS, 还是RT-Thread。
3
thread heap stack overflow ?
4
rtt消息队列delay问题
5
释放被删除线程的内存地方在哪里啊
6
请教:各线程结束后,释放其中的内存的连续性问题
7
STM32F103中断关于信号量、邮箱问题
8
RTT中的线程栈大小如何控制
9
关于线程由执行态变为挂起态的代码实现,,,
10
rt_malloc(rt_size_t size)内存分配函数最小分配尺寸问题
推荐文章
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
STM32H7R7运行CherryUSB
2
RT-Smart首次线下培训,锁定2024 RT-Thread开发者大会!
3
使用RC522软件包驱动FM1722
4
常量数据类型和表达式陷阱分享
5
进行i2c驱动移植的经验总结
热门标签
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
UART
WIZnet_W5500
ota在线升级
freemodbus
PWM
flash
cubemx
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
中断
编译报错
Debug
SFUD
rt_mq_消息队列_msg_queue
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
踩姑娘的小蘑菇
4
个答案
1
次被采纳
红枫
4
个答案
1
次被采纳
张世争
4
个答案
1
次被采纳
Ryan_CW
4
个答案
1
次被采纳
xiaorui
1
个答案
1
次被采纳
本月文章贡献
catcatbing
3
篇文章
5
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
Woshizhapuren
1
篇文章
5
次点赞
YZRD
1
篇文章
2
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部