队列集使用在系统需要支持多个输入设备的情况,这是每个输入设备的数据都存放在一个队列中,队列集将他们管理起来,可以实现实时识别哪一个队列中有数据并将数据读取出来。
相关配置
使用队列集的函数,需要先开启宏开关。具体操作如下:
创建队列集
函数声明如下:
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的数据。