使用 stream buffer 传递数据
概述
如前所述,队列虽然提供了任务之间传递数据的功能,但没有对通知机制进行优化,即不方便实现多次采集不同长度的数据,然后触发一次通知接收的机制。
特性概述
Streambuffer 的中文含意是“流式缓冲区”,其特点可以概述如下:
1)发送消息的一方(发送方)与获取消息的一方(接收方)之间可以按任意长度的字节流的方式进行数据传递。
2)可以设置触发唤醒通知的字节数,仅在缓冲区中的数据达到一定长度时,才唤醒接收方接收数据。
3)适用于仅有一个发送方、一个接收方的场景。如果有多个发送方、接收方,则需要在发送、接收处添加互斥保护,特别地,多个接收方时应将接收阻塞时间设置为0。
Streambuffer 的基本结构如图所示,主要由消息缓冲区、管理消息缓冲区的相关字段、解阻塞字节数标记、以及两个阻塞延时列表组成。一定程度上,Streambuffer 可以看作在触发接收的机制上改良的队列。
相关 API
StreamBufferHandle_t xStreamBufferCreate(xBufferSizeBytes,
xTriggerLevelBytes)
size_t xStreamBufferSend(StreamBufferHandle_t xStreamBuffer,
const void *pvTxData,
size_t xDataLengthBytes,
TickType_t xTicksToWait)
size_t xStreamBufferReceive(StreamBufferHandle_t xStreamBuffer,
void *pvRxData,
size_t xBufferLengthBytes,
TickType_t xTicksToWait)
BaseType_t xStreamBufferReset(StreamBufferHandle_txStreamBuffer)
注意,Receive 返回的情况有两种可能:
1)获取到不小于唤醒长度的数据。
2)超时返回,此时实际获取的数据长度为 [0,TriggerLevel]。
API 参考:stream buffer API, 读者可以通过点击网页自行查看每个 API 的使用方法和参数。
需求及功能解析
示例创建了一个 TriggerLevel 为 5 的streambuf,来实现 task1 中每产生五个数据就自动唤醒 task2 处理数据的逻辑。
示例解析
示例输出:
This is esp32 chip with 2 CPU core(s), WiFi/BT/BLE, Minimum free heap size: 295348 bytes
TASK1: flag=0
TASK2: timeout and read some data
TASK2: The buffer data is as follows:00
TASK1: flag=1
TASK1: flag=2
TASK1: flag=3
TASK1: flag=4
TASK1: flag=5
TASK2: read triggle level bytes
TASK2: The buffer data is as follows:01 02 03 04 05
TASK1: flag=6
TASK1: flag=7
TASK1: flag=8
TASK1: flag=9
TASK1: flag=10
TASK2: read triggle level bytes
TASK2: The buffer data is as follows:06 07 08 09 0a
这种自动的触发机制,比上节使用队列的情况要简单了一些。
讨论
Streambuffer 虽然实现了可以发送不定长度的数据串,并规定了一定的触发唤醒机制:即数据量至少达到 TriggerLevel 才唤醒等待数据的任务。
但是一些情况下,发送的数据是不定长度的数据块,每个数据块都具有指定的格式,具备不同的长度,并且不能被拆分和组合。
比如发送数据的任务发送人的身份证号、手机号码。接收数据的任务要准确地识别这些数据,必须知道数据的长度,否则无法区分那部分数据属于身份证数据、手机号码数据。
流式缓冲区无法描述这些不定长数据块的具体长度。我们将在下一节介绍处理不定长离散数据块的通信组件。
总结
1)Streambuffer 可看作针对单一生产者、消费者传输不定长数据通信场景而优化的 queue。
2)Streambuffer 还优化了唤醒机制,可以设置触发唤醒通知的字节数,仅在缓冲区中的数据达到一定长度时,才唤醒接收方接收数据。
3)Streambuffer 可以传输没有固定结构的不定长数据,但是它无法描述这些不定长数据块的具体长度。
资源链接
1)Learning-FreeRTOS-with-esp32 系列博客介绍
2)对应示例的 code 链接 (点击直达代码仓库)
3)下一篇:使用 message buffer 传递数据
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)