头图

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;
}

step1nto
1 声望1 粉丝