freertos 源码分析二 list链表源码

list.c

一、链表初始化

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 ) );
    }   
    #endif
    pxList->uxNumberOfItems = ( UBaseType_t ) 0U; 
    listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
    listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
}

分解

pxList->pxIndex 指向结构中的xListEnd结构体

c 复制代码
pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd );

校验

c 复制代码
#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

c 复制代码
#if ( configUSE_16_BIT_TICKS == 1 ) 
    #define pdINTEGRITY_CHECK_VALUE    0x5a5a
#else
    #define pdINTEGRITY_CHECK_VALUE    0x5a5a5a5aUL
#endif  

portMAX_DELAY数值

c 复制代码
#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 

往下

c 复制代码
   pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );
   pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );

链表结构中xListEnd结构体的前后表项指针匀指向xListEnd

c 复制代码
pxList->uxNumberOfItems = ( UBaseType_t ) 0U; 

表项个数设为零

二、表项初始化

c 复制代码
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 );
}

三、表尾插入表项

c 复制代码
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结构体,初次插入表项时,连同链表内表项一同插入链表。

c 复制代码
 ListItem_t * const pxIndex = pxList->pxIndex;

检测校验

c 复制代码
#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,代码覆盖路径测试 展开为空 检测用

c 复制代码
#ifndef mtCOVERAGE_TEST_DELAY
    #define mtCOVERAGE_TEST_DELAY()
#endif       

指针操作,表项插入在当前链表表项索引之前。

c 复制代码
pxNewListItem->pxNext = pxIndex;                                                                                                               
pxNewListItem->pxPrevious = pxIndex->pxPrevious;
pxIndex->pxPrevious->pxNext = pxNewListItem;                                                                                                   
pxIndex->pxPrevious = pxNewListItem;

设链表为当前表项Container,并增加表项数目。

c 复制代码
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 <= xValueOfInsertion; pxIterator = pxIterator-    >pxNext )
        {
        }
    }
    pxNewListItem->pxNext = pxIterator->pxNext;
    pxNewListItem->pxNext->pxPrevious = pxNewListItem;
    pxNewListItem->pxPrevious = pxIterator;
    pxIterator->pxNext = pxNewListItem;
    pxNewListItem->pxContainer = pxList;
    ( pxList->uxNumberOfItems )++;
}

五、删除表项

c 复制代码
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指针为当前拥有者链表。

c 复制代码
List_t * const pxList = pxItemToRemove->pxContainer;

若移除表项为当前索引,当前索引前移。

c 复制代码
if( pxList->pxIndex == pxItemToRemove )
{
    pxList->pxIndex = pxItemToRemove->pxPrevious;
}

代码覆盖路径测试 检测用

c 复制代码
 mtCOVERAGE_TEST_MARKER();

表项数目减一,返回表项数目。

c 复制代码
( pxList->uxNumberOfItems )--;
return pxList->uxNumberOfItems;
相关推荐
drebander21 分钟前
使用 Java Stream 优雅实现List 转化为Map<key,Map<key,value>>
java·python·list
_whitepure5 小时前
常用数据结构详解
java·链表····队列·稀疏数组
系统之家装机大师8 小时前
Win11 22H2/23H2系统11月可选更新KB5046732发布!
windows·电脑
系统之家装机大师8 小时前
微软发布Win11 24H2系统11月可选更新KB5046740!
windows·电脑
熬夜学编程的小王8 小时前
【C++篇】深度解析 C++ List 容器:底层设计与实现揭秘
开发语言·数据结构·c++·stl·list
戎梓漩10 小时前
windows下安装curl,并集成到visual studio
ide·windows·visual studio
Lenyiin10 小时前
02.06、回文链表
数据结构·leetcode·链表
爱摸鱼的孔乙己10 小时前
【数据结构】链表(leetcode)
c语言·数据结构·c++·链表·csdn
蓝田~12 小时前
观察者模式和订阅模式
windows·观察者模式
努力进修14 小时前
“探索Java List的无限可能:从基础到高级应用“
java·开发语言·list