当前位置: 首页 > news >正文

freertos 源码分析二 list链表源码

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_VALUE    0x5a5a
#else#define pdINTEGRITY_CHECK_VALUE    0x5a5a5a5aUL
#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 <= xValueOfInsertion; pxIterator = pxIterator-    >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;
http://www.lryc.cn/news/293210.html

相关文章:

  • Peter算法小课堂—Dijkstra最短路算法
  • Python 读取和写入包含中文的csv、xlsx、json文件
  • 【算法】利用递归dfs解决二叉树算法题(C++)
  • 计算机网络_1.6.1 常见的三种计算机网络体系结构
  • XML传参方式
  • Pyecharts炫酷散点图构建指南【第50篇—python:炫酷散点图】
  • 关于爬取所有哔哩哔哩、任意图片、所有音乐、的python脚本语言-Edge浏览器插件 全是干货!
  • 压力测试工具-Jmeter使用总结
  • [cmake]CMake Error: Could not create named generator Visual Studio 16 2019解决方法
  • 2024美赛数学建模D题思路分析 - 大湖区水资源问题
  • 2024 高级前端面试题之 HTTP模块 「精选篇」
  • 【Linux C | 网络编程】netstat 命令图文详解 | 查看网络连接、查看路由表、查看统计数据
  • Python爬虫存储库安装
  • 用函数求最小公倍数和最大公约数(c++题解)
  • 鲜花销售|鲜花销售小程序|基于微信小程序的鲜花销售系统设计与实现(源码+数据库+文档)
  • 三.Linux权限管控 1-5.Linux的root用户用户和用户组查看权限控制信息chmod命令chown命令
  • Jmeter学习系列之四:测试计划元素介绍
  • LeetCode.1686. 石子游戏 VI
  • 【硬件产品经理】锂电池充电时间怎么计算?
  • Oracle篇—普通表迁移到分区表(第五篇,总共五篇)
  • 作为开发人的我们,怎么可以不了解这些?
  • 基于 Echarts 的 Python 图表库:Pyecahrts交互式的日历图和3D柱状图
  • web应用课——(第四讲:中期项目——拳皇)
  • Python爬虫http基本原理
  • iOS17使用safari调试wkwebview
  • 二叉树(1)
  • ArcGIS Pro字段编号相关代码
  • AJAX-URL查询参数
  • DBeaver连接ClickHouse,时间少了8小时
  • week03day03(文件操作、正则表达式1)