1. 列表和列表项

2023-05-16

列表和列表项

列表

列表是一个数据结构,用来追踪任务,列表中有一个指针指向列表项

列表是一个结构体,内部携带一个指针,指针指向列表项,列表项形成双向链式结构挂载在列表下

一个列表下面可以有很多的列表项,每个列表项都会有一个指针指向这个列表,下面是一个列表

typedef struct xLIST
{
	listFIRST_LIST_INTEGRITY_CHECK_VALUE
	configLIST_VOLATILE UBaseType_t uxNumberOfItems;	// 记录列表挂载列表项数量
	ListItem_t * configLIST_VOLATILE pxIndex;			// 指向列表项的指针,用于遍历列表
	MiniListItem_t xListEnd;							// 不会改变,永远指向首/尾列表项,xListEnd
	listSECOND_LIST_INTEGRITY_CHECK_VALUE
} List_t;

listFIRST_LIST_INTEGRITY_CHECK_VALUE与listSECOND_LIST_INTEGRITY_CHECK_VALUE用于检测列表的完整性,使能后自动添加变量

uxNumberOfItems:记录列表中列表项的数量

pxIndex:记录当前某个列表项的地址,用于遍历列表(指针,记录当前列表项位置,列表项按照升序排列,寻址访问对应列表项)

xListEnd:列表中的最后一个列表项,用来表示列表结束,是一个阉割版的列表项,迷你列表项(不要不必要的东西)

列表初始化
void vListInitialise( List_t * const pxList )
{
	pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd );				// 初始化索引地址,默认挂载 xListEnd
	pxList->xListEnd.xItemValue = portMAX_DELAY;							// 辅助值 排序节点,xListEnd为最后一节点
	pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );		// 当前列表为空,只挂载 xListEnd
	pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );	// 再挂载是通过 xListEnd
	pxList->uxNumberOfItems = ( UBaseType_t ) 0U;							// 当前挂载列表项数量为0,链表节点计数器
	listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );							// 宏,变量定义
	listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
}

初始化列表,由于列表项的数量为0,所以大多数据被初始化为0,各种指针指向xListEnd,也就是列表中的迷你列表项,也是双向列表的首尾

列表项

struct xLIST_ITEM
{
	listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE			// 宏值,列表项完整性考虑
	configLIST_VOLATILE TickType_t xItemValue;			// 列表项辅助值,进行排序
	struct xLIST_ITEM * configLIST_VOLATILE pxNext;		// 列表项 next 指针
	struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;	// 列表项 prev 指针
	void * pvOwner;										// 列表项归属TCB
	void * configLIST_VOLATILE pvContainer;				// 列表项归属列表
	listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE
};
typedef struct xLIST_ITEM ListItem_t;

listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE与listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE用于检测列表项的完整性

xItemValue:当前列表项挂载的位置,记录列表项在链表中的位置(xListEnd是0)

pxNext:指向下一个列表项

pxPrevious:指向上一个列表项(实现双向链表)

pvOwner:记录列表项的拥有者(归属TCB)

pvContainer:记录列表项归属列表(就绪,阻塞列表)

迷你列表项

列表项的阉割版(主要是节省资源),作为列表下挂列表项的头和尾

struct xMINI_LIST_ITEM		// 一般是xEndList
{
   listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE
   configLIST_VOLATILE TickType_t xItemValue;			// 列表项挂载值,列表项排序
   struct xLIST_ITEM * configLIST_VOLATILE pxNext;		// 列表项 next 指针
   struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;	// 列表项 prev 指针
};
typedef struct xMINI_LIST_ITEM MiniListItem_t;

listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE用于检测迷你列表项的完整

xItemValue:用于记录列表项值

pxNext:指向下一个列表项

pxPrevious:指向上一个列表项

列表项初始化
void vListInitialiseItem( ListItem_t * const pxItem )
{
   pxItem->pvContainer = NULL;									// 仅仅只需要初始化列表项归属列表,表示该列表项没插入任何列表
   listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
   listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
}

列表项插入

末尾插入

找到列表项最后一项,也就是xListEnd的previous指针指向列表项

步骤:

1、移动列表项指针,找到列表最终列表项的项值(xListEnd是首也是尾,最后一个列表项就是(xListEnd - 1))

2、改变新插入列表项的指针,previous指向(xListEnd - 1)与next指向(xListEnd )

3、改变(xListEnd - 1)的next指针

4、改变(xListEnd)的previous指针(xListEnd->privious 指向新插入的列表项)

5、标记列表项归属

6、列表的列表项数量自增(列表项的项值也要改变)

void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem )// 指定列表项要插入哪个列表,以及要插入的列表项
{
	ListItem_t * const pxIndex = pxList->pxIndex;	// 列表项索引,获取当前索引,
	pxNewListItem->pxNext = pxIndex;				// 新插入列表项 加入链表, pxNewListItem->pxNext 指向 xEnd
	pxNewListItem->pxPrevious = pxIndex->pxPrevious;// 新插入列表项 加入链表, pxNewListItem->pxPrev 指向 xEnd->pre 
	pxIndex->pxPrevious->pxNext = pxNewListItem;	// 改变 (xEnd - 1)的 next 指针,
	pxIndex->pxPrevious = pxNewListItem;			// 改变 xEnd 的 previous 指针
	pxNewListItem->pvContainer = ( void *) pxList;	// 新插入列表项的归属列表
	( pxList->uxNumberOfItems )++;					// 列表项数目自增
}

相当于是在 xListEnd 前面插入一个新的列表项(改变 xListEnd的pre指针)

一共需要改变四个指针,新插入的列表项的per和next指针,之(xListEnd - 1)的next指针,xListEnd的pre指针

pxIndex 值是第0个列表项,也是最后一个列表项(双向列表) xListEnd,通过next指针遍历链表

升序插入

通过列表项项值xItemValue比对,查找插入位置

步骤:

1、通过要插入的列表项的项值,找到要插入列表项的前一个列表项( 项值 - 1)

2、改变(项值 - 1)的next指针,新插入列表项的previous指针,新插入列表项的next指针

3、改变(项值 + 1)的previous指针

4、标记新插入列表项归属列表

5、列表的列表项数量自增

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后,改变 xListEnd.pxPrevious
	}
	else
	{
		for (	pxIterator = ( ListItem_t * ) &( pxList->xListEnd );// 索引从链表最后开始往前索引
				pxIterator->pxNext->xItemValue <= xValueOfInsertion;// 通过next索引,与要插入列表项值比较
				pxIterator = pxIterator->pxNext )					// 移动next指针进行索引
		{
			// xValueOfInsertion > pxIterator->pxNext->xItemValue,即pxIterator为要插入列表项位置前一个
		}
	}
	pxNewListItem->pxNext = pxIterator->pxNext;			// 改变要插入列表项的 next 指针
	pxNewListItem->pxNext->pxPrevious = pxNewListItem;	// 改变要插入列表项的 prev 指针
	pxNewListItem->pxPrevious = pxIterator;				// 
	pxIterator->pxNext = pxNewListItem;

	pxNewListItem->pvContainer = ( void * ) pxList;		// 通过pvContainer标记列表项属于哪个列表
	( pxList->uxNumberOfItems )++;						// 列表的列表项数目自增
}

删除

步骤:

1、设置要删除列表项(项值 - 1)的next指针

2、设置要删除列表项(项值 + 1)的previous指针

3、清空要删除列表项的previous与next指针

4、清除列表项归属列表标记

5、列表项数量自减

void vListDelete( List_t * const pxList, ListItem_t * const pxNewListItem )
{
   ListItem_t presentListItem;				// 使用临时列表项遍历列表项
   presentListItem = pxList->pxIndex;		// 获取当前列表项,此时为xListEnd

   if( pxNewListItem->xItemValue == portMAX_DELAY)	// 当前索引位置为链表最后位置
   {
   	  presentListItem->xItemValue = pxList->pxIndex;	// 直接插入最后
   }
   else
   {
   	for( presentListItem->xItemValue = pxList->pxIndex;				/* 从起始列表项开始*/
   		 presentListItem->xItemValue = pxNewListItem->xItemValue;	/* 当列表项匹配就结束*/
   		  presentListItem = presentListItem->next);					/* 移动next指针*/
   }
   presentListItem->pxPrevious->pxNext = pxList->pxIndex;				// 要删除节点 前一个的next指针
   presentListItem->pxNext->pxPrevious = presentListItem->pxPrevious;	// 要删除节点 下一个的prev指针
   presentListItem->pxNext = NULL;										// 要删除节点自己的指针
   presentListItem->pxPrevious = NULL;

   presentListItem->pvContainer = NULL;
   pxList->xItemValue--;
}

任务的执行由系统来调度,为了调度任务每个任务都会定义一个任务控制块,这个任务控制块相当于任务的身份证,保存有任务的所有信息

系统堆任务的全部操作都是通过任务控制块来实现的

任务块中的列表项,都标记有归属列表,通过列表可以遍历所有的列表项

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

1. 列表和列表项 的相关文章

  • 二维相机能得到三维信息?机器人感知部分之Aruco标定板的使用

    大家好 xff0c 我是小鱼 xff0c 今天来介绍一下Aruco并是结合ROS来进行识别 aruco其实是opencv中的一个库 xff0c 可以将特定的标记物转换成三维的坐标 xff0c 所以它是可以脱离ROS进行使用的 aruco介绍
  • 《动手学ROS2》扩展阅读2:ROS2客户端库RCL介绍

    本系列教程作者 xff1a 小鱼 公众号 xff1a 鱼香ROS QQ交流群 xff1a 139707339 教学视频地址 xff1a 小鱼的B站 完整文档地址 xff1a 鱼香ROS官网 版权声明 xff1a 如非允许禁止转载与商业用途
  • 《动手学ROS2》5.8Action客户端Python实现

    本系列教程作者 xff1a 小鱼 公众号 xff1a 鱼香ROS QQ交流群 xff1a 139707339 教学视频地址 xff1a 小鱼的B站 完整文档地址 xff1a 鱼香ROS官网 版权声明 xff1a 如非允许禁止转载与商业用途
  • 《动手学ROS2》6.5Gazebo介绍

    本系列教程作者 xff1a 小鱼 公众号 xff1a 鱼香ROS QQ交流群 xff1a 139707339 教学视频地址 xff1a 小鱼的B站 完整文档地址 xff1a 鱼香ROS官网 版权声明 xff1a 如非允许禁止转载与商业用途
  • Pixhawk无人机精准降落

    转自 xff1a http blog sina com cn s blog 6266a8840102xa77 html 多标记识别 xff0c 比官方的IR LOCK还要灵活 xff1a
  • 三位数的IMU长什么样?二位数的呢?不要钱的呢?| 为FishBot配置IMU惯性测量单元

    大家好 xff0c 我是小鱼 xff0c 上节课通过配置两轮差速控制器我们已经成功的让fishbot在gazebo中动了起来 xff0c 本节课我们通过给fishbot的URDF配置IMU传感器插件 xff0c 让IMU模块工作起来 1 惯
  • 本文之后,再无ROS安装问题 | 10分钟在Windows搭建好ROS开发环境

    很多新手刚开始学习ROS的时候因为用不惯Linux xff0c 加上安装虚拟机的各种和安装ROS的时候各种难受的折腾 xff0c 看着挺让人心疼 xff0c 所以本篇文章主要针对Windows上利用Docker和各种奇淫技巧让你轻松在Win
  • YoloV5+ROS2直接发布出物品坐标

    大家好 xff0c 我是秃头了依然在敲代码的小鱼 最近小鱼又整了一个开源库 xff0c 结合YOLOV5订阅图像数据和相机参数 xff0c 直接给出一个可以给出识别物品的坐标信息 xff0c 方便进行识别和抓取 xff0c 目前适配完了2D
  • IKFAST太难配?小鱼OpenRave的Docker镜像分享给你!

    大家好 xff0c 我是倒腾了一天机械臂的小鱼 众所周知 xff0c moveit自带的求解器 xff0c 使用的是数值解 xff0c 求解结果稳定性是要看人品的 xff0c 不过Moveit支持通过配置来更换求解器 xff0c 目前比较公
  • 小鱼的一键安装系列

    小鱼的一键安装系列 鱼香ROS介绍 xff1a 鱼香ROS是由机器人爱好者共同组成的社区 xff0c 欢迎一起参与机器人技术交流 进交流群请加机器人小伊微信 xff1a fishros2048 文章信息 xff1a 标题 xff1a 小鱼的
  • ubuntu18.04 ros-melodic 在安装ros依赖包时总是出现E软件包无法定位

    ubuntu18 04 ros melodic 在安装ros依赖包时总是出现E软件包无法定位 鱼香ROS介绍 xff1a 鱼香ROS是由机器人爱好者共同组成的社区 xff0c 欢迎一起参与机器人技术交流 进交流群请加机器人小伊微信 xff1
  • 树莓派4B(Pi buster)一键安装apt存在问题,WARNING: apt does not have a stable CLI interface

    树莓派4B xff08 Pi buster xff09 一键安装apt存在问题 xff0c WARNING apt does not have a stable CLI interface 鱼香ROS介绍 xff1a 鱼香ROS是由机器人爱
  • ROS1/ROS2版本代号

    ROS1 ROS2版本代号 鱼香ROS介绍 xff1a 鱼香ROS是由机器人爱好者共同组成的社区 xff0c 欢迎一起参与机器人技术交流 进群加V xff1a fishros2048 文章信息 xff1a 标题 xff1a ROS1 ROS
  • 一键安装失败

    一键安装失败 鱼香ROS介绍 xff1a 鱼香ROS是由机器人爱好者共同组成的社区 xff0c 欢迎一起参与机器人技术交流 进群加V xff1a fishros2048 文章信息 xff1a 标题 xff1a 一键安装失败 原文地址 xff
  • 在ROS 2中使用QT,显示话题内容,详细配置代码

    功能包类型选ament cmake xff0c 核心代码是这两句 xff0c 把spin单独出来 xff0c 不然接收不到话题数据 std thread spin thread listener gt void rclcpp spin li
  • 进程切换-

    实验课之前有一些问题 中断机制 第一个问题 xff1a interrupt的两个状态源头 xff1a 外中断多由随机中断 xff08 异步中断 xff09 造成 xff0c 如鼠标点击 xff0c 键盘输入 xff1b 内终端多由故障终端
  • 前后端分离项目 — 基于SpringSecurity OAuth2.0用户认证

    1 前言 现在的好多项目都是基于APP移动端以及前后端分离的项目 xff0c 之前基于Session的前后端放到一起的项目已经慢慢失宠并淡出我们视线 xff0c 尤其是当基于SpringCloud的微服务架构以及Vue React单页面应用
  • Android Studio com.android.support:percent 导入错误

    看第一行代码 xff08 第二版的 xff09 书 xff0c 讲了一个关于PercentFrameLayout和PercentRelativeLayout的部分 xff0c 书上在build gradle中导入了com android s
  • BS_TYPEMASK 重定义

    问题来源 CButtonST从VC6移植到VS2008的时候 xff0c 会提示下面语句重定义 span class token macro property span class token directive keyword defin
  • Ubuntu安装python

    CentOS 安装 Python3 没什么坑 xff0c 按照步骤一步步来就可以了 但 Ubuntu 安装 Python3 的坑却不少 xff0c 这里总结一下 xff0c 避免以后继续踩坑 我用的是 ubuntu16 04 xff0c 安

随机推荐

  • 【深度学习】Pytorch中cv2的错误 TypeError: Expected Ptr<cv::UMat> for argument ‘img‘

    错误出现的原因应该为数据之间出了冲突 xff0c 需要在某些地方调用 copy 函数 当我查看画框后的原图和旋转后的图片时 xff0c 发现它只是旋转的原图 xff0c 而不是将原图直接拷贝一份再旋转 下面为代码 xff1a import
  • PX4飞控开发——环境配置及编译ubuntu18.04

    PX4飞控学习过程 xff08 随着学习不断更新 xff0c 欢迎讨论 xff09 一 安装时遇到的问题二 添加环境变量及编译三 解決E 无法获得锁 var lib dpkg lock frontend open 11 资源暂时不可用 的問
  • PX4飞控试炼之路

    PX4飞控试炼之路 一 地面站控制台上显示输出 Hello Sky 二 利用飞控计算加法三 飞控按指定频率计数 xff0c 并将计数结果反馈到控制台1 利用while循环实现计数2 利用 96 hrt call every 96 周期回调函
  • 解决电脑wlan被禁用无法再启动的办法.

    快捷键ctrl 43 alt 43 delete打开任务管理器 gt 选择服务 gt 左下角打开服务 gt 找到WLAN AutoConfig右键 gt 选择重新启动 xff0c 然后Ok了
  • 关于虚拟机ubuntu编译程序时报make: warning: Clock skew detected. Your build may be incomplete.问题的解决办法

    关于ubuntu虚拟机编译程序时报make warning Clock skew detected Your build may be incomplete 问题的解决办法 xff1a 我在ubuntu虚拟的arm linux gcc上编译
  • 解决rosbag时间戳未对齐的解决方法

    解决rosbag时间戳未对齐的解决方法 Reference ROS org rosbag Cookbook http wiki ros org rosbag Cookbook rosbag在存储时间时 xff0c 接收消息的时间和生成消息的
  • ROS+python控制小乌龟走方形的实现rospy

    常见的简陋的控制乌龟行走方形的方式很简单 xff0c 例如 xff1a 代码有些地方是测试用的 xff0c 可以不要 usr bin env python from pickle import TRUE import rospy from
  • C++ STL算法

    C 43 43 STL算法 1 非修正序列算法1 1 adjacent find first last 1 2 count first last val 2 修正序列算法2 1 random shuffle first last 2 2 p
  • git子模块的修改和更新操作

    Reference git子模块的修改和更新操作 1 子库与父库 git关于子模块的官方文档链接 xff1a https git scm com book zh v2 Git E5 B7 A5 E5 85 B7 E5 AD 90 E6 A8
  • CMakeLists Option使用简介

    CMakeLists Option使用简介 1 基本格式2 示例3 基本用法4 C程序条件编译5 次项目之间选项的关系 Reference xff1a CMake之Option使用简介 CMake中的option用于控制编译流程 xff0c
  • 四轴一键起飞定高定点悬停伪代码

    四轴飞行器一键起飞定高 xff0c 降落 xff0c 光流定点悬停控制算法伪代码 基于飞控系统的二次开发
  • 开源飞控地面站 Openpilot GCS (现在的Librepilot GCS)源码分析  (2)地图插件

    xff08 xff11 xff09 OpenPilot项目中有地图显示模块 xff08 xff12 xff09 地图显示模块的插件是 xff1a opmap插件 xff0c 位置是src gt plugins gt opmap xff08
  • ubuntu 下运行程序报错 对‘std::cout’未定义的引用:gcc与g++的区别

    目录 1 问题提出 2 gcc与g 43 43 的区别 2 1 预处理 2 2 编译 2 3 汇编 2 4 链接运行 3 总结 1 问题提出 linux初学 xff0c 写了个例程 xff0c 用gcc o编译时出现以下问题 xff1a 后
  • 2.2 开启调度器

    开启调度器 void vTaskStartScheduler void BaseType t xReturn if configSUPPORT STATIC ALLOCATION 61 61 1 静态创建空闲任务 StaticTask t
  • 4. 消息队列

    消息队列 队列又称消息队列 xff0c 常用于任务间通信的数据结构 xff0c 可以在任务与任务之间 xff0c 中断与任务之间传递消息 xff0c 实现任务接收来自其他任务或中断的不固定长度的消息 任务可从消息队列中读取消消息 xff0c
  • 网卡接口

    网络接口 网络接口 xff08 以太网 xff09 是硬件接口 xff0c LwIP是软件 xff0c 并且网卡也是由很多种的 LwIP使用一个数据结构 xff0c nitif来描述网卡 用户提供最底层的接口函数 xff0c LwIP则提供
  • 系统扇区

    系统结构 DBR xff0c 主引导记录 xff1b DPT xff0c 分区表 xff1b DBR xff0c 分区引导扇区 引导扇区 MBR Main Boot Record xff0c 主引导扇区 xff0c 硬盘主引导记录区 xff
  • 华为3COM交换机配置命令详解

    1 配置文件相关命令 Quidway display current configuration 显示当前生效的配置 Quidway display saved configuration xff1b 显示flash中配置文件 xff0c
  • 分区结构

    分区结构 DBR xff0c 引导记录区 xff0c 包括一个引导程序和一个BPB xff0c 即本分区参数记录表 系统可直接访问的第一个扇区 xff0c 大小为512个字节 xff08 特殊情况占用其他保留扇区 xff09 512字节中
  • 1. 列表和列表项

    列表和列表项 列表 列表是一个数据结构 xff0c 用来追踪任务 xff0c 列表中有一个指针指向列表项 列表是一个结构体 xff0c 内部携带一个指针 xff0c 指针指向列表项 xff0c 列表项形成双向链式结构挂载在列表下 一个列表下