举例子说明:队列集的使用
队列集:Queue Set
多个队列的集合,一个队列中依次存放多个队列的句柄
一般使用API的流程如下:
1.创建几个队列
2.创建队列集
3.把这几个队列添加进队列集中
然后可以创建任务去使用队列和队列集
static QueueHandle_t xQueueHandle1; /* 队列1的句柄 */
static QueueHandle_t xQueueHandle2; /* 队列2的句柄 */
static QueueSetHandle_t xQueueSet; /* 队列集的句柄 */
/* 使用API创建队列集的过程 */
void UseQueueSetStep(void)
{
/* Step1. 创建2个queue ------------------------*/
xQueueHandle1 = xQueueCreate(2, sizeof(int));
if (xQueueHandle1 == NULL)
{
printf("can not create queue 1 \r\n");
}
xQueueHandle2 = xQueueCreate(2, sizeof(int));
if (xQueueHandle2 == NULL)
{
printf("can not create queue 2 \r\n");
}
/* Step2. 创建queue set ----------------------*/
xQueueSet = xQueueCreateSet(4);
/* 注意:这里队列集合的长度为什么是4?
当前队列集要监测2个队列A,B;
队列集的长度是:队列A的长度+队列B的长度
所以这里的长度应该是2+2=4 */
/* Step3. 把2个queue添加进queue set -----------*/
xQueueAddToSet(xQueueHandle1, xQueueSet);
xQueueAddToSet(xQueueHandle2, xQueueSet);
}
/* Task1:往队列里写一个int类型的值,且这个值伴随Task1的每次执行从0开始自增 */
void Task1Function(void * param)
{
int i = 0;
while (1)
{
xQueueSend(xQueueHandle1, &i, portMAX_DELAY);
i++;
vTaskDelay(10);
}
}
/* Task2:往队列里写一个int类型的值,且这个值伴随Task1的每次执行从-1开始自减 */
void Task2Function(void * param)
{
int i = -1;
while (1)
{
xQueueSend(xQueueHandle2, &i, portMAX_DELAY);
i--;
vTaskDelay(20);
}
}
/* Task3:使用队列集监测Queue1和Queue2哪个队列有数据,就将该队列中的数据打印出来 */
void Task3Function(void * param)
{
QueueSetMemberHandle_t handle;
int i;
while (1)
{
/* Step1:读取 加入队列集中的所有队列里 哪个队列有数据,
返回该队列的句柄 等待时长为最大时长 */
handle = xQueueSelectFromSet(xQueueSet, portMAX_DELAY);
/* Step2:读队列 由于Step1已经知道哪个队列有数据了,
因此,这里就是正常的读队列操作,只是超时时间可以直接设置为0,
因为能执行到这里,说明该队列里肯定是有数据的,无须等待,因此写0. */
xQueueReceive(handle, &i, 0);
/* Step3:打印数据 */
printf("get data : %d\r\n", i);
}
}
int main( void )
{
prvSetupHardware();
UseQueueSetStep();
/* 创建3个任务,来体验队列和队列集的使用 */
xTaskCreate(Task1Function, "Task1", 100, NULL, 1, NULL);
xTaskCreate(Task2Function, "Task2", 100, NULL, 1, NULL);
xTaskCreate(Task3Function, "Task3", 100, NULL, 1, NULL);
vTaskStartScheduler();
return 0;
}
从上述的代码中可以分析的是:
1.Task1、Task2、Task3三个任务的优先级均一致且优先级均大于0,因此任务调度器开启后,先执行的任务是Task3,
而后是Task1和Task2,后续的顺序将会因为Task1和Task2的延时不同有所调整.
2.那么可以猜想,Task3先执行,但是由于Task1与Task2均未执行,没有向队列中写入数据,那么Task3监测的队列集中
也不会有数据,因此Task3最开始第一次执行任务的时候是不会有数据打印的;
当Tick中断到来的时候,切换了Task1,Task1向Queue1中写入了值是0,然后自增,那么同时写队列这个操作也会将
Queue的句柄写入队列集中,那么后面再次执行到Task3的时候就会打印出来数据是0;
当Tick中断再次到来,切换为了Task2,Task2向Queue2中写入了值是-1,然后自减,那么同时写队列这个操作也会将
Queue的句柄写入队列集中,那么后面再次执行到Task3的时候就会打印出来数据是-1;
当Tick中断再次到来,切换为了Task3,这时候读队列集,发现有数据,依次读取,第一次读取是Queue1的0,打印0,然
后再次读取是Queue2的-1,打印-1.
Debug看一下串口打印的结果是否和理论推到一致,如下图: