list.c
一、链表初始化
void vListInitialise( List_t * const pxList ){pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) );pxList->xListEnd.xItemValue = portMAX_DELAY;pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );#if ( configUSE_MINI_LIST_ITEM == 0 ) { pxList->xListEnd.pvOwner = NULL;pxList->xListEnd.pxContainer = NULL;listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) );} #endifpxList->uxNumberOfItems = ( UBaseType_t ) 0U; listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );}
分解
pxList->pxIndex 指向结构中的xListEnd结构体
pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd );
校验
#if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 )#define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )#define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )#define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList )#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList )#else#define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE#define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE#define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList )( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList )( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE#endif
验验数值 5a
#if ( configUSE_16_BIT_TICKS == 1 ) #define pdINTEGRITY_CHECK_VALUE0x5a5a#else#define pdINTEGRITY_CHECK_VALUE0x5a5a5a5aUL#endif
portMAX_DELAY数值
#if( configUSE_16_BIT_TICKS == 1 )typedef uint16_t TickType_t;#define portMAX_DELAY ( TickType_t ) 0xffff#else typedef uint32_t TickType_t;#define portMAX_DELAY ( TickType_t ) 0xffffffffUL#endif
往下
pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );
链表结构中xListEnd结构体的前后表项指针匀指向xListEnd
pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
表项个数设为零
二、表项初始化
void vListInitialiseItem( ListItem_t * const pxItem ){pxItem->pxContainer = NULL;listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );}
三、表尾插入表项
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ){ListItem_t * const pxIndex = pxList->pxIndex;listTEST_LIST_INTEGRITY( pxList );listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );pxNewListItem->pxNext = pxIndex;pxNewListItem->pxPrevious = pxIndex->pxPrevious;mtCOVERAGE_TEST_DELAY();pxIndex->pxPrevious->pxNext = pxNewListItem;pxIndex->pxPrevious = pxNewListItem;pxNewListItem->pxContainer = pxList;( pxList->uxNumberOfItems )++;}
由于初始化时,索引指向了链表内xListEnd结构体,初次插入表项时,连同链表内表项一同插入链表。
ListItem_t * const pxIndex = pxList->pxIndex;
检测校验
#if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList )#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList )#define listTEST_LIST_ITEM_INTEGRITY( pxItem )#define listTEST_LIST_INTEGRITY( pxList )#else#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList )\( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE#define listTEST_LIST_ITEM_INTEGRITY( pxItem )\configASSERT( ( ( pxItem )->xListItemIntegrityValue1 ==pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) #define listTEST_LIST_INTEGRITY( pxList ) \configASSERT( ( ( pxList )->xListIntegrityValue1 ==pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) #endif
mtCOVERAGE_TEST_DELAY,代码覆盖路径测试 展开为空 检测用
#ifndef mtCOVERAGE_TEST_DELAY#define mtCOVERAGE_TEST_DELAY()#endif
指针操作,表项插入在当前链表表项索引之前。
pxNewListItem->pxNext = pxIndex; pxNewListItem->pxPrevious = pxIndex->pxPrevious;pxIndex->pxPrevious->pxNext = pxNewListItem; pxIndex->pxPrevious = pxNewListItem;
设链表为当前表项Container,并增加表项数目。
pxNewListItem->pxContainer = pxList;( pxList->uxNumberOfItems )++;
四、插入表项
依据表项的xItemValue数值,插入表项,若数值相等插入相等值之后。
void vListInsert( List_t * const pxList,ListItem_t * const pxNewListItem ){ ListItem_t * pxIterator;const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;listTEST_LIST_INTEGRITY( pxList );listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );if( xValueOfInsertion == portMAX_DELAY ){pxIterator = pxList->xListEnd.pxPrevious;}else{for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue pxNext ){}}pxNewListItem->pxNext = pxIterator->pxNext;pxNewListItem->pxNext->pxPrevious = pxNewListItem;pxNewListItem->pxPrevious = pxIterator;pxIterator->pxNext = pxNewListItem;pxNewListItem->pxContainer = pxList;( pxList->uxNumberOfItems )++;}
五、删除表项
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ){List_t * const pxList = pxItemToRemove->pxContainer;pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;mtCOVERAGE_TEST_DELAY();if( pxList->pxIndex == pxItemToRemove ){pxList->pxIndex = pxItemToRemove->pxPrevious;}else{mtCOVERAGE_TEST_MARKER();}pxItemToRemove->pxContainer = NULL;( pxList->uxNumberOfItems )--;return pxList->uxNumberOfItems;}
分解
表项pxContainer指针为当前拥有者链表。
List_t * const pxList = pxItemToRemove->pxContainer;
若移除表项为当前索引,当前索引前移。
if( pxList->pxIndex == pxItemToRemove ){pxList->pxIndex = pxItemToRemove->pxPrevious;}
代码覆盖路径测试 检测用
mtCOVERAGE_TEST_MARKER();
表项数目减一,返回表项数目。
( pxList->uxNumberOfItems )--;return pxList->uxNumberOfItems;