文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

FreeRTOS实时操作系统的列表与列表项操作示例

2024-04-02 19:55

关注

 

 

前言

FreeRTOS列表与列表项其实就是链表和节点,在list.clist.h实现

列表项数据结构

//列表项数据结构
typedef struct xLIST_ITEM
{
	TickType_t xItemValue;  //辅助值,用作节点做顺序排序
	struct xLIST_ITEM * pxNext;//后继指针
	struct xLIST_ITEM * pxPrevious;//前驱指针
	void * pvOwner;      //指向拥有该列表项的内核对象,通常是TCB
	void * pvContainer;  //指向该列表项所在的列表
}ListItem_t;

列表项初始化

void vListInitialiseItem(ListItem_t * const pxItem)
{
//初始化该列表项所在列表指针指向NULL,表示还没插入任何列表
		pxItem->pvContainer = NULL;
}

列表数据结构

typedef struct xLIST
{
	UBaseType_t uxNumberOfItems; //指示这条列表上有多少个列表项
	ListItem_t * pxIndex; //列表项索引指针
	MiniListItem_t xListEnd; //列表最后一个列表项
}List_t;

其中MiniListItem_t数据结构如下

typedef struct xMINI_LIST_ITEM
{
	TickType_t xItemValue;//辅助值,用作节点做顺序排序
	struct xLIST_ITEM * pxNext;//后继指针
	struct xLIST_ITEM * pxPrevious;//前驱指针
}MiniListItem_t;

可以看到是列表项数据结构去掉了pvOwnerpvContainer成员

列表初始化

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);	
	//表示此时列表中有0个列表项
	pxList->uxNumberOfItems = (UBaseType_t)0U;
}

如下图

在这里插入图片描述

将列表项插入列表尾部

void vListInsertEnd(List_t * const pxList,ListItem_t * const pxNewListItem)
{
    //取列表项索引指针,此时该指针指向最后一个节点
	ListItem_t * const pxIndex = pxList->pxIndex;
	//新插入的列表项前驱指针指向最后一个节点
	pxNewListItem->pxNext = pxIndex;
	//新插入的列表项的后继指针也指向最后一个节点
	pxNewListItem->pxPrevious = pxIndex->pxPrevious;
	//列表的最后一个节点的后继指针指向新插入的列表项
	pxNewListItem->pxPrevious->pxNext = pxNewListItem;
	//列表的最后一个节点的前驱指针也指向新插入的列表项
	pxIndex->pxPrevious = pxNewListItem;
	//新插入的列表项是输入该列表的
	pxNewListItem->pvContainer = (void*) pxList;
	 //该列表中列表项数目+1
	(pxList->uxNumberOfItems)++;
}

如下

在这里插入图片描述

将列表项按照升序排列插入到列表

假如向现有的2个列表项序辅助值分别是 1 和 3的列表插入辅助值是2个列表项

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)
			{
			}
	}
	//对于下图此时pxIterator指向List_item1
	//此时pxIterator->pxNext是List_item3地址
	pxNewListItem->pxNext = pxIterator->pxNext;//1
	//pxNewListItem->pxNext->pxPrevious是item3的前驱指针指向新列表项item2
	pxNewListItem->pxNext->pxPrevious = pxNewListItem;
	//新列表项item2的前驱指针指向pxIterator即item1
	pxNewListItem->pxPrevious = pxIterator;
	//pxIterator即item1的后继指向新列表项item2
	pxIterator->pxNext = pxNewListItem;
	pxNewListItem->pvContainer = (void*) pxList;
	(pxList->uxNumberOfItems)++;
}

如图,注意2、3步的指针箭头,野火的pdf画的有误

在这里插入图片描述

将列表项从列表删除

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;
	if(pxList->pxIndex == pxItemToRemove)
	{
			pxList->pxIndex = pxItemToRemove->pxPrevious;
	}
	//该列表项所有者置空
	pxItemToRemove->pvContainer = NULL;
	(pxList->uxNumberOfItems)--;
	return pxList->uxNumberOfItems;
}

下面是测试代码即仿真结果

List_t List_Test;
ListItem_t List_Item1;
ListItem_t List_Item2;
ListItem_t List_Item3;
int main(void)
{
	//初始化列表
    vListInitialise(&List_Test);
    //初始化列表项
    vListInitialiseItem(&List_Item1);
	List_Item1.xItemValue = 1;
    vListInitialiseItem(&List_Item2);
	List_Item2.xItemValue = 2;
    vListInitialiseItem(&List_Item3);
	List_Item3.xItemValue = 3;
    vListInsert(&List_Test,&List_Item1);
	vListInsert(&List_Test,&List_Item3);
	vListInsert(&List_Test,&List_Item2);
	while(1);
}

在这里插入图片描述

以上就是FreeRTOS实时操作系统的列表与列表项操作示例的详细内容,更多关于FreeRTOS列表与列表项操作的资料请关注编程网其它相关文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-人工智能
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯