官方文档参考
4.6 Receiving From Multiple Queues
[[FreeRTOS_Mastering_the_FreeRTOS_Real_Time_Kernel-A_Hands-On_Tutorial_Guide.pdf#page=158&selection=5,0,7,30|FreeRTOS_Mastering_the_FreeRTOS_Real_Time_Kernel-A_Hands-On_Tutorial_Guide, page 158]]
官方文档函数参考
164 3.4 xQueueCreateSet()
[[FreeRTOS_Reference_Manual_V10.0.0.pdf#page=164&selection=0,3,4,17|FreeRTOS_Reference_Manual_V10.0.0, page 164]]
队列集合 Queue Set
- 多个任务把数据写进各自的 Queue 中,然后一个任务分别从这个队列中读取数据。
- FreeRTOS提供一个函数接口,可以让读取任务从集合中取得对应队列的句柄,然后再从对应的队列中读出数据。
xQueueCreateSet()
#include "FreeRTOS.h"
#include "queue.h"
QueueSetHandle xQueueCreateSet( const UBaseType_t uxEventQueueLength );
函数说明:
- 创建一个队列集合
参数:
uxEventQueueLength:
需要加进队列集合的总长度。例如 Queue1 长度为 5 , Queue2 长度为 2 ,则此参数应赋值为 7。
返回值:
NULL:
创建队列集合失败。其他:
创建队列集合成功,返回队列集合。
xQueueAddToSet()
#include "FreeRTOS.h"
#include "task.h"
baseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet );
函数说明:
- 将队列加入到队列集合。
参数:
xQueueOrSemaphore:
要加入队列集合的队列。xQueueSet:
队列集合。
返回值:
pdPASS:
添加成功。pdFAIL:
添加失败。
xQueueSelectFromSet()
#include "FreeRTOS.h"
#include "task.h"
QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait );
函数说明:
- 从队列集合中选择由数据的队列。
参数:
xQueueSet:
队列集合。xTickToWait:
等待时间。
返回值:
NULL:
超过等待时间后,仍不存在由数据的队列或信号。Any:
队列句柄。other value:
包含数据的队列集合,或者包含信号的句柄(转换为QueueSetMemberHandle_t
类型)。
代码示例
#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"
#include "freertos/queue.h"
void sender_task_1(void *pvPara)
{
QueueHandle_t QHandle = (QueueHandle_t)pvPara;
int numToSend = 1;
while (true) {
xQueueSendToBack(QHandle, &numToSend, 0);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
void sender_task_2(void *pvPara)
{
QueueHandle_t QHandle = (QueueHandle_t)pvPara;
int numToSend = 2;
while (true) {
xQueueSendToBack(QHandle, &numToSend, 0);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
void receiver_task(void *pvPara)
{
// 创建消息队列集合,接收形参赋值
QueueSetHandle_t QSetHandle = (QueueSetHandle_t)pvPara;
// 创建消息队列集合成员句柄
QueueSetMemberHandle_t queue_data;
int numToReceive = 0;
while (true) {
// 选出有消息的队列,将队列句柄赋值给 queue_data
queue_data = xQueueSelectFromSet(QSetHandle, portMAX_DELAY);
// 从 queue_data 队列句柄接收消息
xQueueReceive(queue_data, &numToReceive, portMAX_DELAY);
printf("[RECEIVER]: %d\n", numToReceive);
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}
void app_main(void)
{
// 创建两个消息队列
QueueHandle_t QHandle1 = xQueueCreate(5, sizeof(int));
QueueHandle_t QHandle2 = xQueueCreate(5, sizeof(int));
// 创建消息队列集合
QueueSetHandle_t QSetHandle = xQueueCreateSet(5+5);
// 将两个消息队列添加到队列集合
xQueueAddToSet(QHandle1, QSetHandle);
xQueueAddToSet(QHandle2, QSetHandle);
if (QHandle1 && QHandle2 && QSetHandle) {
xTaskCreate(sender_task_1, "Sender Task 1", 2048, (void *)QHandle1, 2, NULL);
xTaskCreate(sender_task_2, "Sender Task 2", 2048, (void *)QHandle2, 1, NULL);
xTaskCreate(receiver_task, "Receiver Task", 2048, (void *)QSetHandle, 3, NULL); // 传递给接收函数队列集合句柄
} else {
printf("[MAIN]: Do not have enough memory to create a queue.\n");
}
}