一、基本介绍
队列固然可以在任务和任务之间进行消息的传递,但是一个队列只能传递一种类型的数据结构,就好比数组只能存储一种类型的数据一样,为了任务可以接收不同数据类型的数据,于是就有了队列集。
队列集就是队列的集合,因为信号量的本质也是队列,因此队列集中可以有多个队列或信号量,并且每个队列存储的数据类型可以是不同的。
队列集的创建与队列的创建一致。
二、函数介绍
1.xQueueCreateSet()介绍
QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength )
{
QueueSetHandle_t pxQueue;
pxQueue = xQueueGenericCreate( uxEventQueueLength, ( UBaseType_t ) sizeof( Queue_t * ), queueQUEUE_TYPE_SET );
return pxQueue;
}
uxEventQueueLength该参数官方解释为----队列集存储集合中包含的队列和信号量上发生的事件。 uxEventQueueLength指定一次可以排队的最大事件数。要绝对确定事件不会丢失,必须将uxEventQueueLength 设置为 添加到集合中的队列长度之和,其中二进制信号量和互斥体长度为1,计数信号量的长度由其最大计数值设置。理解,队列集中所有的队列或信号量长度之和。
2.xQueueAddToSet()
BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore,
QueueSetHandle_t xQueueSet )
{
BaseType_t xReturn;
taskENTER_CRITICAL();
{
if( ( ( Queue_t * ) xQueueOrSemaphore )->pxQueueSetContainer != NULL )
{
/* Cannot add a queue/semaphore to more than one queue set. */
xReturn = pdFAIL;
}
else if( ( ( Queue_t * ) xQueueOrSemaphore )->uxMessagesWaiting != ( UBaseType_t ) 0 )
{
/* Cannot add a queue/semaphore to a queue set if there are already
* items in the queue/semaphore. */
xReturn = pdFAIL;
}
else
{
( ( Queue_t * ) xQueueOrSemaphore )->pxQueueSetContainer = xQueueSet;
xReturn = pdPASS;
}
}
taskEXIT_CRITICAL();
return xReturn;
}
将队列加入到队列集中,注意,加入的队列或信号量必须不存在在其他的队列集中,也不能有有效数据。我觉得这只是表面的加入,真正的加入在于队列集中的队列/信号量的入队/释放。
3.xQueueSelectFromSet()
QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
TickType_t const xTicksToWait )
{
QueueSetMemberHandle_t xReturn = NULL;
( void ) xQueueReceive( ( QueueHandle_t ) xQueueSet, &xReturn, xTicksToWait ); /*lint !e961 Casting from one typedef to another is not redundant. */
return xReturn;
}
获取可用的队列或信号量的句柄。
三、问题与总结
1.当队列集中的队列/信号量的入队/释放时,才会将该队列/信号量添加到队列集中,而不是简单地如xQueueAddToSet()中指明该队列/信号量所属的队列集,当然这个函数xQueueAddToSet()的使用时必不可少的。
2.加入队列集的队列/信号量首先不存在于另一个队列集,也不存在有效数据,才可以加入到一个队列集中。
3.队列集的本质上其实也是一个队列,只不过存储的数据类型是队列。
4.使用队列集时请注意将FreeRTOSConfig.h中的configUSE_QUEUE_SETS置1.