16.FreeRTOS数据结构:StreamBuffer,MessageBuffer和Queue的区别

FreeRTOS数据结构:StreamBuffer,MessageBuffer和Queue的区别

介绍

在嵌入式系统开发中,任务间的通信是非常重要的一部分。FreeRTOS提供了多种数据结构来实现任务间的通信,包括StreamBufferMessageBufferQueue。这三种数据结构各又什么特点又有什么区别呢?

StreamBuffer

StreamBuffer是FreeRTOS中用于任务间或任务与中断间连续数据传输的数据结构。它允许你发送和接收任意长度的数据。StreamBuffer的主要特点是:

  • 数据连续:StreamBuffer传输连续的数据,可以一次写入任意数量的字节,并且可以一次读取任意数量的字节。
  • 适用场景:StreamBuffer主要应用于一个发送者一个接收者的场景,比如从中断发送给task,或者从一个cpu核发送到另一个cpu核。

MessageBuffer

MessageBuffer是FreeRTOS中用于任务间或任务与中断间离散数据传输的数据结构。它允许你发送和接收带有长度的消息。MessageBuffer的主要特点是:

  • 数据离散:MessageBuffer传送离散的带有长度的消息,每一条消息的写入增加了一个字节用来表示该条消息的长度。
  • 适用场景:MessageBuffer非固定长度,带有长度标签,适合传输协议帧数据。

Queue

Queue是FreeRTOS中用于任务间或任务与中断间数据传输的数据结构。它允许你发送和接收固定大小的数据项。Queue的主要特点是:

  • 数据固定:Queue传送固定大小的数据项,每一条数据项的大小在创建队列时确定。
  • 适用场景:Queue适用于多任务间的数据传输,可以有多个发送者和接收者。

Stream Buffer 和 Message Buffer的一些不同:

它们都可以用于任务-任务,任务-中断的数据传输,都遵循FIFO先进先出原则,数据传递的方式为拷贝。但是,它们之间存在一些关键的区别:

  1. 数据单位Stream Buffer传输连续的数据,可以一次写入任意数量的字节,并且可以一次读取任意数量的字节。而Message Buffer传送离散的带有长度的消息,每一条消息的写入增加了四个字节用来表示该条消息的长度。

  2. 接收方式Message Buffer一次只能接收1条Message,而Stream Buffer则根据长度接收。Message Buffer在接收缓冲区<1条消息大小时,不会接收,而Stream Buffer则会将数据截断接收。

  3. 使用场景Stream Buffer主要应用于一个发送者一个接收者的场景,比如从中断发送给task,或者从一个cpu核发送到另一个cpu核。而Message Buffer非固定长度,带有长度标签,适合传输协议帧数据。

需要注意的是,与大多数其他FreeRTOS API不同的是,Stream BufferMessage Buffer针对单个读取器单写入器场景进行了优化,例如将数据从中断服务例程传递到任务,或者从双核CPU上的一个微控制器核心传递到另一个。在多任务读写的环境中,需要将该函数相关的调用置于关键区域内(taskENTER_CRITICAL和taskEXIT_CRITICAL),也可以使用互斥信号量来解决。

以下是StreamBufferMessageBuffer接收数据的示例:

StreamBuffer示例

假设我们有一个StreamBuffer,其中包含字符串"Hello, World!"(包括结束符’\0’,总共13个字节)。我们的接收缓冲区只有10个字节的大小。

char pcReceivedString[10];
size_t xReceivedBytes;

xReceivedBytes = xStreamBufferReceive(xStreamBuffer, (void *)pcReceivedString, 10, portMAX_DELAY);

在这种情况下,xStreamBufferReceive()将会接收前10个字节的数据(“Hello, Wor”),并返回接收到的字节数(10)。剩下的数据(“ld!\0”)仍然留在StreamBuffer中。

MessageBuffer示例

假设我们有一个MessageBuffer,其中包含消息"Hello, World!"(包括结束符’\0’,总共13个字节,加上4个字节的长度字段,总共17个字节)。我们的接收缓冲区只有10个字节的大小。

char pcReceivedMessage[10];
size_t xReceivedBytes;

xReceivedBytes = xMessageBufferReceive(xMessageBuffer, (void *)pcReceivedMessage, 10, portMAX_DELAY);

在这种情况下,xMessageBufferReceive()将会检查下一条消息的大小。由于下一条消息的大小(13个字节)大于接收缓冲区的大小(10个字节),xMessageBufferReceive()将不会接收任何数据,而是立即返回0。消息"Hello, World!"仍然完整地留在MessageBuffer中。

结语

这就是StreamBufferMessageBuffer在接收数据时的主要区别。StreamBuffer会根据长度接收数据,即使这意味着数据会被截断。而MessageBuffer则会检查整条消息是否可以完整地接收,如果不能,它就不会接收任何数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宁子希

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值