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

在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;
}
相关推荐
李少兄3 小时前
Windows 11 环境下 BAT 脚本无法执行的排查与修复指南
windows
解道Jdon3 小时前
FigCraft把Figma用Rust从零重写了一遍
ide·windows·git·svn·eclipse·github·visual studio
zh73145 小时前
Docker Desktop on Windows 挂载问题根因分析
windows·docker·容器
Surpass-HC5 小时前
WSL2 windows-ubuntu
linux·windows·ubuntu
遇印记6 小时前
网络安全,数据链路层,物理层
运维·服务器·网络·windows·学习
mx_jun6 小时前
Wireshark 蓝牙 HCI 日志分析常用操作速查
windows·microsoft·hci·bt
艾iYYY7 小时前
思考: C++ 万能引用与完美转发
c++·windows·microsoft
小趴菜一只9 小时前
SIEM-wazuh安装过程
运维·windows·安全·网络安全
MOONICK9 小时前
COM 组件技术(三)
c++·windows
Source.Liu9 小时前
【A11】客户端登录流程笔记
windows·rust