原创 FreeRTOS队列结构与创建

2009-6-20 10:51 2682 4 4 分类: MCU/ 嵌入式

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;

}


相关网址:http://www.openrtos.cn/article/9.php
PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
4
关闭 站长推荐上一条 /3 下一条