使用消息队列 queue 实现数据通信

使用消息队列 queue 实现数据通信

概述

如前所述:使用全局变量传递数据的方式存在一些限制,如读写时的数据保护与同步问题、数据缓存的问题(新数据会覆盖旧数据)。

使用队列则可以自动解决上述问题。队列在实现上已经添加了一定的读写保护、并具备一定的存储长度,来缓存一定的数据。当发送数据的一方速度快于使用数据的一方,或者多个数据发送方的情况下,这种缓存机制可以缓解使用数据的一方的一定的处理压力。

此外,队列实现的延时发送机制(发送失败的情况下,若延时时间不为0,可以等待一段时间再发送数据)也可以改善通信双方的速率差异。

xQueueSend(xQueue, // 要发送数据的队列
pvItemToQueue,     // 要发送到队列的条目(item)
xTicksToWait)      // 队列满时,延时等待的时间

用邮箱实现多事件的单向同步章节中,已经介绍了队列的基本使用方法和注意事项,这里仅从数据通信的角度给出一些示例。

需求及功能解析

队列适合每次传输的数据长度固定的情况,并且可以应用在数据传输中有多个发送方、多个接收方的的场景。

实际的项目中,产生数据的一方可能多次生产数据,然后将数据发送到另一个任务进行处理。比如,数据采集设备中会多次采集数据,然后将数据发送到另一个任务进行计算、显示到屏幕上等。

示例给出了这样的示例:任务1每生产五个数据,就通过队列发送到任务2。

示例解析

示例输出:

This is esp32 chip with 2 CPU core(s), WiFi/BT/BLE, Minimum free heap size: 295348 bytes
TASK2: The buffer data is as follows:00 00 00 00 00 

TASK2: The buffer data is as follows:00 01 02 03 04 

TASK2: The buffer data is as follows:05 06 07 08 09 

TASK2: The buffer data is as follows:0a 0b 0c 0d 0e 

讨论

对多次产生数据,集中处理一次的应用场景,使用队列时,存在以下的限制:

1)队列要求每次产生的条目的长度是一样的,如示例中创建的队列的元素类型为 int array[5],则每次最大发送5个数据,超过5个数据的情况下,无法使用该队列进行传输。

2)多次采集单次触发发送的机制需要自己在应用层进行实现。示例中发送方任务1通过计数,来控制这种逻辑:

if(remainder == 0) {
     if (xQueueSendToFront(custom_queue, (void *)&data_send, 0) != pdTRUE) { // 每五次发送一个数据
           printf("%s: failed send\n", TASK1_TAG); // 检查是否发送失败
     }
}

在后续的学习中,我们将介绍具备发送不固定长度的数据、满足一定数量后自动触发接收的通信组件,它们是队列相关特性的补充。

总结

1)队列兼具数据传输,同步的两种功能。

2)队列适合每次传输的数据长度固定的情况,并且可以应用在数据传输中有多个发送方、多个接收方的的场景。

3)队列的不足之处是要求每次发送的条目的长度是一样的,并且没有实现自动完成多次发送触发单次接收的机制。

4)大部分情况下,复杂的数控类型,队列传递的往往是指针类型。

资源链接

1)Learning-FreeRTOS-with-esp32 系列博客介绍
2)对应示例的 code 链接 (点击直达代码仓库)

3)下一篇:使用 stream buffer 传递数据

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在 FreeRTOS 中,可以使用消息队列实现任务之间的通信消息队列是一个先进先出(FIFO)的数据结构,允许任务发送和接收消息。 要使用消息队列,首先需要创建一个消息队列对象。可以使用 `xQueueCreate()` 函数来创建一个消息队列。该函数接受两个参数:队列的长度和每个消息的大小。例如,下面的代码创建了一个长度为 10,每个消息大小为 4 字节的消息队列: ```c QueueHandle_t queue = xQueueCreate(10, 4); ``` 然后,可以使用 `xQueueSend()` 函数将消息发送到队列中。该函数接受三个参数:待发送的队列句柄、指向要发送的数据的指针和等待时间。如果队列已满,可以选择等待一段时间或者立即返回。例如,下面的代码将一个整数发送到队列中: ```c int data = 42; if (xQueueSend(queue, &data, 0) != pdTRUE) { // 处理发送失败的情况 } ``` 最后,可以使用 `xQueueReceive()` 函数从队列中接收消息。该函数接受三个参数:待接收的队列句柄、指向存储接收数据的缓冲区的指针和等待时间。如果队列为空,可以选择等待一段时间或者立即返回。例如,下面的代码从队列中接收一个整数: ```c int receivedData; if (xQueueReceive(queue, &receivedData, portMAX_DELAY) != pdTRUE) { // 处理接收失败的情况 } else { // 处理接收到的数据 } ``` 以上就是在 FreeRTOS 中使用消息队列的基本步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

物联网老王

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

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

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

打赏作者

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

抵扣说明:

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

余额充值