引言
链表是FreeRTOS中最基础也是最重要的数据结构,它支撑着整个调度器的运行。FreeRTOS使用双向循环链表来管理任务、队列、定时器等各种对象。本文将深入分析FreeRTOS V11.1.0中链表的设计理念和实现细节,揭示其高效运行的秘密。
1. 链表结构设计概览
FreeRTOS的链表设计包含两个核心结构:链表项(ListItem_t)和链表(List_t)。
1.1 链表项结构
struct xLIST_ITEM
{
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /* 完整性检查值1 */
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 /* 完整性检查值2 */
};
typedef struct xLIST_ITEM ListItem_t;
1.2 链表结构
typedef struct xLIST
{
listFIRST_LIST_INTEGRITY_CHECK_VALUE /* 完整性检查值1 */
configLIST_VOLATILE UBaseType_t uxNumberOfItems; /* 链表中的项目数量 */
ListItem_t * configLIST_VOLATILE pxIndex; /* 用于遍历链表的索引指针 */
MiniListItem_t xListEnd; /* 链表结束标记,包含最大可能值 */
listSECOND_LIST_INTEGRITY_CHECK_VALUE /* 完整性检查值2 */
} List_t;
1.3 迷你链表项
为了节省内存,FreeRTOS还提供了迷你链表项:
#if ( configUSE_MINI_LIST_ITEM == 1 )
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;
#else
typedef struct xLIST_ITEM MiniListItem_t;
#endif
2. 双向循环链表的设计精髓
2.1 循环结构的巧妙设计
FreeRTOS的链表是双向循环链表,其中xListEnd作为哨兵节点:
void vListInitialise( List_t * const pxList )
{
/* 链表索引指向结束标记 */
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 );
/* 初始化其他字段 */
#if ( configUSE_MINI_LIST_ITEM == 0 )
{
pxList->xListEnd.pvOwner = NULL;
pxList->xListEnd.pxContainer = NULL;
listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) );
}
#endif
pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
/* 设置完整性检查值 */
listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
}
设计亮点:
-
哨兵节点:
xListEnd简化了边界条件处理 -
循环结构: 消除了NULL指针检查的需要
-
最大值标记: 确保哨兵节点始终在链表末尾
2.2 链表项初始化
void vListInitialiseItem( ListItem_t * const pxItem )
{
/* 确保链表项不被记录为在任何链表中 */
pxItem->pxContainer = NULL;
/* 设置完整性检查值 */
listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
}
3. 链表操作算法深度解析
3.1 按值插入算法
FreeRTOS的链表支持按值自动排序插入:
void vListInsert( List_t * const pxList, ListItem_t * const

最低0.47元/天 解锁文章
363

被折叠的 条评论
为什么被折叠?



