从0构建一个基于STM32F103的类FreeRTOS系统内核 - 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;
    // 记录此 链表项 归谁拥有,通常是 TCB (任务控制块)
    void * pvOwner;
    // 拥有该 链表项 的 链表 
    struct xLIST * configLIST_VOLATILE pxContainer;
    // 检验一个 链表项 数据是否完整
    listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE
};
typedef struct xLIST_ITEM ListItem_t;

它的组织形式如下图所示
在这里插入图片描述
除此之外,还有一个MINI链表,但迷你列表项仅用于标记列表的末尾和挂载其他插入列表中的列表项,用户是用不到迷你列表项的,通常在在 list.h 文件中。
可以理解成专用于表示链表的尾节点的数据结构,即链表的尾巴。

/*MINI链表项
2024/11/6
ConstantZ
*/
struct xMINI_LIST_ITEM
{
	// 检验一个 MINI链表项 数据是否完整
    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;

它的组织形式如下图所示
在这里插入图片描述
接下里介绍的数据结构就是包含上述两个数据结构的东西的完整链表,即xLIST,它的结构如下

typedef struct xLIST
{
	// 检验一个 链表 数据是否完整
    listFIRST_LIST_INTEGRITY_CHECK_VALUE 
    // 记录 链表 中 链表项 数目
    volatile UBaseType_t uxNumberOfItems;
    // 遍历 链表 的指针
    ListItem_t * configLIST_VOLATILE pxIndex;
    // 使用 MINI链表项 表示 链表尾部
    MiniListItem_t xListEnd;
    // 检验一个 链表 数据是否完整
    listSECOND_LIST_INTEGRITY_CHECK_VALUE
} List_t;

xLIST由多个链表项构成的链表,每个链表项都挂载了一个任务。它的作用一般是区分不同任务状态或任务优先级,比如就绪状态的任务放在就绪链表中,阻塞状态的任务放在阻塞链表中,方便任务切换和管理.它的结构框图如下:
在这里插入图片描述

实现功能

实现的功能起始就是基础的 增删查改功能

初始化链表
  • void vListInitialiseItem( ListItem_t * const pxItem )
    初始化的时候该链表项未被任何链表包含,即初始化表示任何xLIST结构体变量都不拥有它(xMINI_LIST_ITEM)
void vListInitialiseItem( ListItem_t * const pxItem )  
{
   
     
    // 确保链表项未被记录在链表中
    pxItem->pxContainer = NULL; 
}

初始化xList结构体,即初始化链表,需要做四件事情
 (1) 当前链表指针pxIndex指向末尾xListEnd
 (2) 确保尾链表项 xListEnd 被排在链表最尾部 由代码可见是升序排序这些链表项的值的
 (3) 将尾链表项 xListEnd 的前/后链表项指针均指向自己,因为初始化链表时只有尾链表项
 (4) 初始化链表有0个链表项

void vListInitialise( List_t * const pxList )  
{
   
     
    // 链表当前指针指向 xListEnd
    pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd );
    
    // 设置链表尾链表项排序值为最大, 保证 xListEnd 会被放在链表的尾部
    pxList->xListEnd.xItemValue = portMAX_DELAY;
  
    // 尾链表项 xListEnd 的前/后链表项指针均指向自己
    pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );
    pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );
	// 初始化时链表中有 0 个链表项
    pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
}

执行完找个函数后,xList结构体内部的值如下
在这里插入图片描述

尾部插入链表项

即我们在链表项的最后插入链表项。代码实现如下

void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem )  
{
   
   
	// 获取链表中当前指针 pxIndex 位置
	ListItem_t * const pxIndex = pxList->pxIndex;
	 
	// 1. 改变自身 pxNext 和 pxPrevious
    pxNewListItem->pxNext = pxIndex;
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值