freertos 双向循环链表插入删除的实现与直观理解
2022-01-28 22:07 jym蒟蒻 阅读(767) 评论(0) 收藏 举报freertos 双向循环链表插入删除的实现与直观理解
- main.c
- list.h
- 其他头文件
- FreeRTOS.h
- FreeRTOSConfig.h
- portable.h
- portmacro.h
- list.c
- vListInsertEnd函数
- vListInsert函数
- uxListRemove函数
用debug之后,查看观察窗口,结果如下。这个实验目的就是,建一个根节点,三个普通节点的链表,并且这三个普通节点按照xitemValue的值进行升序排列。

main.c里面
首先看节点的类型:链表根节点类型是xLIST、普通节点类型是xLIST_ITEM。
然后看main函数:vListInitialise这个是链表根节点初始化函数、vListInitialiseItem这个是普通节点初始化函数、xItemValue这个是普通节点里面的成员变量、vListInsert这个函数实现将节点插入链表,按照升序排列功能。
接下来分别研究上面这些东西。
#include "list.h"
/* 定义链表根节点 */
struct xLIST       List_Test;
/* 定义节点 */
struct xLIST_ITEM  List_Item1;
struct xLIST_ITEM  List_Item2;
struct xLIST_ITEM  List_Item3;
int main(void)
{	
	
    /* 链表根节点初始化 */
    vListInitialise( &List_Test );
    
    /* 节点1初始化 */
    vListInitialiseItem( &List_Item1 );
    List_Item1.xItemValue = 1;
    
    /* 节点2初始化 */    
    vListInitialiseItem( &List_Item2 );
    List_Item2.xItemValue = 2;
    
    /* 节点3初始化 */
    vListInitialiseItem( &List_Item3 );
    List_Item3.xItemValue = 3;
    
    /* 将节点插入链表,按照升序排列 */
    vListInsert( &List_Test, &List_Item2 );    
    vListInsert( &List_Test, &List_Item1 );
    vListInsert( &List_Test, &List_Item3 );    
    
    for(;;)
	{
		/* 啥事不干 */
	}
}
直接看下面这个图,就可以知道根节点结构体和其他节点结构体里面的成员变量了。

#ifndef LIST_H
#define LIST_H
#include "FreeRTOS.h"
/* 节点结构体定义 */
struct xLIST_ITEM
{
	TickType_t xItemValue;             /* 辅助值,用于帮助节点做顺序排列 */			
	struct xLIST_ITEM *  pxNext;       /* 指向链表下一个节点 */		
	struct xLIST_ITEM *  pxPrevious;   /* 指向链表前一个节点 */	
	void * pvOwner;					   /* 指向拥有该节点的内核对象,通常是TCB (用于表示该节点内嵌在哪个数据结构中)*/
	void * pvContainer;		           /* 指向该节点所在的链表,通常指向链表的根节点*/
};
typedef struct xLIST_ITEM ListItem_t;  /* 节点数据类型重定义 */
/* mini节点结构体定义,作为双向链表的结尾
   因为双向链表是首尾相连的,头即是尾,尾即是头 */
struct xMINI_LIST_ITEM
{
	TickType_t xItemValue;                      /* 辅助值,用于帮助节点做升序排列 */
	struct xLIST_ITEM *  pxNext;                /* 指向链表下一个节点 */
	struct xLIST_ITEM *  pxPrevious;            /* 指向链表前一个节点 */
};
typedef struct xMINI_LIST_ITEM MiniListItem_t;  /* 最小节点数据类型重定义 */
/* 链表结构体定义 */
typedef struct xLIST
{
	UBaseType_t uxNumberOfItems;    /* 链表节点计数器,用于表示该链表下有多少个节点,根节点除外*/
	ListItem_t *  pxIndex;			/* 链表节点索引指针,用于遍历节点 */
	MiniListItem_t xListEnd;		/* 链表最后一个节点 */
} List_t;
/*
************************************************************************
*                                宏定义
************************************************************************
*/
/* 初始化节点的拥有者 */
#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner )		( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) )
/* 获取节点拥有者 */
#define listGET_LIST_ITEM_OWNER( pxListItem )	( ( pxListItem )->pvOwner )
/* 初始化节点排序辅助值 */
#define listSET_LIST_ITEM_VALUE( pxListItem, xValue )	( ( pxListItem )->xItemValue = ( xValue ) )
/* 获取节点排序辅助值 */
#define listGET_LIST_ITEM_VALUE( pxListItem )	( ( pxListItem )->xItemValue )
/* 获取链表根节点的节点计数器的值 */
#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList )	( ( ( pxList )->xListEnd ).pxNext->xItemValue )
/* 获取链表的入口节点 */
#define listGET_HEAD_ENTRY( pxList )	( ( ( pxList )->xListEnd ).pxNext )
/* 获取链表的第一个节点 */
#define listGET_NEXT( pxListItem )	( ( pxListItem )->pxNext )
/* 获取链表的最后一个节点 */
#define listGET_END_MARKER( pxList )	( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) )
/* 判断链表是否为空 */
#define listLIST_IS_EMPTY( pxList )	( ( BaseType_t ) ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) )
/* 获取链表的节点数 */
#define listCURRENT_LIST_LENGTH( pxList )	( ( pxList ) 
                     
                    
                