SIEMENS河北省承德市 西门子代理商——西门子华北一级总代理
xQueueGenericReset()函数中会调用vListInitialise()函数构建列表结构:
输入参数:
xQueue:消息队列控制块(内存中分配的消息队列的地址)
xNewQueue:是否为新的队列
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;}
这里先来看一下列表结构体的定义:
/* 列表结束值是列表中可能的最高值,以确保它保持在列表的末尾. */ 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 );
展开全文
相关产品