物联网操作系统学习笔记——列表及列表项

列表及列表项概念及其应用

列表和列表项
任务调度列表介绍
在这里插入图片描述
其他组件列表介绍
在这里插入图片描述
双向链表结构
1:插入与删除效率高,只要操作一次就能完成。
2:对数据的管理更加灵活与便捷,有利于编写逻辑清晰的程序。
在这里插入图片描述
列表与列表项
在这里插入图片描述
freeRTOS列表操作API
vListInitialise()
在这里插入图片描述
vListInitialiseItem()
在这里插入图片描述
vListInsert()
在这里插入图片描述
vListInsertEnd()
在这里插入图片描述
uxListRemove()
在这里插入图片描述
列表及列表项函数应用
功能需求
在这里插入图片描述
功能业务划分
在这里插入图片描述

void Delay_Task(void const * argument)
{
  /* USER CODE BEGIN Delay_Task */
	EventBits_t KeyEventBits;

	uint8_t	index;
	static uint8_t record = 0;
	ListItem_t* pListItem;
	
	/*
		1、列表及列表项初始化
	*/
	vListInitialise(&ListTest);
	for(index=0;index<ITEM_NUMBER;index++){
	
		vListInitialiseItem(&ListItemTest[index]);
		ListItemTest[index].xItemValue = index;
	
	}	
  /* Infinite loop */
  for(;;)
  {
	  /*
		1、修改事件标志组等待状态为 触发后清除标志
		2、检测按键,处理相关功能
	  
	  */
	  KeyEventBits = xEventGroupWaitBits(KeyEventGroup,
								KEY3_EVENT_BIT|KEY4_EVENT_BIT|KEY5_EVENT_BIT|KEY6_EVENT_BIT,
								pdTRUE,
								pdFALSE,
								portMAX_DELAY);
	  printf("Key is Down Key Event Bit is %x\r\n",KeyEventBits);
	  switch(KeyEventBits){
		  case KEY3_EVENT_BIT:
			  /*
				当列表项在范围内,允许插入
				插入完毕后,记录值record加一
			  */
			  if(record < ITEM_NUMBER){
				vListInsert(&ListTest,&ListItemTest[record++]);
			  }
			  else{
				printf("plese press K4 remove!\r\n");
			  }
				
			break;
		  case KEY4_EVENT_BIT:
			  /*
				当记录值有效时,允许移除
				插入完毕后,记录值record减一
			  */
			  if((record != 0)&&(record <= ITEM_NUMBER)){
				uxListRemove(&ListItemTest[--record]);
			  }
			  else{
				printf("plese press K3 insert!\r\n");
			  }
							  
			break;		 
		  case KEY5_EVENT_BIT:
			  /*
				1、打印有效列表项地址
				2、打印有效列表项(ItemValue)
				3、打印有效列表项前节点地址
				4、打印有效列表项后节点地址
			*/
			 for(pListItem = ListTest.xListEnd.pxNext;pListItem != (ListItem_t*)&ListTest.xListEnd;pListItem=pListItem->pxNext){
			 
				printf("pListItem addr = %x\r\n",pListItem);
				printf("pListItem item value = %d\r\n",pListItem->xItemValue);
				printf("pListItem previous addr = %x\r\n",pListItem->pxPrevious);
				printf("pListItem next addr = %x\r\n",pListItem->pxNext);
			 
			 }
			break;	  
		  default:
			  break;
	  
	  
	  }
		osDelay(10);
  }
  /* USER CODE END Delay_Task */
}

列表及列表项数据结构
在这里插入图片描述
列表初始化
在这里插入图片描述

/*
	列表项结构体原型
*/
struct xLIST_ITEM
{
	//列表项值 -----一般用于排序
	configLIST_VOLATILE TickType_t xItemValue;			/*< The value being listed.  In most cases this is used to sort the list in descending 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. */
	//当前列表项归属的列表
	void * configLIST_VOLATILE pvContainer;				/*< Pointer to the list in which this list item is placed (if any). */
};
typedef struct xLIST_ITEM ListItem_t;					/* For some reason lint wants this as two separate definitions. */

struct xMINI_LIST_ITEM
{
	//列表项值
	configLIST_VOLATILE TickType_t xItemValue;
	//指向下个节点地址
	struct xLIST_ITEM * configLIST_VOLATILE pxNext;
	//指向上一个节点地址
	struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
};
typedef struct xMINI_LIST_ITEM MiniListItem_t;

/*
 * Definition of the type of queue used by the scheduler.
 */
typedef struct xLIST
{
	//列表内有效列表项个数
	configLIST_VOLATILE UBaseType_t uxNumberOfItems;
	//列表遍历时用到的索引
	ListItem_t * configLIST_VOLATILE pxIndex;			/*< Used to walk through the list.  Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */
	//列表尾节点
	MiniListItem_t xListEnd;							/*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
} List_t;

列表项初始化
在这里插入图片描述

/*
	列表初始化
	参数:指向列表的指针

*/
void vListInitialise( List_t * const pxList )
{
	/* 索引地址指向尾节点 */
	pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd );			/*lint !e826 !e740 The mini list structure is used as the list end to save RAM.  This is checked and valid. */

	/* 
		尾节点初始化
		1、value = 最大值,按序排列在最后面
		2、pxNext、pxPrevious都指向尾节点本身,表示列表为空


	*/
	pxList->xListEnd.xItemValue = portMAX_DELAY;
	pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );	/*lint !e826 !e740 The mini list structure is used as the list end to save RAM.  This is checked and valid. */
	pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*lint !e826 !e740 The mini list structure is used as the list end to save RAM.  This is checked and valid. */
	//当前有效的列表个数为0
	pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
}
/*
	列表项初始化
	参数:指向列表项的指针

*/
void vListInitialiseItem( ListItem_t * const pxItem )
{
	/*列表项初始化不归属任务列表所有 */
	pxItem->pvContainer = NULL;
}

列表及列表项插入
列表项按序插入
在这里插入图片描述

/*
	有序插入列表项
	参数:
		1、指向列表的指针
		2、指向列表项的指针

*/
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
	{
		//从尾节点开始遍历,然后与下个节点的Value值进行比较,当要插入Value值大于遍历列表项Value时,就获得插入位置
		for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM.  This is checked and valid. */
		{
		
		}
	}
	//更新后面节点信息 (前后指针进行赋值)
	pxNewListItem->pxNext = pxIterator->pxNext;
	pxNewListItem->pxNext->pxPrevious = pxNewListItem;
	//更新前面节点信息(前后指针进行赋值)
	pxNewListItem->pxPrevious = pxIterator;
	pxIterator->pxNext = pxNewListItem;

	/* 把列表项归属于当前的列表 */
	pxNewListItem->pvContainer = ( void * ) pxList;
	/* 有效列表项数量进行累加 */
	( pxList->uxNumberOfItems )++;
}

列表项尾部插入
在这里插入图片描述

/*
	尾部插入法
	参数:
		1、指向列表的指针
		2、指向列表项的指针
		跟尾节点,没有半毛钱关系,这个接口,只能用freertos使用,尾部插入,主要用于任务调度
*/
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->uxNumberOfItems )++;
}

列表项移除

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;

	/* Only used during decision coverage testing. */
	mtCOVERAGE_TEST_DELAY();

	/* 索引是否需要更新 */
	if( pxList->pxIndex == pxItemToRemove )
	{
		pxList->pxIndex = pxItemToRemove->pxPrevious;
	}
	else
	{
		mtCOVERAGE_TEST_MARKER();
	}
	//移除列表
	pxItemToRemove->pvContainer = NULL;
	//有效列表项数量减一
	( pxList->uxNumberOfItems )--;
	//返回当前列表的有效列表项数量
	return pxList->uxNumberOfItems;
}

FreeRTOS操作列表接口
在这里插入图片描述

在这里插入图片描述
深入理解调度器实现原理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值