Skip to content

数据结构

数据类型

portCHAR: char

portSHORT: short

portLONG: long

portTickType: unsigned short int, unsigned int用于系统计时器, 具体要看文件FreeRTOSConfig.h文件中宏configUSE_16_BIT_TICKS为1时为16位, 0为32位

portBASE_TYPE: long, 根据处理器架构界定

前缀

c: char

s: short

l: long

x: portBASE_TYPE

u: 无符号类型

p: 指针

函数名

包括前缀, 文件名, 函数名

宏的前缀是文件名

信号量的函数是一个宏定义, 但是是遵循函数名的命名方法

image-20230706103041491

列表和列表项

列表和列表项, 实际上就是链表和链表项

单链表: 本身包含一个节点指针, 指向后一个节点, 还可以包含一些私有信息, 通常内嵌一个节点, 会使用链表把零散的数据串联, 通常会设置一个根节点

双向链表: 有两个节点指针

c
struct xLIST_ITEM
{
    listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE           /*< Set to a known value if config 																			USE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1.辅助值 */
    configLIST_VOLATILE TickType_t xItemValue;          /*< The value being listed.  In most cases this is used to 														sort the list in ascending order. */
    struct xLIST_ITEM * configLIST_VOLATILE pxNext;     /*< Pointer to the next ListItem_t in the list. 指向后一个节													点*/
    struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. 指向前一													个节点*/
    void * pvOwner;                                     /*< Pointer to the object (normally a TCB) that contains 													the list item.  There is therefore a two way link between 													the object containing the list item and the list item 															itself. 指向拥有该节点的对象, 通常是PCB*/
    struct xLIST * configLIST_VOLATILE pxContainer;     /*< Pointer to the list in which this list item is placed 													(if any). */
    listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE          /*< Set to a known value if 																				configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
};
typedef struct xLIST_ITEM ListItem_t;                   /* For some reason lint wants this as two separate 	definitions. */
c
struct xLIST_ITEM
{
	TickType_t	xItemValue;				//辅助值
	struct xLIST_ITEN * pxNext;			//指向下一个节点
	struct xLIST_ITEN * pxPrevious;		//指向上一个节点
	void * pvOwner;				//指向拥有该节点的内核对象
	void * pvCountainer;		//指向节点所在的链表
};
typedef struct xLIST_ITEM ListItem_t;

//结尾节点
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 uxNumberOfItem;		//节点计数器
	ListItem_t	* pxIndex;			//链表节点索引
	MiniListItem_t xListEnd;		//最后一个节点
}List_t;

定义三中节点

image-20230706112438094

初始化根节点

c
//根节点初始化函数
void vListInitialist(List_t * const pxList)
{
	pxList->pxIndex = (ListItem_t *) & (pxList->xListEnd);		//索引指向最后一个节点
	pxList->xListEnd.xItemValue = portMAX_DELAY;//最后一个节点的数字指向最大
	pxList->xListEnd.pxNext = (ListItem_t *) &(pxList->xListEnd);//最后节点pxNext和pxPrevious指向自身
	pxList->xListEnd.pxPrevious = (ListItem_t *) &(pxList->xListEnd);
	pxList->uxNumberOfItem = (UBaseType_t)0U;		//设置节点的数量为0
}

image-20230706113548330

c
//把一个空的链表插入到尾部
void vListInsertEnd(List_t * const pxList, ListItem_t * const pxNewListItem)
{
	ListItem_t * const pxIndex = pxList->pxIndex;	//获得最后一个节点的指针, 转换为ListItem类型
	
	pxNewListItem->pxNext = pxIndex;		//新节点最后指向末尾的节点
	pxNewListItem->pxPrevious = pxIndex->pxPrevious;	//前一个节点指向末尾结点的前一个节点
	pxIndex->pxPrevious->pxNext = pxNewListItem;	//之前的倒数第二个节点指向自己
	pxIndex->pxPrevious = pxNewListItem;	//末尾结点前一个节点指向自己
	
	(pxList->uxNumberOfItem)++;
}

image-20230706122402274

按照值的大小进行插入

c
//按照数字的大小进行插入
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->pvCountainer = (void *)pxList;

	(pxList->uxNumberOfItem)++;
}

image-20230706124423375

c
//移除一个链表
UBaseType_t uxListRemove(ListItem_t * const pxItemToRemov)
{
	//获取链表的节点
	List_t * const pxList = (List_t *)pxItemToRemov->pvCountainer;
	
	
	pxItemToRemov->pxNext->pxPrevious = pxItemToRemov->pxPrevious;
	pxItemToRemov->pxPrevious->pxNext = pxItemToRemov->pxNext;
	
	if(pxList->pxIndex == pxItemToRemov)
	{
		//如果删除的最后的节点把他设置为现在数字最大的节点(前一个)
		pxList->pxIndex = pxItemToRemov->pxPrevious;
	}
	pxItemToRemov->pvCountainer = NULL;
	(pxList->uxNumberOfItem)--;
	
	return pxList->uxNumberOfItem;
}
  • 一些宏定义
c
//初始化节点拥有者
#define liseSET_LIST_ITEM_OWNER(pxListItem, pxOwner) 	((pxListItem->pvOwner)=(void *)(pxOwner))
//获得节点的拥有者
#define listGET_ITEM_ITEM_OWNER(pxListItem)  			(pxListItem->pvOwner)
//初始化节点的排序辅助值
#define liseSET_LIST_ITEM_VALUE(pxListItem, xValue) 	((pxListItem)->xItemValue)=xValue
//获取链表根节点的计数器值
#define liseGET_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 )->uxNumberOfItems )
/* 获取链表节点的OWNER,即TCB */
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList )										\
{																							\
	List_t * const pxConstList = ( pxList );											    \
	/* 节点索引指向链表第一个节点调整节点索引指针,指向下一个节点,
    如果当前链表有N个节点,当第N次调用该函数时,pxInedex则指向第N个节点 */\
	( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;							\
	/* 当前链表为空 */                                                                       \
	if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) )	\
	{																						\
		( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;						\
	}																						\
	/* 获取节点的OWNER,即TCB */                                                             \
	( pxTCB ) = ( pxConstList )->pxIndex->pvOwner;											 \
}
#define listGET_OWNER_OF_HEAD_ENTRY( pxList )  ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner )

image-20230709102454093