Achieve FreeRTOS- linked list

A .C language list

As a basic list of data structures in the C language, the program used in the usual count is relatively low, but more often the operating system used in the linked list. The maximum effect is the list of discrete data can be linked together, and this is not the same array, the array of storage space is a contiguous memory, and the memory list can be discontinuous data link. The main learning list is a list of learning and nodes. The relationship between the list and the node is like the relationship between racks and hooks: The
Here Insert Picture Description
list is like the top of the hook, the node is like a small hook below, you can find all the little hook by hook above, is between nodes data can be mounted on each of the nodes connected to the first, so it can put a list a plurality of data together.

1. singly linked list

Singly linked list node itself must contain a node pointer, for pointing to the next node, the node may of course also carry other data. Node is a custom type of data structure may be a single data array, or a pointer to the data structure in the data node.
E.g:

struct node
{
 struct node *next; /* 指向链表的下一个节点 */
 
 /* 节点携带的数据可以是如下内容 */
 char data1; /* 单个的数据 */
 unsigned char array[]; /* 数组 */
 unsigned long *prt /* 指针数据 */
 struct userstruct data2; /* 自定义结构体类型数据 */
 /* 其他数据类型 */
 }

In the singly linked list, the pointer to the last node of the first node, the list is representative of the cycle, as shown:
Here Insert Picture Description

2. doubly linked list

Doubly linked list, and the difference is unidirectional: doubly linked list node has two pointers, pointing to a previous node and the node, and as the rest of the singly linked list.
Doubly linked list structure as shown:
Here Insert Picture Description

3. list and array

A node list is by linking the discrete data into a table by the node insertions and deletions in order to achieve access to the data. The array is through the creation of a contiguous memory to store data, which is the biggest difference between arrays and linked lists. Each member of the array corresponding to the linked list data type node, and the node member may be a standard type C or a user-defined structure. Array has start address and end address, and the list is a circle, without the head and tail points, but in order to facilitate insertion and deletion operations predetermined artificially a root node.

Two .FreeRTOS in the linked list implementation

1. Define node structure

List node data structure is defined as follows:

/* 定义节点的数据结构 */
struct xLIST_ITEM
{
	/* 辅助值,相当于节点的序号 */
	TickType_t xItemValue;
	/* 指向下一个节点 */
	struct xLIST_ITEM * pxNext;
	/* 指向前一个节点 */
	struct xLIST_ITEM * pxPrevious;
	/* 指向拥有该节点的内核对象,通常为TCB */
	void * pvOwner;
	/* 指向该节点所在的链表 */
	void * pvContainer;
};
/* 重定义节点数据类型 */
typedef struct xLIST_ITEM ListItem_t;

2. Define node streamlined structure

/* 定义链表精简节点结构体 */
struct xMINI_LIST_ITEM
{
	/* 辅助值,帮助节点做升序排序 */
	TickType_t xItemValue;
	/* 指向链表下一个节点 */
	struct xLIST_ITEM * pxNext;
	/* 指向节点前一个节点 */
	struct xLIST_ITEM * pxPrevious;
};
/* 重定义精简节点结构体 */
typedef struct xMINI_LIST_ITEM MiniListItem_t;

3. Define the root structure

/* 定义节点链表(根节点)的数据结构 */
typedef struct xLIST
{
	/* 链表节点计数器,记录链表中节点的个数 */
	UBaseType_t uxNumberOfItemsl;
	/* 链表节点索引指针,用于遍历节点 */
	ListItem_t * pxIndex;
	/* 链表最后一个节点,也是第一个节点,此节点数据结构是精简结构 */
	MiniListItem_t xListEnd;
}List_t;

4. Node Initialization

/* 链表节点初始化 */
void vListInitialiseItem( ListItem_t * const pxItem )
{
	/* 将节点指向的链表为空,表示节点还没有插入任何链表 */
	pxItem->pvContainer = NULL;
}

5. Initialization root

/* 链表根节点初始化 */
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->uxNumberOfItemsl = ( UBaseType_t ) 0;
}

6. node into the tail of the linked list

/* 将节点插入到链表尾部,即插入到最后一个节点的前面,充当最后节点 */
void vListInsertEnd( 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->uxNumberOfItemsl )++;
}

7. The node into a fixed position

/* 将节点按照升序插入到链表中,插在序号节点前面 */
/* 比如插入节点的序号为7,代表要插在链表原来的6与7之间,成为新的7号 */
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
	{
		/* 直到迭代节点是6号节点 */
		for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd );
					pxIterator->pxNext->xItemValue <= xValueOfInsertion;
					pxIterator = pxIterator->pxNext)
		{
			/* 什么都不做,不断迭代只为寻找节点要插入的位置 */
		}
	}
	
	/* 将节点插入到迭代节点后面,即插在6号节点后面 */
	pxNewListItem->pxNext = pxIterator->pxNext;
	pxNewListItem->pxNext->pxPrevious = pxNewListItem;
	pxNewListItem->pxPrevious = pxIterator;
	pxIterator->pxNext = pxNewListItem;
	
	/* 将插入的节点归入链表中 */
	pxNewListItem->pvContainer = ( void * ) pxList;
	/* 链表中节点数加一 */
	( pxList->uxNumberOfItemsl )++;
}

8. Delete Node

/* 将节点从链表删除,并返回链表中的剩余节点个数 */
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->uxNumberOfItemsl )--;
	/* 返回链表中剩余的节点个数 */
	return ( pxList->uxNumberOfItemsl );
}

III. Simulation

Run the following code, the relationship between the use of simulation test list node is correct, create a root node, three nodes, three nodes will be inserted in the list order.

#include "list.h"

/* 一个根节点 */
struct xLIST        List_Test;
/* 三个节点 */
struct xLIST_ITEM   List_Item_1;
struct xLIST_ITEM   List_Item_2;
struct xLIST_ITEM   List_Item_3;


int main(void)
{
	/* 初始化根节点 */
	vListInitialise( & List_Test );
	
	/* 初始化节点 */
	vListInitialiseItem( & List_Item_1 );
	List_Item_1.xItemValue = 1;
	vListInitialiseItem( & List_Item_2 );
	List_Item_2.xItemValue = 2;
	vListInitialiseItem( & List_Item_3 );
	List_Item_3.xItemValue = 3;

	/* 将节点插入到链表中 */
	vListInsert( & List_Test, & List_Item_1 );
	vListInsert( & List_Test, & List_Item_2 );
	vListInsert( & List_Test, & List_Item_3 );

	while( 1 )
	{
		;
	}
}

The simulation results are shown:

Here Insert Picture Description
From the results, a correspondence relationship between nodes is correct.

Published 62 original articles · won praise 188 · views 10000 +

Guess you like

Origin blog.csdn.net/qq_43743762/article/details/100167147