Queue 队列集合

Queue 队列集合

官方文档参考 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

官方文档参考

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

12. Queue 队列集合-20240614181644834.webp

  • 多个任务把数据写进各自的 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");
    }
}
Comment