【嵌入式——FreeRTOS】队列集

简介

一个队列只允许任务间传递的消息为同一种数据类型,如果需要在任务间传递不同数据类型的消息时,那么就可以使用队列集。

作用:用于对多个队列或信号量进行“监听”,其中不管哪一个消息到来,都可让任务退出阻塞状态

相关API

函数描述
xQueueCreateSet()创建队列集
xQueueAddToSet()队列添加到队列集中
xQueueRemoveFromSet()从队列集中移除队列
xQueueSelectFromSet()获取队列集中有有效消息的队列
xQueueSelectFromSetFromISR()在中断中获取队列集中有有效消息的队列
//uxEventQueueLength  队列集可容纳的队列数量
//返回值 NULL创建失败,其他值创建成功返回句柄
QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength )

//队列在被添加到队列集之前,队列中不能有有效的消息
//xQueueOrSemaphore待添加的队列句柄  xQueueSet目标队列集
//返回值 pdPASS 队列添加成功  pdFAIL队列添加失败
BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore,
                           QueueSetHandle_t xQueueSet )

//队列在从队列集移除之前,必须没有有效的消息
//xQueueOrSemaphore 待移除的队列句柄,xQueueSet  队列集
//返回值 pdPASS 队列移除成功  pdFAIL队列移除失败
BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,
                                QueueSetHandle_t xQueueSet )

//xQueueSet 队列集 xTicksToWait  阻塞超时时间
//返回值 NULL 获取消息失败 ,其他值 获取到消息的队列句柄
QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
                                            TickType_t const xTicksToWait )

使用流程

  1. 启用队列集功能需要将宏configUSE_QUEUE_SETS置为1
  2. 创建队列集
  3. 创建队列或信号量
  4. 往队列集中添加队列或信号量
  5. 往队列发生信息或释放信号量
  6. 获取队列集的消息

代码示例

#include "queue.h"
#include "semphr.h"

QueueSetHandle_t queueset_handle;
QueueHandle_t queue_handle;
QueueHandle_t semphr_handle;

void init(){
	queueset_handle = xQueueCreateSet(2);  //创建队列集
	queue_handle = xQueueCreate(1,sizeof(uint8_t)); //创建队列
	semphr_handle = xSemaphoreCreateBinary(); //创建信号量

	xQueueAddToSet(queue_handle,queueset_handle); //队列添加到队列集
	xQueueAddToSet(semphr_handle,queueset_handle); //信号量添加到队列集
}

void task1(){
	uint8_t key = 0;
	while(1){
		key = key_scan();
		if(key == KEY0_PRES){
			 xQueueSend(queue_handle,&key,portMAX_DELAY); //向队列中添加数据
		}else if(key == KEY1_PRES){
			 xSemaphoreGive(semphr_handle); //释放信号量
		}
	}
}

void task2(){
	QueueSetMemberHandle_t member_handle;
	uint8_t key;
	while(1){
		member_handle = xQueueSelectFromSet( queueset_handle, portMAX_DELAY);
		if(member_handle == queue_handle){
			xQueueReceive(member_handle,&key,portMAX_DELAY); //从队列头部读取消息
		} else if(member_handle == semphr_handle){
			xSemaphoreTake(member_handle,portMAX_DELAY); //获取信号量
		}
	}
}

更多推荐