FreeRTOS数据结构(一)--链表和链表项
结构体定义
/*链表结构体*/
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;
};
根据定义可以看出以下几点:
- 链表结构是一个双向链表。
- 每个链表都由链表和链表项组成。
- 链表结构体本身有一个迷你链表项,用来标记链表的结尾。
链表和链表项初始化
/*链表初始化*/
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_VALUE和listSECOND_LIST_INTEGRITY_CHECK_VALUE(mini链表项没有定义这个),该定义是一个16位或32位的整形数,在链表或链表项初始化的时候会将该变量初始化为0x5a5a或0x5a5a5a5a,在检查的时候如果这两个变量都没有改变则通过完整性检查,否则认为链表被破坏。
2).如何使用List?
- 必须先定义一个List_t的全局变量,比如Timer中的 xActiveTimerList1
- 每一个节点结构体必须包含xLIST_ITEM类型的成员。
- 初始化链表后,将含有List Item成员的数据结构按照链表项值的大小插入到链表中,比如Timer中利用该值溢出的判断。
- 设置好pvOwner指针,后续可以根据该指针反向找到该节点的具体结构,如Timer_t。
FreeRTOS数据结构(一)--链表和链表项的更多相关文章
- js数据结构与算法--单链表的实现与应用思考
链表是动态的数据结构,它的每个元素由一个存储元素本身的节点和一个指向下一个元素的引用(也称指针或链接)组成. 现实中,有一些链表的例子. 第一个就是寻宝的游戏.你有一条线索,这条线索是指向寻找下一条线 ...
- JavaScript 数据结构与算法3(链表)
学习数据结构的 git 代码地址: https://gitee.com/zhangning187/js-data-structure-study 1.链表 本章学习如何实现和使用链表这种动态的数据结构 ...
- 数据结构——基于java的链表实现(真正理解链表这种数据结构)
原创不易,如需转载,请注明出处https://www.cnblogs.com/baixianlong/p/10759599.html,否则将追究法律责任!!! 一.链表介绍 1.什么是链表? 链表是一 ...
- 自己动手实现java数据结构(二) 链表
1.链表介绍 前面我们已经介绍了向量,向量是基于数组进行数据存储的线性表.今天,要介绍的是线性表的另一种实现方式---链表. 链表和向量都是线性表,从使用者的角度上依然被视为一个线性的列表结构.但是, ...
- php数据结构课程---2、链表(php中 是如何实现单链表的(也就是php中如何实现对象引用的))
php数据结构课程---2.链表(php中 是如何实现单链表的(也就是php中如何实现对象引用的)) 一.总结 一句话总结: php是弱类型语言,变量即可表示数值,也可表示对象:链表节点的数据域的值就 ...
- C# 数据结构 - 单链表 双链表 环形链表
链表特点(单链表 双链表) 优点:插入和删除非常快.因为单链表只需要修改Next指向的节点,双链表只需要指向Next和Prev的节点就可以完成插入和删除操作. 缺点:当需要查找某一个节点的时候就需要一 ...
- jdk1.8HashMap底层数据结构:散列表+链表+红黑树,jdk1.8HashMap数据结构图解+源码说明
一.前言 本文由jdk1.8源码整理而得,附自制jdk1.8底层数据结构图,并截取部分源码加以说明结构关系. 二.jdk1.8 HashMap底层数据结构图 三.源码 1.散列表(Hash table ...
- 数据结构:DHUOJ 删除链表的顺数及倒数第N个节点
删除链表的顺数及倒数第N个节点 作者: turbo时间限制: 1S章节: DS:数组和链表 题目描述: 可使用以下代码,完成其中的removeNth函数,其中形参head指向无头结点单链表,n为要删除 ...
- 数据结构与算法之PHP实现链表类(单链表/双链表/循环链表)
链表是由一组节点组成的集合.每个节点都使用一个对象的引用指向它的后继.指向另一个节点的引用叫做链表. 链表分为单链表.双链表.循环链表. 一.单链表 插入:链表中插入一个节点的效率很高.向链表中插 ...
随机推荐
- 和菜鸟一起学linux之linux性能分析工具oprofile移植
一.内核编译选项 make menuconfig General setup---> [*] Profiling support <*> OProfile system profil ...
- obj-c编程14:Cocoa和Cocoa Touch简介
这一篇篇幅相对少很多,几乎没有代码,全部都要靠本猫的语言组织能力啊!Cocoa框架在前面讲解F库时曾简单做过介绍,现在再具体说一说喽.各位童鞋是否已经发现鸟,前面所写的所有代码都是基于终端(或称之为c ...
- OS X10.10下HomeBrew的安装提示
apple@kissAir: c_src$ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/m ...
- JS实现鼠标滚动事件,兼容IE9,FF,Chrome.
<!-- 废话不多说,直接贴代码 --><script type="text/javascript" src="jquery.min.js"& ...
- Centos下安装mysql 和挂载硬盘
一,CentOS下安装Mysql 6.5 1.检测系统是否自带安装mysql # yum list installed | grep mysql 2.删除已经安装的Mysql # yum -y rem ...
- Oracle 报错ORA-00904:标示符无效
写select查询,报错:ORA-00904 标示符无效 这个错误通常是因为 字段名写错了,或者是在创建表的时候,创建最后一个字段的时候也加了逗号 . 我遇到的情况时,之前的同事创建表的时候,将小写的 ...
- 《转》Xcode 6 正式版如何创建一个Empty Application
Xcode 6 正式版里面没有Empty Application这个模板,这对于习惯了纯代码编写UI界面的程序员来说很不习惯. 有网友给出了一个解决方法是,把Xcode 6 beta版里面的模板复制过 ...
- Java的运行原理
在Java中引入了虚拟机的概念,即在机器和编译程序之间加入了一层抽象的虚拟的机器.这台虚拟的机器在任何平台上都提供给编译程序一个的共同的接口.编译程序只需要面向虚拟机,生成虚拟机能够理解的代码,然后由 ...
- 经典的java中return和finally问题!
经典的java中return和finally问题! 标签: 杂谈 分类: java学习 前一段时间 参加公司的笔试问了这个问题,回来一查才知道当时自己做错了,百思不得其解,上网查到下面的程序,但是运行 ...
- RocketMQ源码 — 七、 RocketMQ高可用(2)
上一篇说明了RocketMQ怎么支持broker集群的,这里接着说RocketMQ实现高可用的手段之一--冗余. RocketMQ部署的时候一个broker set会有一个mater和一个或者多个sl ...