FreeRTOS源代码分析 - List.c 学习笔记
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 ); /*新增加的部分,用来检测完整性*/
}
链表节点初始化
注意:
/*果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 );
}
/*-----------------------------------------------------------*/
将节点按照升序排列插入到链表
注意:
/* 仅当还定义了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 )++;
}
/*-----------------------------------------------------------*/
将节点插入到链表的尾部
/* 仅当还定义了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 )++;
}
/*-----------------------------------------------------------*/
上一篇: Maven依赖中的scope详解
下一篇: 如何低延时直播
推荐阅读