前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >FreeRTOS(八):列表和列表项

FreeRTOS(八):列表和列表项

作者头像
Jasonangel
发布2021-12-27 15:52:43
发布2021-12-27 15:52:43
2.2K0
举报

要想看懂 FreeRTOS 源码并学习其原理,有一个东西绝对跑不了,那就是 FreeRTOS 的列表和列表项。列表和列表项是 FreeRTOS 的一个数据结构,FreeRTOS 大量使用到了列表和列表项, 它是 FreeRTOS 的基石。要想深入学习并理解 FreeRTOS,那么列表和列表项就必须首先掌握, 否则后面根本就没法进行。

列表 ---> 链表

1、列表

列表是 FreeRTOS 中的一个数据结构,概念上和【链表】有点类似,列表被用来跟踪 FreeRTOS 中的任务。与列表相关的全部东西都在文件 list.c 和 list.h 中。在 list.h 中定义了一个叫 List_t 的结构体,如下:

(1) 和 (5) 、 这 两 个 都 是 用 来 检 查 列 表 完 整 性 的 , 需 要 将 宏 configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 设置为 1,开启以后会向这两个地方分别 添加一个变量 xListIntegrityValue1 和 xListIntegrityValue2,在初始化列表的时候会这两个变量中写入一个特殊的值,默认不开启这个功能。

(2)、uxNumberOfItems 用来记录列表中列表项的数量。

(3)、pxIndex 用来记录当前列表项索引号,用于遍历列表。

(4)、列表中最后一个列表项,用来表示列表结束,此变量类型为 MiniListItem_t,这是一个 迷你列表项。

并未列出用于列表完整性检查的成员变量。

2、列表项

列表项就是存放在列表中的项目,FreeRTOS 提供了两种列表项:列表项和迷你列表项。这 两个都在文件 list.h 中有定义,先来看一下列表项,定义如下:

(1)和(7)、用法和列表一样,用来检查列表项完整性的。以后我们在学习列表项的时候不讨 论这个功能!

(2)、xItemValue 为列表项值。

(3)、pxNext 指向下一个列表项。

(4)、pxPrevious 指向前一个列表项,和 pxNext 配合起来实现类似双向链表的功能。

(5)、pvOwner 记录此链表项归谁拥有,通常是任务控制块。

(6)、pvContainer 用来记录此【列表项】归哪个【列表】。

3、迷你列表项

迷你列表项在文件 list.h 中有定义。

(1)、用于检查迷你列表项的完整性。

(2)、xItemValue 记录列表列表项值。

(3)、pxNext 指向下一个列表项。

(4)、pxPrevious 指向上一个列表项。

可以看出迷你列表项只是比列表项少了几个成员变量,迷你列表项有的成员变量列表项都有的,没感觉有什么本质区别啊?那为什么要弄个迷你列表项出来呢?那是因为有些情况下我们不需要列表项这么全的功能,可能只需要其中的某几个成员变量,如果此时用列表项的话会造成内存浪费!比如上面列表结构体 List_t 中表示最后一个列表项的成员变量 xListEnd 就是MiniListItem_t 类型的。

4、列表初始化

新创建或者定义的列表需要对其做初始化处理,列表的初始化其实就是初始化列表结构体List_t 中的各个成员变量,列表的初始化通过使函数 vListInitialise() 来完成,此函数在 list.c 中有定义。

5、列表项初始化

同列表一样,列表项在使用的时候也需要初始化,列表项初始化由函数 vListInitialiseItem() 来完成。

6、列表项插入

列表项的插入操作通过函数 vListInsert() 来完成,列表项是按照升序的方式插入的。

插入过程和数据结构中双向链表的插入类似,像 FreeRTOS 这种 RTOS 系统和一些协议栈都会大量用到数据结构的知识,所以建议大家没事的时候多看看数据结构方面的书籍,否则的话看源码会很吃力的。

注意观察插入完成以后列表 List 和列表项 ListItem1 中各个成员变量之间的变化,比如列 表 List 中的 uxNumberOfItems 变为了 1,表示现在列表中有一个列表项。列表项 ListItem1 中的pvContainer 变成了 List,表示此列表项属于列表 List。通过图 7.3.2.1 可以看出,列表是一个环形的,即环形列表!

上面再讲解函数 vListInsert()的时候说过了列表项是按照升序的方式插入的,所以 ListItem2 肯定是插入到 ListItem1 的后面、xListEnd 的前面。同样的,列表 List 的 uxNumberOfItems 再次加一变为 2 了,说明此时列表中有两个列表项。

按照升序排列的方式,ListItem3 应该放到 ListItem1 和 ListItem2 中间,大家最好通过对照这三幅图片来阅读函数 vListInsert()的源码,这样就会对函数有一个直观的认识。

7、列表项末尾插入

列表末尾插入列表项的操作通过函数 vListInsertEnd ()来完成。

8、列表项的删除

有列表项的插入,那么必然有列表项的删除,列表项的删除通过函数 uxListRemove()来完成。----> 将要删除的列表项的前后两个列表项“连接”在一起。

9、列表的遍历

介绍列表结构体的时候说过列表 List_t 中的成员变量 pxIndex 是用来遍历列表的,FreeRTOS提供了一个函数来完成列表的遍历,这个函数是 listGET_OWNER_OF_NEXT_ENTRY()。每调用一次这个函数列表的 pxIndex 变量就会指向下一个列表项,并且返回这个列表项的 pxOwner变量值。这个函数本质上是一个宏,这个宏在文件 list.h 中定义。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-12-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 嵌入式Linux系统开发 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、列表
  • 2、列表项
  • 3、迷你列表项
  • 4、列表初始化
  • 5、列表项初始化
  • 6、列表项插入
  • 7、列表项末尾插入
  • 8、列表项的删除
  • 9、列表的遍历
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档