在FreeRTOS中,队列(Queue)和信号量(Semaphore)是两种常用的通信机制,用于在任务之间传递数据或同步。然而,当需要同时等待多个队列或信号量时,队列集(Queue Set)提供了一种更为灵活的解决方案。本文将详细介绍FreeRTOS中的队列集,并通过示例代码展示其使用方法。
目录
队列集概述
队列集允许任务同时等待多个队列或信号量中的任何一个变为可用。队列集本身是一个集合,可以包含多个队列和信号量。当集合中的任意一个队列或信号量有数据可用时,任务将被唤醒,并可以确定是哪个队列或信号量变为可用。
队列集的创建和使用
- 创建队列集:首先,创建一个队列集并指定其大小,即可以包含的队列和信号量的总数。
- 创建并添加队列和信号量:将队列和信号量创建并添加到队列集中。
- 等待队列集事件:任务可以阻塞等待队列集中的任何一个队列或信号量变为可用。
- 处理事件:任务被唤醒后,需要检查哪个队列或信号量变为可用,并进行相应处理。
示例代码
以下是一个示例代码,展示了如何在FreeRTOS中使用队列集:
#include <FreeRTOS.h>
#include <task.h>
#include <queue.h>
#include <semphr.h>
// 定义队列和信号量句柄
QueueHandle_t xQueue1, xQueue2;
SemaphoreHandle_t xBinarySemaphore;
QueueSetHandle_t xQueueSet;
void vSenderTask1(void *pvParameters)
{
const char *pcMessage = "Message from Sender 1";
for (;;)
{
// 发送消息到队列1
xQueueSend(xQueue1, &pcMessage, portMAX_DELAY);
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
void vSenderTask2(void *pvParameters)
{
const char *pcMessage = "Message from Sender 2";
for (;;)
{
// 发送消息到队列2
xQueueSend(xQueue2, &pcMessage, portMAX_DELAY);
vTaskDelay(pdMS_TO_TICKS(1500));
}
}
void vReceiverTask(void *pvParameters)
{
QueueSetMemberHandle_t xActivatedMember;
char *pcReceivedMessage;
for (;;)
{
// 等待队列集中的任意一个队列或信号量变为可用
xActivatedMember = xQueueSelectFromSet(xQueueSet, portMAX_DELAY);
// 检查哪个队列变为可用并处理消息
if (xActivatedMember == xQueue1)
{
xQueueReceive(xQueue1, &pcReceivedMessage, 0);
printf("Received from Queue 1: %s\n", pcReceivedMessage);
}
else if (xActivatedMember == xQueue2)
{
xQ