结构体定义

/*链表结构体*/
typedef struct xLIST
{
listFIRST_LIST_INTEGRITY_CHECK_VALUE /*用于链表完整性检查*/
configLIST_VOLATILE UBaseType_t uxNumberOfItems; /*记录链表项数目*/
ListItem_t * configLIST_VOLATILE pxIndex; /*用于遍历链表,初始化会指向最后的链表项,这里需要注意使用了volatile关键字,表明该指针可能会在其他地方修改*/
MiniListItem_t xListEnd;/*用于标记链表尾*/
listSECOND_LIST_INTEGRITY_CHECK_VALUE /*用于链表完整性检查*/
} List_t;
/*链表项结构体*/
struct xLIST_ITEM
{
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*用于链表完整性检查*/
configLIST_VOLATILE TickType_t xItemValue;/*链表项值:大部分时候根据此值升序排列*/
struct xLIST_ITEM * configLIST_VOLATILE pxNext;/*指向下一个节点*/
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;/*指向上一个节点*/
void * pvOwner; /*指向结构体控制块*/
void * configLIST_VOLATILE pvContainer;/*指向该链表项对应的链表*/
listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*用于链表完整性检查*/
};
/*迷你链表项结构体*/
struct xMINI_LIST_ITEM
{
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE
configLIST_VOLATILE TickType_t xItemValue;
struct xLIST_ITEM * configLIST_VOLATILE pxNext;
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
};

根据定义可以看出以下几点:

  1. 链表结构是一个双向链表。
  2. 每个链表都由链表和链表项组成。
  3. 链表结构体本身有一个迷你链表项,用来标记链表的结尾。

链表和链表项初始化

/*链表初始化*/
void vListInitialise( List_t * const pxList )
{
/*将链表的Index索引指针指向自身的迷你链表项,即链表结尾*/
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;
/*初始化链表的完整性检查值*/
listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
}
/*链表项初始化*/
void vListInitialiseItem( ListItem_t * const pxItem )
{
/*确保该链表项没有被链表使用,往往初始化链表项之后就会进行插入或设置操作*/
pxItem->pvContainer = NULL;
/*初始化完整性检查*/
listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
}

链表的操作

链表的插入会根据List Item Value进行升序排列,其他并没有什么特殊的地方。初始化并插入两个节点后大概的数据结构,如下图所示:

从图中可以看出,List初始化并添加节点后,List Item 1/List Item 2 和 List自己的xListEnd节点一起组成了一个双向循环的链表。

Q&A

1).如何完成链表的完整性检查?

如果打开了完整性检查的开关(configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES),每个链表和链表项结构都会定义listFIRST_LIST_INTEGRITY_CHECK_VALUElistSECOND_LIST_INTEGRITY_CHECK_VALUE(mini链表项没有定义这个),该定义是一个16位或32位的整形数,在链表或链表项初始化的时候会将该变量初始化为0x5a5a或0x5a5a5a5a,在检查的时候如果这两个变量都没有改变则通过完整性检查,否则认为链表被破坏。

2).如何使用List?

  1. 必须先定义一个List_t的全局变量,比如Timer中的 xActiveTimerList1
  2. 每一个节点结构体必须包含xLIST_ITEM类型的成员。
  3. 初始化链表后,将含有List Item成员的数据结构按照链表项值的大小插入到链表中,比如Timer中利用该值溢出的判断。
  4. 设置好pvOwner指针,后续可以根据该指针反向找到该节点的具体结构,如Timer_t。

FreeRTOS数据结构(一)--链表和链表项的更多相关文章

  1. js数据结构与算法--单链表的实现与应用思考

    链表是动态的数据结构,它的每个元素由一个存储元素本身的节点和一个指向下一个元素的引用(也称指针或链接)组成. 现实中,有一些链表的例子. 第一个就是寻宝的游戏.你有一条线索,这条线索是指向寻找下一条线 ...

  2. JavaScript 数据结构与算法3(链表)

    学习数据结构的 git 代码地址: https://gitee.com/zhangning187/js-data-structure-study 1.链表 本章学习如何实现和使用链表这种动态的数据结构 ...

  3. 数据结构——基于java的链表实现(真正理解链表这种数据结构)

    原创不易,如需转载,请注明出处https://www.cnblogs.com/baixianlong/p/10759599.html,否则将追究法律责任!!! 一.链表介绍 1.什么是链表? 链表是一 ...

  4. 自己动手实现java数据结构(二) 链表

    1.链表介绍 前面我们已经介绍了向量,向量是基于数组进行数据存储的线性表.今天,要介绍的是线性表的另一种实现方式---链表. 链表和向量都是线性表,从使用者的角度上依然被视为一个线性的列表结构.但是, ...

  5. php数据结构课程---2、链表(php中 是如何实现单链表的(也就是php中如何实现对象引用的))

    php数据结构课程---2.链表(php中 是如何实现单链表的(也就是php中如何实现对象引用的)) 一.总结 一句话总结: php是弱类型语言,变量即可表示数值,也可表示对象:链表节点的数据域的值就 ...

  6. C# 数据结构 - 单链表 双链表 环形链表

    链表特点(单链表 双链表) 优点:插入和删除非常快.因为单链表只需要修改Next指向的节点,双链表只需要指向Next和Prev的节点就可以完成插入和删除操作. 缺点:当需要查找某一个节点的时候就需要一 ...

  7. jdk1.8HashMap底层数据结构:散列表+链表+红黑树,jdk1.8HashMap数据结构图解+源码说明

    一.前言 本文由jdk1.8源码整理而得,附自制jdk1.8底层数据结构图,并截取部分源码加以说明结构关系. 二.jdk1.8 HashMap底层数据结构图 三.源码 1.散列表(Hash table ...

  8. 数据结构:DHUOJ 删除链表的顺数及倒数第N个节点

    删除链表的顺数及倒数第N个节点 作者: turbo时间限制: 1S章节: DS:数组和链表 题目描述: 可使用以下代码,完成其中的removeNth函数,其中形参head指向无头结点单链表,n为要删除 ...

  9. 数据结构与算法之PHP实现链表类(单链表/双链表/循环链表)

    链表是由一组节点组成的集合.每个节点都使用一个对象的引用指向它的后继.指向另一个节点的引用叫做链表. 链表分为单链表.双链表.循环链表.   一.单链表 插入:链表中插入一个节点的效率很高.向链表中插 ...

随机推荐

  1. ActiveMQ系列之五:ActiveMQ的Transport

    连接到ActiveMQ Connector:ActiveMQ提供的,用来实现连接通讯的功能.包括:client-to-broker.broker-to-broker. ActiveMQ允许客户端使用多 ...

  2. android-async-http框架源码分析

    async-http使用地址 android-async-http仓库:git clone https://github.com/loopj/android-async-http 源码分析 我们在做网 ...

  3. HBase事务

    众所周知,ACID是指原子性(Atomicity),一致性(Consistency),隔离性(Isolation)和持久性(Durability). HBase对同一行数据的操作提供ACID保证.HB ...

  4. SharePoint 2007 文档库中的文档添加评论功能

    背景:接到一个项目,要求文档管理,当然文档库就可以了,但是要求文档需要大家去读,读完以后还可以发表评论,这Moss貌似就有点困难了.和同事一起合计,想来想去也没有太好的办法,后来想到传统开发,两个表的 ...

  5. access treeview读取数据表成树并与子窗体联动

    Private Sub Form_Load()Dim i As IntegerDim rst As DAO.RecordsetSet rst = CurrentDb.OpenRecordset(&qu ...

  6. tomcat启动非常慢;连接oracle数据库失败,jdbc错误日志提示connection reset;测试主机间网络互通及数据库端口都正常

      [判断确认:这时候大家可能要去检查一下/dev/random 这个设备档案.可以用cat /dev/random 来看它的内容,如果你发现他一直没显示任何内容﹝可能是乱码数字之类的﹞,那就是它出问 ...

  7. Pydev Console中文提示乱码的问题

    1. 像这样的规则内容请这样处理"\u305d\u3093\u306a\u306b"style unicode string : print str.decode("un ...

  8. Android Studio集成Lombok Plugin

    Lombok是Android Studio名列前茅的插件,有啥用,看这个:http://www.blogjava.NET/fancydeepin/archive/2012/07/12/lombok.h ...

  9. 任务调度利器:Celery

    http://www.liaoxuefeng.com/article/00137760323922531a8582c08814fb09e9930cede45e3cc000 Celery是Python开 ...

  10. eclipse配置tomcat后启动报内存错误解决方法

    一.双击tomcat服务,打开配置界面 二.打开launch configuration窗口,在Argument最后面加入:-Xms256m -Xmx512m -XX:PermSize=256M -X ...