xQueueCreate函数
xQueueCreate
其实是一个宏,调用了xQueueGenericCreate
函数。
xQueueGenericCreate
函数第三个参数区分创建的队列的几种类型:包括信号量,二进制信号量,互斥量等都是由队列变体得来。
在创建队列时,第三个参数固定使用 queueQUEUE_TYPE_BASE
。
#define xQueueCreate( uxQueueLength, uxItemSize ) \
xQueueGenericCreate(( uxQueueLength ), \
( uxItemSize ), \
( queueQUEUE_TYPE_BASE ) )
xQueueGenericCreate函数
QueueHandle_t xQueueGenericCreate(
const UBaseType_t uxQueueLength,
const UBaseType_t uxItemSize,
const uint8_t ucQueueType )
{
Queue_t * pxNewQueue = NULL;
size_t xQueueSizeInBytes;
uint8_t * pucQueueStorage;
// 需要检查参数是否合法?
// 条件1 队列长度 > 0
// 条件2 总字节数(队列长度x每个元素的大小)要在uint32_t能表示的最大数之内
if(
( uxQueueLength > ( UBaseType_t ) 0 ) &&
( ( SIZE_MAX / uxQueueLength ) >= uxItemSize ) &&
( ( SIZE_MAX - sizeof( Queue_t ) ) >= ( uxQueueLength * uxItemSize ) )
)
{
// 计算队列需要的字节数,
// 字节数 = 队列长度 * 每个元素的大小
xQueueSizeInBytes = (size_t)(uxQueueLength * uxItemSize);
// 申请一块内存
// 包括 队列结构体的大小 + 总存储字节数大小
pxNewQueue = ( Queue_t * ) \
pvPortMalloc(sizeof(Queue_t) + xQueueSizeInBytes);
if( pxNewQueue != NULL )
{
pucQueueStorage = ( uint8_t * ) pxNewQueue;
// 前面存储 Queue_t
// 后面存储 数据
pucQueueStorage += sizeof( Queue_t );
// 初始化Queue
prvInitialiseNewQueue( uxQueueLength,
uxItemSize,
pucQueueStorage,
ucQueueType,
pxNewQueue );
}
else
{
// 正常情况不会走到这里。
}
}
else
{
// 正常情况不会走到这里。
}
return pxNewQueue;
}
.
prvInitialiseNewQueue函数
static void prvInitialiseNewQueue(
const UBaseType_t uxQueueLength,
const UBaseType_t uxItemSize,
uint8_t * pucQueueStorage,
const uint8_t ucQueueType,
Queue_t * pxNewQueue )
{
// uxItemSize表示队列中每个元素占有的字节数,一般来说不会为0
if( uxItemSize == ( UBaseType_t ) 0 )
{
pxNewQueue->pcHead = ( int8_t * ) pxNewQueue;
}
else
{
pxNewQueue->pcHead = ( int8_t * ) pucQueueStorage;
}
pxNewQueue->uxLength = uxQueueLength;
pxNewQueue->uxItemSize = uxItemSize;
( void ) xQueueGenericReset( pxNewQueue, pdTRUE );
}
.
xQueueGenericReset函数
.
BaseType_t xQueueGenericReset( QueueHandle_t xQueue,
BaseType_t xNewQueue )
{
BaseType_t xReturn = pdPASS;
Queue_t * const pxQueue = xQueue;
configASSERT( pxQueue );
if( ( pxQueue != NULL ) &&
( pxQueue->uxLength >= 1U ) &&
( ( SIZE_MAX / pxQueue->uxLength ) >= \
pxQueue->uxItemSize ) )
{
taskENTER_CRITICAL();
{
pxQueue->u.xQueue.pcTail = pxQueue->pcHead + ( pxQueue->uxLength * pxQueue->uxItemSize );
pxQueue->uxMessagesWaiting = ( UBaseType_t ) 0U;
pxQueue->pcWriteTo = pxQueue->pcHead;
pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - 1U ) * pxQueue->uxItemSize ); /*lint !e9016 Pointer arithmetic allowed on char types, especially when it assists conveying intent. */
pxQueue->cRxLock = queueUNLOCKED;
pxQueue->cTxLock = queueUNLOCKED;
if( xNewQueue == pdFALSE )
{
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
{
queueYIELD_IF_USING_PREEMPTION();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
/* Ensure the event queues start in the correct state. */
vListInitialise( &( pxQueue->xTasksWaitingToSend ) );
vListInitialise( &( pxQueue->xTasksWaitingToReceive ) );
}
}
taskEXIT_CRITICAL();
}
else
{
xReturn = pdFAIL;
}
configASSERT( xReturn != pdFAIL );
/* A value is returned for calling semantic consistency with previous
* versions. */
return xReturn;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。