使用 message buffer 传递数据
概述
MessageBuffer,即消息缓冲区,是在流式缓冲区的基础上实现的针对离散消息的专用通信组件,其进一步针对“消息”进行设计改进。
在 StreamBuffer 的基础上,MessageBuffer 对每条数据的长度进行了记录。MessageBuffer每一条消息的写入增加了一个字段用来表示该条消息的长度。读取时需要一次性读出至少一条消息,否则会返回读取失败。
如下所示,在使用 MessageBuffer 时发送数据的一方在调用发送数据的接口时,组件会自动记录该条消息的长度。接收数据的一方接收到该条数据时,可以知道该条数据的长度。而 StreamBuffer 会把这些数据处理成连续的字节流,没有明确的区分它们到底属于什么结构的数据。
与 StreamBuffer 一样,MessageBuffer 适用于 一个发送者、一个接收者的数据通信场景。在多个发送者、接收者时需要添加互斥保护机制。
主要的 API 如下:
MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes );
size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer,
const void *pvTxData,
size_t xDataLengthBytes,
TickType_t xTicksToWait );
size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer,
void *pvRxData,
size_t xBufferLengthBytes,
TickType_t xTicksToWait );
需求及功能解析
示例给出了使用 MessageBuffer 发送两种不同的离散消息的场景:
uint8_t ArrayToSend1[] = { 0, 1, 2, 3 };
uint8_t ArrayToSend2[] = { 4, 5, 6, 7, 8, 9};
示例解析
使用 MessageBuffer 发送两种不同的离散消息的示例输出如下:
This is esp32 chip with 2 CPU core(s), WiFi/BT/BLE, Minimum free heap size: 295348 bytes
TASK1: array is 1
TASK2: receive length is 4
TASK2: The buffer data is as follows:00 01 02 03
TASK1: array is 2
TASK2: receive length is 6
TASK2: The buffer data is as follows:04 05 06 07 08 09
TASK1: array is 1
TASK2: receive length is 4
TASK2: The buffer data is as follows:00 01 02 03
TASK1: array is 2
TASK2: receive length is 6
TASK2: The buffer data is as follows:04 05 06 07 08 09
TASK1: array is 1
TASK2: receive length is 4
TASK2: The buffer data is as follows:00 01 02 03
讨论
1)存储身份证号和手机号的场景中,使用 queue、stream buffer、message buffer 时的示意图如下:
队列因为只能存储固定大小的数据,它需要按照最长的数据“身份证号”分配两块空间来存储身份证号+手机号。并且接收方要接收两次数据才能接收一次完整的身份证号+手机号。
流式缓存区可以存储身份证号和手机号,但它没有记录两者的长度,不容易区分到底哪部分数据属于身份证号、哪部分属于手机号,它不适合处理离散的数据块。
消息缓存区存储身份证号、手机号,并自动地记录它们的长度,最适合处理这种离散的消息。
2)目前讲述的通信组件 queue、StreamBuffer、MessageBuffer都具备一定的缓存能力,但他们都没有提供管理数据溢出的机制,即缓冲区写满之后,再次写入数据如何处理的问题,我们将在下一节介绍一种提供这个溢出管理机制的通信组件-ringbuffer。
总结
1)队列 queue 处理固定大小的消息,通常是一个结构,但它也可以是一个包含指针的基类型。StreamBuffer 流缓冲区将消息作为字节流进行处理。消息将作为一个单元放入队列中,并且没有任何固定大小(只是它应该适合缓冲区的最大值),并且在取出时,可以以任意长度检索获取存入的数据。消息缓冲区保存具有固定大小的离散消息,但每条消息不必具有相同的大小,并且在取出时,消息的形式与存入时完全一致。
2)MessageBuffer 与 StreamBuffer 一样,适用于 一个发送者、一个接收者的数据通信场景。在多个发送者、接收者时需要添加互斥保护机制。
资源链接
1)Learning-FreeRTOS-with-esp32 系列博客介绍
2)对应示例的 code 链接 (点击直达代码仓库)
3)下一篇:使用 Ring Buffer 完成数据传递
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)