freertos内核原理学习 Day1(链表)

这篇具有很好参考价值的文章主要介绍了freertos内核原理学习 Day1(链表)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1.freertos列表与列表操作

1.1链表各节点定义(头文件list.h中)

1.1.1普通节点定义

1.1.2mini节点定义

1.1.3根节点定义

1.2链表操作(源文件list.c中)

1.2.1链表节点初始化

 1.2.2链表根节点初始化

  1.2.3插入节点到链表尾部

  1.2.4将节点按“升序”排列后插入到链表中

  1.2.5将节点从链表中删除

1.3仿真


1.freertos列表与列表操作

1.1链表各节点定义(头文件list.h中)

1.1.1普通节点定义

普通节点元素:

辅助排序值(xitemvalue);节点排序时确定当前节点处于链表的第几位

指向下一节点指针(pxnext);

指向上一节点指针(pxprevious);

指向内核对象指针(pvowner);

指向节点所在链表(pvcontainer);根节点代表的就是当前链表

freertos内核原理学习 Day1(链表),7天学会freertos内核原理,学习

  • struct xLIST_ITEM
    {
    	TickType_t xItemValue;             /* 辅助值,用于帮助节点做顺序排列 */			
    	struct xLIST_ITEM *  pxNext;       /* 指向链表下一个节点 */		
    	struct xLIST_ITEM *  pxPrevious;   /* 指向链表前一个节点 */	
    	void * pvOwner;					   /* 指向拥有该节点的内核对象,通常是TCB */
    	void *  pvContainer;		       /* 指向该节点所在的链表 */
    };
    typedef struct xLIST_ITEM ListItem_t;  /* 节点数据类型重定义 */
    

    1.1.2mini节点定义

  • mini节点:作为双向链表的结尾;(双向链表的头即是尾,尾即是头
  • mini节点元素组成:
  • 辅助排序值(xitemvalue);
  • 指向下一节点指针(pxnext);

  • 指向上一节点指针(pxprevious);

  • struct xMINI_LIST_ITEM
    {
    	TickType_t xItemValue;                      /* 辅助值,用于帮助节点做升序排列 */
    	struct xLIST_ITEM *  pxNext;                /* 指向链表下一个节点 */
    	struct xLIST_ITEM *  pxPrevious;            /* 指向链表前一个节点 */
    };
    typedef struct xMINI_LIST_ITEM MiniListItem_t; 

    1.1.3根节点定义

  • 根节点元素组成:
  • 链表节点计数器(uxnumberofitems);
  • 链表节点索引指针(pxindex);用于指向链表节点时用
  • 链表最后节点(MiniListItem_t);
  • mini节点元素;根节点作为双向链表的起始,故其也是链表的结尾
  • freertos内核原理学习 Day1(链表),7天学会freertos内核原理,学习
typedef struct xLIST
{
	UBaseType_t uxNumberOfItems;    /* 链表节点计数器 */
	ListItem_t *  pxIndex;			/* 链表节点索引指针 */
	MiniListItem_t xListEnd;		/* 链表最后一个节点 */
} List_t;

1.2链表操作(源文件list.c中)

1.2.1链表节点初始化

执行操作如下:
普通节点其所在链表指针置空(表节点还未被加入任何链表

void vListInitialiseItem( ListItem_t * const pxItem )
{
	/* 初始化该节点所在的链表为空,表示节点还没有插入任何链表 */
	pxItem->pvContainer = NULL;
}

 1.2.2链表根节点初始化

执行操作如下:
根节点的下/上一节点指针指向自己(表还未有节点加入链表),xItemValue置为最大(由于根节点必须在链表末尾/起始,为保证根节点在链表末尾,置根节点的辅助排序值为所允许的最大值,portMAX_DELAY为32位的最大值:0xffffffff),初始化节点计数器为0(表还未有节点加入链表)

  • freertos内核原理学习 Day1(链表),7天学会freertos内核原理,学习
void vListInitialise( List_t * const pxList )
{
	/* 将链表索引指针指向最后一个节点 */
	pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd );
	/* 将链表最后一个节点的辅助排序的值设置为最大,确保该节点就是链表的最后节点 */
	pxList->xListEnd.xItemValue = portMAX_DELAY;
    /* 将最后一个节点的pxNext和pxPrevious指针均指向节点自身,表示链表为空 */
	pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );
	pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );
	/* 初始化链表节点计数器的值为0,表示链表为空 */
	pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
}

  1.2.3插入节点到链表尾部

注:vListInsertEnd函数操作只能用于插入第一个节点时用,因为其并没有考虑到当根节点下已有普通节点的情况;

执行操作如下:

普通节点的下一节点指针->根节点;普通节点的上一节点指针->根节点;

根节点的下一节点指针->加入的普通节点;根节点的上一节点指针->加入的普通节点;

普通节点的链表指针->根节点(表其处于当前根节点的链表中);
节点插入完成初始化节点计数器+1(表有1个节点加入链表);

  • freertos内核原理学习 Day1(链表),7天学会freertos内核原理,学习
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem )
{
	ListItem_t * const pxIndex = pxList->pxIndex;

	pxNewListItem->pxNext = pxIndex;
	pxNewListItem->pxPrevious = pxIndex->pxPrevious;
	pxIndex->pxPrevious->pxNext = pxNewListItem;
	pxIndex->pxPrevious = pxNewListItem;

	/* 记住该节点所在的链表 */
	pxNewListItem->pvContainer = ( void * ) pxList;

	/* 链表节点计数器++ */
	( pxList->uxNumberOfItems )++;
}

  1.2.4将节点按“升序”排列后插入到链表中

执行操作如下:

注:迭代指针pxinteror指向的是待插入节点在其插入链表后的上一节点;

1.插入节点排序值 = 根节点初始化排序值时:认为此节点要插入到链表末尾,迭代指针指向上一次链表末尾的普通节点;

2.插入节点排序值 < 根节点初始化排序值时:迭代指针指向根节点,并开始遍历直到找到序号刚好<=插入节点排序值,此时迭代指针刚好指向要插入节点插入后的上一个节点;

由于迭代指针指向的是“待插入节点插入链表后的上一节点”,则在新节点插入时迭代指针的下一节点指针指向新节点,新节点的上一节点指针指向迭代指针,新节点的下一节点等于“新节点未插入时迭代指针的下一节点”,新节点的下一节点的上一节点更新指向为新节点;

  • freertos内核原理学习 Day1(链表),7天学会freertos内核原理,学习
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem )
{
	ListItem_t *pxIterator;
	
	/* 获取节点的排序辅助值 */
	const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;

	/* 寻找节点要插入的位置 */
	if( xValueOfInsertion == portMAX_DELAY )
	{
		pxIterator = pxList->xListEnd.pxPrevious;
	}
	else
	{
		for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd );
		     pxIterator->pxNext->xItemValue <= xValueOfInsertion; 
			 pxIterator = pxIterator->pxNext )
		{
			/* 没有事情可做,不断迭代只为了找到节点要插入的位置 */			
		}
	}
	pxNewListItem->pxNext = pxIterator->pxNext;
	pxNewListItem->pxNext->pxPrevious = pxNewListItem;
	pxNewListItem->pxPrevious = pxIterator;
	pxIterator->pxNext = pxNewListItem;
	/* 记住该节点所在的链表 */
	pxNewListItem->pvContainer = ( void * ) pxList;
	/* 链表节点计数器++ */
	( pxList->uxNumberOfItems )++;
}

  1.2.5将节点从链表中删除

执行操作如下:

获取要被移除节点所在的链表信息,被移除节点的上一节点其下一节点指针更新为被移除节点的上一节点,被移除节点的下一节点其上一节点指针更新为被移除节点的上一节点,若此时pxindex引导指针指向的是被移除的节点则将其指向更新为被移除节点的上一节点(pxindex引导指针必须指向其自己所在的链表,被移除节点已经不属于当前链表,所以索引指针不能指向它),将被移除节点所属链表项置空(表被移除节点现在已不属于任何链表),最后将链表节点计数器-1;

  • freertos内核原理学习 Day1(链表),7天学会freertos内核原理,学习
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
{
	/* 获取节点所在的链表 */
	List_t * const pxList = ( List_t * ) pxItemToRemove->pvContainer;
	pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
	pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
	/* Make sure the index is left pointing to a valid item. */
	if( pxList->pxIndex == pxItemToRemove )
	{
		pxList->pxIndex = pxItemToRemove->pxPrevious;
	}
	/* 初始化该节点所在的链表为空,表示节点还没有插入任何链表 */
	pxItemToRemove->pvContainer = NULL;
	/* 链表节点计数器-- */
	( pxList->uxNumberOfItems )--;
	/* 返回链表中剩余节点的个数 */
	return pxList->uxNumberOfItems;
}

1.3仿真

如下图所示:

main函数内创建了三个节点,之后可通过软件仿真的方式查看freertos中链表具体是如何运作的,程序是由野火提供的例程。

(程序链接:https://pan.baidu.com/s/1CSe82iXMcnYDph2MnqVj7A?pwd=1234 
提取码:1234)

freertos内核原理学习 Day1(链表),7天学会freertos内核原理,学习

本人为初学菜鸟,文章如有错误地方,感谢指正!!

参考:野火freertos内核实现与应用文章来源地址https://www.toymoban.com/news/detail-816686.html

到了这里,关于freertos内核原理学习 Day1(链表)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 学习JavaSE基础-day1

    JRE 和 JDK JRE:Java运行环境,如果想要运行Java程序至少要安装JRE JDK:Java开发环境(开发工具包),如果要开发Java程序,必须安装JDK JRE = JVM + 核心类库 JDK = JRE + 开发工具包 JDK JRE JVM 关系如图所示:     JDK下载地址:www.oracle.com 配置Path环境变量:希望可以在命令窗口的任意的

    2024年02月07日
    浏览(102)
  • Nodejs前端学习Day1

    妈的,这几天真tm冷,前天上午还下了一整天的雪,大雪 妈的,昨天没学,上午练车去了,下午就当了一下午废物,操,真是个废物。 现在官网的描述: 学习视频中的描述(旧版本): 如果我们写了一段js放到浏览器中运行则证明在做前端开发 如果我们写了一段js放到node

    2024年01月25日
    浏览(42)
  • 【剑指offer】学习计划day1

    目录 一. 前言  二. 用两个栈实现队列         a.题目          b.题解分析           c.AC代码   二. 包含min函数的栈          a.题目          b.题解分析         c.AC代码   本系列是针对Leetcode中剑指offer学习计划的记录与思路讲解。详情查看以下链接: 剑指offer-学

    2023年04月24日
    浏览(40)
  • 前端学习——JS进阶 (Day1)

    局部作用域 全局作用域 作用域链 JS垃圾回收机制 闭包 变量提升 函数提升 函数参数 动态参数 剩余参数 展开运算符 箭头函数(重要) 基本写法 箭头函数参数 箭头函数 this 数组解构 练习 数组解构 对象解构 多级对象解构 for each 案例 筛选

    2024年02月16日
    浏览(37)
  • Vue3 学习笔记(Day1)

    「写在前面」 本文为尚硅谷禹神 Vue3 教程的学习笔记。本着自己学习、分享他人的态度,分享学习笔记,希望能对大家有所帮助。 目录 0 课程介绍 1 Vue3 简介 2 创建 Vue3 工程 2.1 基于 vue-cli 创建 2.2 基于 vite 创建(推荐) 2.3 一个简单的效果 P1:https://www.bilibili.com/video/BV1Za4y

    2024年02月20日
    浏览(41)
  • 前端学习——Web API(Day1)

    Web API 基本认知 作用和分类 DOM DOM树 DOM对象 根据CSS选择器来获取DOM元素 小练习 其他获取DOM元素方法 识别标签 小练习 操作元素常用属性 小练习 操作元素样式属性 小练习 小练习 操作表单元素属性 自定义属性 小练习

    2024年02月13日
    浏览(54)
  • 数据结构与算法学习(day1)

    (1)我是一个大三的学生(准确来说应该是准大三,因为明天才报名哈哈哈)。 (2)最近就想每天闲着没事也刷些C语言习题来锻炼下编程水平,也一直在思考企业对应届大学生能力的要求,所以经常会想到关于面试的事情。由于我也没实习过,所以我对面试没有一个具象化

    2024年02月10日
    浏览(49)
  • 【学习笔记】「JOISC 2022 Day1」错误拼写

    显然只用考虑 [ i : j ] [i:j] [ i : j ] 这一段拼成的串。不难得出结论:设 n x t i nxt_i n x t i ​ 表示 i i i 之后第一个本质不同的字符的位置,那么 n x t i ≤ j nxt_ile j n x t i ​ ≤ j ,并且 s i ? s n x t i s_i?s_{nxt_i} s i ​ ? s n x t i ​ ​ ,或者 n x t i j nxt_ij n x t i ​ j 。 我真傻,真的

    2024年02月03日
    浏览(42)
  • 嵌入式学习-C++Day7&&QT Day1

    2024年02月21日
    浏览(66)
  • 【Java】零基础上手SpringBoot学习日记(day1)

    此帖为本人学习Springboot时的笔记,由于是个接触计算机一年左右的新手,也没有网站开发经验,所以有些地方的理解会比较浅显并且可能会出现错误,望大佬们多多包涵和指正。 在我的理解中,Web应用的开发大体分为两个部分,一个是前端的页面设计以及实现,比如使用H

    2024年02月14日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包