使用消息队列 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)下一篇:

你可能感兴趣的:(FreeRTOS,ESP,freertos,物联网,iot,c语言,单片机)