FreeRTOS中的列表和列表项
在FreeRTOS 中,列表和列表项就是数据结构中的链表和节点。列表(List) 和 列表项(List Item) 是用于管理和操作任务、事件或其他资源的基础数据结构。它们广泛应用于调度器、任务管理、定时器管理以及许多其他模块中。
列表和列表项
1、列表
一个列表(List)由多个列表项(List Item)组成。FreeRTOS中的列表是双向链表,因此可以从前向后或者从后向前遍历列表项。列表通常用于实现任务就绪队列、定时器队列等数据结构。
有关列表的定义如下:
typedef struct xLIST
{
listFIRST_LIST_INTEGRITY_CHECK_VALUE /* 校验值 */
volatile UBaseType_t uxNumberOfItems; /* 列表中列表项的数量 */
ListItem_t * configLIST_VOLATILE pxIndex; /* 用于遍历列表 */
MiniListItem_t xListEnd; /* 最后一个列表项 */
listSECOND_LIST_INTEGRITY_CHECK_VALUE /* 校验值 */
} List_t;
列表的结构图如下:
列表的特点:
- 双向链表:由多个列表项组成,形成双向链表结构。
- 动态增删:支持动态增删操作,且具有 O(1) 时间复杂度。
- 按排序值组织:根据 xItemValue 排序,保证高效的访问和操作。
- 元素计数:列表会跟踪当前包含的元素数目 ,避免每次遍历整个链表来计算长度。
2、列表项
列表项是一个结构体,表示列表中的一个元素,它存储了与该元素相关的信息。
列表项中含有的信息如下:
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; /* 列表项的拥有者 */
struct xLIST * configLIST_VOLATILE pxContainer; /* 列表项所在列表 */
listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /* 用于检测列表项的数据完整性 */
};
typedef struct xLIST_ITEM ListItem_t;/* 重定义成 ListItem_t */
列表项的结构图如下:
列表项的特点:
- 双向链表结构:每个列表项都包含两个指针,一个指向列表中的下一个项,另一个指向上一个项,能够双向遍历,提高操作灵活性和效率。
- 排序值:每个列表项都有一个xItemValue字段,这个值用于对列表项进行排序。
- 数据存储空间:列表项本身通常并不存储具体的任务或数据结构,而是包含了一个指向任务或其他资源的数据结构的指针。
- 链表节点的“裸”特性:列表项是一个“裸”节点,它只通过 pxNext 和 pxPrevious 来与其他节点进行连接。它没有其他复杂的结构。
对于列表和多个列表之间的关系可以由下图概括:
3、迷你列表项
迷你列表项也是列表项,但迷你列表项仅用于标记列表的末尾和挂载其他插入列表中的列表项 。
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; /* 下一个列表项 */
};
typedef struct xMINI_LIST_ITEM MiniListItem_t;
迷你列表项的结构示意图如下:
迷你列表项只用于标记列表的末尾和挂载其他插入列表中的列表项,因此不需要成员变量 pxOwner 和 pxContainer,以节省内存开销 。
列表和列表项的相关API函数
以下是列表和列表项的相关API函数:
函数 | 描述 |
---|---|
vListInitialise() | 初始化列表 |
vListInitialiseItem() | 初始化列表项 |
vListInsertEnd() | 列表末尾插入列表项 |
vListInsert() | 列表插入列表项 |
uxListRemove() | 列表移除列表项 |
1.vListInitialise()
此函数用于初始化列表,在定义列表之后,需要先对其进行初始化,只有初始化后的列表,才能够正常地被使用。初始化示意图如下所示:
2. vListInitialiseItem()
此函数用于初始化列表项,如同列表一样,在定义列表项之后,也需要先对其进行初始化,只有初始化有的列表项,才能够被正常地使用。初始化示意图如下:
3. vListInsertEnd()
此函数用于将待插入列表的列表项插入到列表 pxIndex 指针指向列表项的前面,是一种无序的插入方法。
注意,pxIndex 不一定指向 xListEnd,而是有可能指向列表中任意一个列表项。
4. vListInsert()
此函数用于将待插入列表的列表项按照列表项值升序排序的顺序,有序地插入到列表中。
此函数在将待插入列表项插入列表之前,会前遍历列表,找到待插入列表项需要插入的位置。待插入列表项需要插入的位置是依照列表中列表项的值按照升序排序确定的。
5. uxListRemove()
此函数用于将列表项从列表项所在列表中移除。
注意,函数 uxListRemove()移除后的列表项,依然于列表有着单向系,即移除后列表项中用于指向上一个和下一个列表项的指针,依然指向列表中的列表项。