FreeRTOS链表实现
直接上源码分析
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 )
pxList->uxNumberOfItems = ( UBaseType_t ) 0U; /* 记录列表中节点的数量 */
}
void vListInitialiseItem( ListItem_t * const pxItem )
{
/* 标记此节点属于哪个列表。初始化为NULL */
pxItem->pxContainer = NULL;
}
void vListInsertEnd( List_t * const pxList,
ListItem_t * const pxNewListItem )
{
ListItem_t * const pxIndex = pxList->pxIndex; /* 先拿到这个链表的索引,网上说这个索引指向列表项的头部,但是初始化并没有这个操作 */
pxNewListItem->pxNext = pxIndex; /* 新插入的节点的下一个节点就是这个pxIndex节点 ,新插入的节点指向了末尾节点 */
pxNewListItem->pxPrevious = pxIndex->pxPrevious; /* pxIndex->pxPrevious 指向的是列表的末尾节点,pxNewListItem->pxPrevious 新插入的节点的上一个等于末尾的节点,不知道为什么要这样 */
pxIndex->pxPrevious->pxNext = pxNewListItem; /* pxIndex->pxPrevious->pxNext本来是指向自己,现在指向的是新节点,等于连接起来 */
pxIndex->pxPrevious = pxNewListItem; /* 基本操作了,链接节点 */
pxNewListItem->pxContainer = pxList; /* 标记状态 */
( pxList->uxNumberOfItems )++; /* 节点加1,这里为什么加括号? */
}
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; /* 如果要插入的节点的值等于最大值,那就插在End的前一个节点的位置 */
}
else
{
/* 首先pxIterator指向此链表的最后一个节点,判断新插入的节点的值和pxIterator下一个节点的值
此时 pxIterator->pxNext->xItemValue就是首节点的值,(为什么是首节点,因为初始化pxIterator指向了End节点,pxIterator = ( ListItem_t * ) &( pxList->xListEnd ))
如果插入的值大于pxIterator->pxNext->xItemValue(第一次是首节点的值),那么pxIterator=pxIterator->pxNext ,即指向下一个节点继续循环
如果插入的值小于pxIterator->pxNext->xItemValue,那么就说明找到了要插入的地方
那就是新插入的到pxIterator的后面,要插入的节点就是pxIterato和 pxIterato->next之间。
*/
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) { }
}
pxNewListItem->pxNext = pxIterator->pxNext; /* 首先把 pxIterator->pxNext 赋值给 pxNewListItem->pxNext,让新列表项指向原本列表中下一个列表项 */
pxNewListItem->pxNext->pxPrevious = pxNewListItem; /* 把 pxNewListItem->pxNext(也就是原本列表中下一个列表项)的 pxNewListItem->pxNext->pxPrevious 成员指向待插入列表项 pxNewListItem,实现双向链表 */
pxNewListItem->pxPrevious = pxIterator; /* 新插入的上一个指向pxIterator,就是上面说的,新的节点插到pxIterator的后面 */
pxIterator->pxNext = pxNewListItem; /* pxIterator->pxNext : 原来的pxIterator节点 (此时只是插入节点,xIterator->pxNext一定要指向pxNewListItem,实现节点的链接)的下一个就是新的节点了 */
pxNewListItem->pxContainer = pxList; /* 老套路了 */
( pxList->uxNumberOfItems )++; /* 列表项个数加1 */
}
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
{
List_t * const pxList = pxItemToRemove->pxContainer; /* 得到要删除节点链表 */
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; /* 这里就只是改变指针前后链接 */
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
mtCOVERAGE_TEST_DELAY(); /* 这里为什么要存在空函数? */
if( pxList->pxIndex == pxItemToRemove ) /* 很好理解,不做解释 */
{
pxList->pxIndex = pxItemToRemove->pxPrevious;
}
pxItemToRemove->pxContainer = NULL; /* 已经都删除节点了,这个节点的属主链表肯定不存在啊 */
( pxList->uxNumberOfItems )--; /* 老套路了 */
return pxList->uxNumberOfItems; /* 返回这个链表还有几个节点 */
}
// 仍有疑问,希望有人看到能解答一下,在下感激不尽。
FreeRTOS链表实现的更多相关文章
- FreeRTOS --(1)链表
转载自 https://blog.csdn.net/zhoutaopower/article/details/106550648 Based On FreeRTOS Kernel V10.3.1 1. ...
- FreeRTOS数据结构(一)--链表和链表项
结构体定义 /*链表结构体*/ typedef struct xLIST { listFIRST_LIST_INTEGRITY_CHECK_VALUE /*用于链表完整性检查*/ configLIST ...
- FreeRTOS 使用指南(转)
源:FreeRTOS 使用指南 繁星电子开发团队制作 作为一个轻量级的操作系统,FreeRTOS 提供的功能包括:任务管理.时间管理.信号量.消息队列.内存管理.记录功能等,可基本满足较小系统的需要. ...
- FreeRTOS初步认识
源:FreeRTOS初步认识 用了半天时间对FreeRTOS有了一个初步的认识,大概总结一下,其中混杂了系统实现和实际应用方面的问题. 现只是以应用为目的,实现方面待以后进一步研究. 1.FreeRT ...
- FreeRTOS代码剖析
FreeRTOS代码剖析之1:内存管理Heap_1.c FreeRTOS代码剖析之2:内存管理Heap_2.c FreeRTOS(V8.0.1)系统之xTaskGenericCreate() ...
- FreeRTOS的内存管理
FreeRTOS提供了几个内存堆管理方案,有复杂的也有简单的.其中最简单的管理策略也能满足很多应用的要求,比如对安全要求高的应用,这些应用根本不允许动态内存分配的. FreeRTOS也允许你自己实现内 ...
- FreeRTOS 动态内存管理
以下转载自安富莱电子: http://forum.armfly.com/forum.php 本章节为大家讲解 FreeRTOS 动态内存管理,动态内存管理是 FreeRTOS 非常重要的一项功能,前面 ...
- FreeRTOS内存管理
简介 Freertos的内存管理分别在heap_1.c,heap_2.c,heap_3.c,heap_4.c,heap_5.c个文件中,选择合适的一种应用于嵌入式项目中即可. 本文的图片中 红色部分B ...
- FreeRTOS基础知识
前面一篇文章介绍了一些命名规范之类的基础知识,但是我觉得还缺少一定前言知识,就是裸机和操作系统有什么区别,为什么我们需要学freertos,因为招聘要求?那么为什么招聘网又会有这个要求呢?所以我们为什 ...
随机推荐
- JVM内存溢出与内存泄漏
内存溢出与内存泄漏 内存溢出相对于内存泄漏来说,尽管更容易被理解,但是同样的,内存溢出也是引发程序崩溃的罪魁祸首之一. 由于GC一直在发展,所有一般情况下,除非应用程序占用的内存增长速度非常快,造成垃 ...
- Apache Hudi和Presto的前世今生
一篇由Apache Hudi PMC Bhavani Sudha Saktheeswaran和AWS Presto团队工程师Brandon Scheller分享Apache Hudi和Presto集成 ...
- spring-dao.xml通常写法
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...
- 交互平台 - Processing - 开发模板(仿Openframeworks)
之前在CSDN上发表过: https://blog.csdn.net/fddxsyf123/article/details/62425251
- 手把手教你基于CentOS8搭建微信订阅号后台服务(一)
一.准备域名并完成解析 关于域名,我买的是阿里的一个1元/年的廉价域名,同时国内域名都需要备案,当时在这里耽搁了挺久的. 域名解析的话,在阿里云官方帮助文档里有.传送门:https://help.al ...
- jquery全选,全不选,反选
前台 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.o ...
- 树莓派3B+安装64位ubuntu系统和docker工具
想在树莓派3B上安装一些64位应用(例如64位JDK),因此首先要安装64位的操作系统,今天咱们就一起来实战: 原文地址:https://blog.csdn.net/boling_cavalry/ar ...
- 【小白学PyTorch】15 TF2实现一个简单的服装分类任务
[新闻]:机器学习炼丹术的粉丝的人工智能交流群已经建立,目前有目标检测.医学图像.时间序列等多个目标为技术学习的分群和水群唠嗑的总群,欢迎大家加炼丹兄为好友,加入炼丹协会.微信:cyx64501661 ...
- 项目里出现两个配置类继承WebMvcConfigurationSupport时,为什么只有一个会生效(源码分析)
为什么我们的项目里出现两个配置类继承WebMvcConfigurationSupport时,只有一个会生效.我在网上找了半天都是说结果的,没有人分析源码到底是为啥,博主准备讲解一下,希望可以帮到大家! ...
- 关于VS编译报错,但是错误信息未提示问题解决方案
可能代码中引用了别的类库中的函数,然后未编译被引用库导致编译报错,重新编译被引用库然后再编译当前库即可解决问题