消息队列接口设计不合理,rt_mq_recv应该传出消息的实际大小
向消息队列发送消息时调用:
rt_mq_send(&mq, data, data_len);
可发送指定长度的消息。 而在接受时调用:
char buff[MAX_SIZE];
rt_mq_recv(&mq, buff, MAX_SIZE, timeout);
无法取到所发送数据的实际长度,必须自己设计数据结构在data中存放长度,造成编程上的不便以及不必要的开销。 建议给recv增加一个可传出实际消息长度的版本,类似这样:
rt_err_t rt_mq_recv_with_size(rt_mq_t mq,
void *buffer,
rt_size_t size,
rt_size_t *real_size,
rt_int32_t timeout)
消息队列里的消息体要求是固定等长的 不是你这样用的 发送的消息体长度是 data_len 接收的时候也必须是 data_len 消息队列消息池的大小是消息体字节大小乘以最大容纳消息个数。更多描述可以看 https://club.rt-thread.org/ask/article/3186.html 这里的相关小节
见官方API参考手册中"详细描述"一节,其中明确提到:
消息队列可以应用于发送不定长消息的场合
只要所发送消息小于创建消息队列时指定的最大msg_size即可。
而且实际中也是有很多需要传输变长消息的需求的,如果只能传定长消息那就只能用固定消息头+动态分配payload内存的形式,这样带来的性能开销特别大。
描述有问题,上面论坛链接里也有提到几种传递不定长消息的方式。可以看看哪种适合你。 目前没有不定长消息机制
感觉这个可以在5.0里改进一下,确实用的很难受,接受发送API里message size那个参数填了根本没啥意义
mq本身是用于快速的,小批量的消息传输,并不是还针对每个消息还设计成变长的。如果是变长方式,内部设计都会变化,一些特性要支持起来也会带来更大的代价。
在接收消息时,可以获得这个消息的长度,这个也许是可以,例如每条消息变成:
struct msg{
len_type_t len;
uint8_t data[0];
};
- 这里的len_type_t也会引入歧途,uint16_t,那么后续的data肯定也就不是32位对齐,这个时候在对齐面前又会有一定的尴尬;
- 如果len_type_t是uint32_t,那么前面的空间肯定也就浪费掉了的。
确切的说,应该是消息的内存池是肯定是定长的,消息长度不能多于一个消息的内存池大小,但是小于是可以的。因此需要返回实际消息的大小。
https://github.com/RT-Thread/rt-thread/pull/7709 此PR已经解决