欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

FreeRTOS源代码分析 - List.c 学习笔记

程序员文章站 2022-07-06 18:00:54
...

FreeRTOS中list.c包含4个函数,
其中功能如下:
void vListInitialise( List_t * const pxList ) PRIVILEGED_FUNCTION;
链表根节点初始化
void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION;
链表节点初始化
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
将节点按照升序排列插入到链表
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
将节点插入到链表的尾部
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION;
将节点从链表删除

链表根节点初始化

注意:
listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ); /新增加的部分,用来检测完整性/
listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ); /新增加的部分,用来检测完整性/
在list.h中定义的宏,如果成员不包括目标值则assert

void vListInitialise( List_t * const pxList )
{
	/* 将链表索引指针指向最后一个节点 */
	pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd );			/*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM.  This is checked and valid. */

	/* 将链表最后一个节点的辅助排序的值设置为最大,确保该节点就是链表的最后节点 */(
	pxList->xListEnd.xItemValue = portMAX_DELAY;

	/* 将最后一个节点的pxNext和pxPrevious指针均指向节点自身,表示链表为空 */
	pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );	/*lint !e826 !e740 !e9087 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 !e9087 The mini list structure is used as the list end to save RAM.  This is checked and valid. */
	/* 初始化链表节点计数器的值为0,表示链表为空 */(
	pxList->uxNumberOfItems = ( UBaseType_t ) 0U;

	/* Write known values into the list if
	configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
	listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );		/*新增加的部分,用来检测完整性*/
	listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );		/*新增加的部分,用来检测完整性*/
}

FreeRTOS源代码分析 - List.c 学习笔记

链表节点初始化

注意:
/*果List_DATA_INTEGRITY_CHECK_BYTES值设置为1,则设置为一个已知的值. */
listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
在list.h中定义的宏,如果成员不包括目标值则assert

void vListInitialiseItem( ListItem_t * const pxItem )
{
	/* 初始化该节点所在的链表为空,表示节点还没有插入任何链表 */
	pxItem->pxContainer = NULL;

	/*果List_DATA_INTEGRITY_CHECK_BYTES值设置为1,则设置为一个已知的值. */
	listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
	listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
}
/*-----------------------------------------------------------*/

FreeRTOS源代码分析 - List.c 学习笔记

将节点按照升序排列插入到链表

注意:
/* 仅当还定义了configASSERT()时,这些测试才有效列表数据结构在内存中被覆盖。 他们不会抓住
错误配置或使用FreeRTOS导致数据错误. */
listTEST_LIST_INTEGRITY( pxList );
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
注意:vListInsert这里崩溃的话,注意以下:
果您发现您的应用程序在此处崩溃,则可能的原因是
下面列出。此外,请参阅https://www.freertos.org/FAQHelp.html,以了解更多技巧,并确保已定义configASSERT()!
https://www.freertos.org/a00110.html#configASSERT
1)堆栈溢出-
参见https://www.freertos.org/Stacks-and-stack-overflow-checking.html
2)错误的中断优先级分配,尤其是在Cortex-M上
数字高优先级值表示低实际值的部分
中断优先级,这似乎很不直观。看到
https://www.freertos.org/RTOS-Cortex-M3-M4.html及其定义
上的configMAX_SYSCALL_INTERRUPT_PRIORITY
https://www.freertos.org/a00110.html
3)在关键区域内或何时调用API函数
调度程序已暂停,或调用了
不能以“ FromISR”结尾。
4)在初始化之前使用队列或信号量或
在调度程序启动之前(是否触发中断)
在vTaskStartScheduler()被调用之前?)。

****************************************************** ******************** /

void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem )
{
ListItem_t *pxIterator;
const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;

	/* 仅当还定义了configASSERT()时,这些测试才有效列表数据结构在内存中被覆盖。 他们不会抓住
错误配置或使用FreeRTOS导致数据错误. */
	listTEST_LIST_INTEGRITY( pxList );
	listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );

	/* 寻找节点要插入的位置 */
	if( xValueOfInsertion == portMAX_DELAY )
	{
		pxIterator = pxList->xListEnd.pxPrevious;
	}
	else
	{
		/* *** NOTE ***********************************************************
		If you find your application is crashing here then likely causes are
		listed below.  In addition see https://www.freertos.org/FAQHelp.html for
		more tips, and ensure configASSERT() is defined!
		https://www.freertos.org/a00110.html#configASSERT

			1) Stack overflow -
			   see https://www.freertos.org/Stacks-and-stack-overflow-checking.html
			2) Incorrect interrupt priority assignment, especially on Cortex-M
			   parts where numerically high priority values denote low actual
			   interrupt priorities, which can seem counter intuitive.  See
			   https://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition
			   of configMAX_SYSCALL_INTERRUPT_PRIORITY on
			   https://www.freertos.org/a00110.html
			3) Calling an API function from within a critical section or when
			   the scheduler is suspended, or calling an API function that does
			   not end in "FromISR" from an interrupt.
			4) Using a queue or semaphore before it has been initialised or
			   before the scheduler has been started (are interrupts firing
			   before vTaskStartScheduler() has been called?).
		**********************************************************************/

		for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM.  This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */
		{
			/* There is nothing to do here, just iterating to the wanted
			insertion position. */
		}
	}
	/* 根据升序排列,将节点插入 */
	pxNewListItem->pxNext = pxIterator->pxNext;
	pxNewListItem->pxNext->pxPrevious = pxNewListItem;
	pxNewListItem->pxPrevious = pxIterator;
	pxIterator->pxNext = pxNewListItem;

	/* 记住该节点所在的链表 */
	pxNewListItem->pxContainer = pxList;
	/* 链表节点计数器++ */
	( pxList->uxNumberOfItems )++;
}
/*-----------------------------------------------------------*/

FreeRTOS源代码分析 - List.c 学习笔记

将节点插入到链表的尾部

/* 仅当还定义了configASSERT()时,这些测试才有效列表数据结构在内存中被覆盖。 他们不会抓住
错误配置或使用FreeRTOS导致数据错误. */
listTEST_LIST_INTEGRITY( pxList );
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );

void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem )
{
ListItem_t * const pxIndex = pxList->pxIndex;

	/* Only effective when configASSERT() is also defined, these tests may catch
	the list data structures being overwritten in memory.  They will not catch
	data errors caused by incorrect configuration or use of FreeRTOS. */
	listTEST_LIST_INTEGRITY( pxList );
	listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );

	/* Insert a new list item into pxList, but rather than sort the list,
	makes the new list item the last item to be removed by a call to
	listGET_OWNER_OF_NEXT_ENTRY(). */
	pxNewListItem->pxNext = pxIndex;
	pxNewListItem->pxPrevious = pxIndex->pxPrevious;

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

	pxIndex->pxPrevious->pxNext = pxNewListItem;
	pxIndex->pxPrevious = pxNewListItem;

	/* Remember which list the item is in. */
	pxNewListItem->pxContainer = pxList;

	( pxList->uxNumberOfItems )++;
}
/*-----------------------------------------------------------*/

FreeRTOS源代码分析 - List.c 学习笔记

相关标签: freertos 链表