广东湘恒智能科技有限公司
主营产品: 西门子PLC代理商,plc变频器,伺服电机,人机界面,触摸屏,线缆,DP接头
SIEMENS河北省承德市 西门子代理商——西门子华北一级总代理


xQueueGenericReset()函数中会调用vListInitialise()函数构建列表结构:


输入参数:

xQueue:消息队列控制块(内存中分配的消息队列的地址)

xNewQueue:是否为新的队列









































BaseType_t xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ){Queue_t * const pxQueue = ( Queue_t * ) xQueue; /* 将内存地址转为消息队列控制块结构体类型,并赋值给局部变量pxQueue */
   configASSERT( pxQueue );    taskENTER_CRITICAL(); /* 进入临界区 */    {        /* 队列尾地址 = 头地址 + 队列长度*单个消息的大小 */        pxQueue->pcTail = pxQueue->pcHead + ( pxQueue->uxLength * pxQueue->uxItemSize );        /* 当前消息队列的消息个数初始化为0 */        pxQueue->uxMessagesWaiting = ( UBaseType_t ) 0U;        /* 可写入消息的位置,初始为pcHead这个位置 */        pxQueue->pcWriteTo = pxQueue->pcHead;        /* 可读取消息的位置,初始为消息队列的队尾位置? */        pxQueue->u.pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - ( UBaseType_t ) 1U ) * pxQueue->uxItemSize );        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 /* 是新的队列,则构建消息队列结构 */        {            vListInitialise( &( pxQueue->xTasksWaitingToSend ) );            vListInitialise( &( pxQueue->xTasksWaitingToReceive ) );        }    }    taskEXIT_CRITICAL(); /* 退出临界区 */    return pdPASS;}


2.5 构建列表结构

这里先来看一下列表结构体的定义:































typedef struct xLIST{    listFIRST_LIST_INTEGRITY_CHECK_VALUE    /*configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES是否被设置为1 */    configLIST_VOLATILE UBaseType_t uxNumberOfItems; /* 链表节点计数器 */    ListItem_t * configLIST_VOLATILE pxIndex;        /* 链表节点索引指针 */    MiniListItem_t xListEnd;                        /* 链表最后一个节点 */    listSECOND_LIST_INTEGRITY_CHECK_VALUE  /*configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES是否被设置为1 */    } List_t;再来看vListInitialise这个函数:输入参数:pxList:发送或接收消息的阻塞列表的结构体void vListInitialise( List_t * const pxList ){    /* 列表结构包含一个用于标记列表结束的列表项。要初始化列表,将列表末尾作为唯一的列表条目插入。*/    pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd );          
   /* 列表结束值是列表中可能的最高值,以确保它保持在列表的末尾. */    pxList->xListEnd.xItemValue = portMAX_DELAY;
   /* 链表的下一个和前一个指针都指向它自己,所以我们知道链表什么时候是空的 */    pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );      pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );
   pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
   /*如果configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES=1,将已知值写入列表 */    listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );    listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );


展开全文
相关产品
拨打电话 微信咨询 发送询价