List And ListItem
目录
FreeRTOS 列表和列表项的用途
内核调度管理
就绪列表 (Ready Lists)
每个优先级都有一个独立的就绪列表,用于管理处于就绪状态的任务。调度器通过遍历这些列表来选择最高优先级的就绪任务运行。
延迟列表 (Delayed List)
管理被延迟的任务,按唤醒时间排序。当系统时钟滴答发生时,检查并移动到期任务到就绪列表。
挂起列表 (Pending Ready List)
在调度器挂起期间变为就绪的任务临时存放在此列表,待调度器恢复时再转移到就绪列表。
事件列表
用于管理等待事件(如信号量、队列、事件组)的任务,按优先级排序。
资源管理
任务状态跟踪
通过列表管理任务的不同状态转换,确保任务在适当的时候被调度执行。
定时器管理
软件定时器使用列表来管理定时器的触发时间和执行顺序。
内存管理
某些内存分配方案使用列表来跟踪空闲内存块。
列表和列表项的概念
列表是 FreeRTOS 内核中的基础数据结构,用于管理任务和各种内核对象。所有列表都实现为双向环形链表,确保高效的插入和删除操作。
列表 (List)
列表是 FreeRTOS 中用于组织和管理多个相关项目的数据结构。每个列表包含头尾指针和项目计数,主要用于: - 就绪任务列表 - 延迟任务列表 - 挂起任务列表 - 事件等待列表
列表项 (ListItem)
列表项是列表中的基本元素,每个列表项包含前后指针和所属列表指针。列表项还包含一个排序值,用于在列表中按升序排列。
列表结构体定义
List_t 结构体
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;
成员说明:
- uxNumberOfItems:记录列表中列表项的数量,不含 xListEnd
- pxIndex:用于遍历列表的指针,指向当前被引用的列表项
- xListEnd:列表尾标记,是一个迷你列表项
- listFIRST_LIST_INTEGRITY_CHECK_VALUE:这两个宏是确定的已知常量,FreeRTOS通过检查这两个常量的值,来判断列表的数据在程序运行的过程中,是否遭到破坏,该功能一般用于调试,默认不开启。
ListItem_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;
struct xLIST * configLIST_VOLATILE pxContainer;
listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE
};
成员说明:
- xItemValue:排序值,用于确定列表项在列表中的位置,为0xFFFFFFFF(32位)
- pxNext:指向下一个列表项的指针
- pxPrevious:指向前一个列表项的指针
- pvOwner:指向拥有该列表项的对象(通常是任务控制块)
- pxContainer:指向该列表项所属的列表
MiniListItem_t 结构体
typedef 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;
} MiniListItem_t;
迷你列表项是简化版的列表项,主要用于列表尾标记以及挂载其他插入列表中的列表项,不包含所有者指针和容器指针。
用处
当列表为空时,我们怎么加入新项?这时候就需要这个Mini列表项,用来挂载加入列表的新元素。当列表为空时,它的两只手(Previous和Next)都指向自己。
列表操作 API
列表初始化
vListInitialise(List_t* const pxList)- 初始化列表vListInitialiseItem(ListItem_t* const pxItem)- 初始化列表项
列表项操作
vListInsert(List_t* const pxList, ListItem_t* const pxNewListItem)- 按排序值插入列表项vListInsertEnd(List_t* const pxList, ListItem_t* const pxNewListItem)- 在列表中当前指向列表项前插入,即插入已遍历的最末端,是一种无序插入方法。uxListRemove(ListItem_t* const pxItemToRemove)- 从列表中移除列表项
列表遍历
listGET_OWNER_OF_NEXT_ENTRY()- 获取下一个列表项的所有者listLIST_IS_EMPTY()- 检查列表是否为空
列表的特点
排序机制
列表项按 xItemValue 值升序排列,这对于时间相关的操作(如任务延迟)非常有用。
完整性检查
当 configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 设置为 1 时,列表和列表项会包含完整性检查字节,用于检测内存损坏。
线程安全
列表操作不是原子性的,在操作列表时需要挂起调度器或使用关键段来保证线程安全。