队列集使用在系统需要支持多个输入设备的情况,这是每个输入设备的数据都存放在一个队列中,队列集将他们管理起来,可以实现实时识别哪一个队列中有数据并将数据读取出来。
即:当想要及时得到多个队列的数据时,会使用队列集。
相关配置
使用队列集的函数,需要先开启宏开关。具体操作如下:
创建队列集
函数声明如下:
QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength )
uxEventQueueLength :队列集长度,该值等于所存队列的长度之和
QueueSetHandle_t :队列集句柄
队列与队列集建立联系
队列要先与队列集建立联系,这时队列集中并没有队列的句柄。
函数声明如下:
BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore,
QueueSetHandle_t xQueueSet )
xQueueOrSemaphore:队列句柄
xQueueSet :队列集句柄
读队列集
函数声明如下:
QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
TickType_t const xTicksToWait )
返回值:有数据的队列句柄
xQueueSet:队列集句柄
xTicksToWait :超时时间,portMAX_DELAY为死等
验证实验
实验内容为:创建三个任务,其中两个任务分别向自己的队列中写数据,任务三对队列集进行读取,并打印读到的数据。编写步骤如下:
- 创建任务1、任务2所用的队列
- 创建队列集
- 将队列与队列集建立联系
- 编写任务处理函数:任务1,任务2不断写队列,任务3读队列集
具体代码如下:
void Task1Function(void *param){
int i=1;
while(1){
xQueueSend((QueueHandle_t)param,&i,portMAX_DELAY);/* 写队列 */
i++;
vTaskDelay(10);
}
}
void Task2Function(void *param){
int i=-1;
while(1){
xQueueSend((QueueHandle_t)param,&i,portMAX_DELAY);/* 写队列 */
i--;
vTaskDelay(10);
}
}
void Task3Function(void *param){
QueueSetMemberHandle_t handle;
int i;
while(1){
/* 读队列集,返回有数据的队列句柄 */
handle = xQueueSelectFromSet((QueueSetHandle_t)param,portMAX_DELAY);
/* 读队列,获取数据 */
xQueueReceive(handle,&i,0);
printf("%d ",i);
}
}
int main( void )
{
TaskHandle_t xHandleTask1;
TaskHandle_t xHandleTask2;
TaskHandle_t xHandleTask3;
QueueHandle_t QueueHandle_Test1; /* 队列句柄,这是个指针 */
QueueHandle_t QueueHandle_Test2; /* 队列句柄,这是个指针 */
QueueSetHandle_t QueueSetHandle_Test; /* 队列集句柄,这是个指针 */
struct test tParam;
prvSetupHardware();
SerialPortInit();
printf("UART TEST\r\n");
/* 1.创建队列 */
QueueHandle_Test1 = xQueueCreate(2,sizeof(int));/* 创建队列1 */
if(QueueHandle_Test1 == NULL){
printf("queue create fail\r\n");
}
QueueHandle_Test2 = xQueueCreate(2,sizeof(int));/* 创建队列2 */
if(QueueHandle_Test2 == NULL){
printf("queue create fail\r\n");
}
/* 2.创建队列集 */
/* 队列1和队列2的长度都为2,所以队列集的长度=2+2=4 */
QueueSetHandle_Test = xQueueCreateSet(4);
/* 3.队列与队列集建立链接 */
xQueueAddToSet(QueueHandle_Test1,QueueSetHandle_Test);
xQueueAddToSet(QueueHandle_Test2,QueueSetHandle_Test);
/* 4.创建任务 */
xTaskCreate(Task1Function,"Task1",100,(void*)QueueHandle_Test1,2,&xHandleTask1);
xTaskCreate(Task2Function,"Task2",100,(void*)QueueHandle_Test2,1,&xHandleTask2);
xTaskCreate(Task3Function,"Task3",100,(void*)QueueSetHandle_Test,1,&xHandleTask3);
vTaskStartScheduler();
return 0;
}
运行结果如下:
可以看到任务3已经读到了来自任务1、任务2写入队列1、队列2的数据。