新闻  |   论坛  |   博客  |   在线研讨会
FreeRTOS队列结构与创建
mayer | 2009-06-21 12:56:28    阅读:4611   发布文章

FreeRTOS队列结构与创建

 

FreeRTOS中信号量与互斥琐的底层都是通过队列来实现的,下面对队列的源码进行初步分析:

队列结构的定义如下:

typedef struct QueueDefinition
{
    signed portCHAR *pcHead;                /*队列 头部指针*/
    signed portCHAR *pcTail;                /*尾部指针,比长度多一个字节*/

    signed portCHAR *pcWriteTo;                /*指向下一个可以写入的空闲空间*/
    signed portCHAR *pcReadFrom;            /*指向队列中最后一个已读的数据 */

    xList xTasksWaitingToSend;                /*等待发送的任务队列,按优先级排序 */
    xList xTasksWaitingToReceive;            /*等待读取的任务队列,按优先级排序*/

    volatile unsigned portBASE_TYPE uxMessagesWaiting;   /*队列中当前的条目数*/
    unsigned portBASE_TYPE uxLength;        /*队列总的条目个数 */
    unsigned portBASE_TYPE uxItemSize;        /*每个条目的大小*/

    signed portBASE_TYPE xRxLock;            /*队列接收锁标志 */
    signed portBASE_TYPE xTxLock;            /*队列发送锁标志 */
     /*这两个标志的值可以为queueUNLOCKED (-1)、queueLOCKED_UNMODIFIED(0)、或正值,当为正直时表示锁的次数*/
} xQUEUE;

队列的创建

队列通过xQueueCreate函数来创建,此函数主要负责申请队列空间,初始化队列的各项的值。

xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize )
{
xQUEUE *pxNewQueue;
size_t xQueueSizeInBytes;

    /* 为队列分配空间*/
    if( uxQueueLength > ( unsigned portBASE_TYPE ) 0 )
    {
        pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) );
        if( pxNewQueue != NULL )
        {
            /* Create the list of pointers to queue items.  The queue is one byte
            longer than asked for to make wrap checking easier/faster. */
            xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1;    /*分配的空间比队列长度多一个字节,方便检测*/

            pxNewQueue->pcHead = ( signed portCHAR * ) pvPortMalloc( xQueueSizeInBytes );
            if( pxNewQueue->pcHead != NULL )
            {
                /* Initialise the queue members as described above where the
                queue type is defined. */
                pxNewQueue->pcTail = pxNewQueue->pcHead + ( uxQueueLength * uxItemSize );
                pxNewQueue->uxMessagesWaiting = 0;
                pxNewQueue->pcWriteTo = pxNewQueue->pcHead;
                pxNewQueue->pcReadFrom = pxNewQueue->pcHead + ( ( uxQueueLength - 1 ) * uxItemSize );    /*指向的是最后一个已读的条目,故初始化为最后一项*/
                pxNewQueue->uxLength = uxQueueLength;
                pxNewQueue->uxItemSize = uxItemSize;
                pxNewQueue->xRxLock = queueUNLOCKED;
                pxNewQueue->xTxLock = queueUNLOCKED;

                /* Likewise ensure the event queues start with the correct state. */
                vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) );      /*初始化两个等待队列*/
                vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );

                traceQUEUE_CREATE( pxNewQueue );    /*用于调试跟踪*/

                return  pxNewQueue;
            }
            else
            {
                traceQUEUE_CREATE_FAILED();
                vPortFree( pxNewQueue );
            }
        }
    }

    /* Will only reach here if we could not allocate enough memory or no memory
    was required. */
    return NULL;
}

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客
站长统计