最簡實時性操作系統之任務鏈表

在freertos中任務和就緒列表就像衣架一樣由根節點和節點那樣構成

實時性操作系統中鏈表的數據結構

鏈表

cpp 复制代码
/* 链表结构体定义 */
typedef struct xLIST
{
	UBaseType_t uxNumberOfItems;    /* 链表节点计数器 */
	ListItem_t *  pxIndex;			/* 链表节点索引指针 */
	MiniListItem_t xListEnd;		/* 链表最后一个节点 */
} List_t;

鏈表下面主要由

1.節點計數器,不包含節點

2.節點索引指針

3.根節點組成

其中根節點一般表示一個就緒任務集合還有阻塞任務集合,用以串聯起該任務的

1.輔助值用以升序排序,一般設爲最大值

2.根節點的前後指針

節點項

節點項可以表示一個任務

1.是輔助值用以升序排序

2.是節點項的上一項和下一項的指針

3.是TCB任務塊的指針

4.是所屬根節點

實時性操作系統中鏈表的操作函數

初始化鏈表

cpp 复制代码
//初始化一個根節點
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);
}

初始化節點

cpp 复制代码
//初始化一個節點
void vListInitialiseItem(ListItem_t * const pxItem)
{
	pxItem->pvContainer = NULL;
}

將節點插入鏈表的尾部

cpp 复制代码
void vListInserEnd(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)++;
}

聽著有點拗口,實際上一個鏈表長這樣 INDEX -> A -> B -> INDEX

INDEX是固定的,INDEX->pxPrevious表示當前鏈表的最後一項

1.首先將當前插入的項的前後相分別指向鏈表的頭相和尾項

2.然後解決之前鏈表的最後一項,讓它指向鏈表要新插入的相,因爲鏈表之前最後一項的上一項沒有變化所以不用改變

3.最後把鏈表相挂在在鏈表中,并且計數器加1

按順序將節點插入鏈表

cpp 复制代码
#include "list.h"

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)++;
}

講解如下:

向链表的尾部插入一个项_哔哩哔哩_bilibili

刪除一個鏈表

cpp 复制代码
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;
}
相关推荐
小羊没烦恼!1 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
rockmelodies1 天前
# Windows Server2008 R2 Standard(SP1镜像U盘)重置本地管理员密码【完整详细步骤】
windows·密码破解
kakakahahahaha2 天前
Windows C盘空间不足的安全清理与迁移流程
windows·电脑·笔记本电脑·软件需求·c盘清理
做咩啊~2 天前
远程连接提示:身份验证错误,要求的函数不受支持
windows
百事牛科技2 天前
PPT只读怎么取消?四种情况分别处理
windows·powerpoint
熊明才2 天前
WSL2 网络突然瘫痪(Network is unreachable / 没有 eth0)最短修复指南(2026年9月20日亲测可用)
linux·windows·wsl2
xbzb3 天前
Windows 启动故障修复知识整理:蓝屏 / 无限重启 / 盘符 X / 无 PE 盘
windows
我命由我123453 天前
Mac 操作系统 - 一些使用记录
运维·windows·学习·系统安全·运维开发·mac·学习方法
kakakahahahaha3 天前
Windows Steam 游戏存档在哪里?定位和恢复排查流程
windows·其他·电脑·笔记本电脑·内容运营·软件需求
Xy-unu3 天前
Windows 开启外接显示器 HDR 后外接显示器无信号、无法扩展模式故障记录
windows