FreeRTOS202212‐ 将节点按照升序排列插入到链表
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐插入前‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐插入后‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
/*‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐*/
void vListInsert ( List_t * const pxList ,
ListItem_t * const pxNewListItem )
{
ListItem_t * pxIterator ;
const TickType_t xValueOfInsertion = pxNewListItem ‐> xItemValue ;
/*OnlyeffectivewhenconfigASSERT()isalsodefined,thesetestsmaycatchthelistdatastructuresbeingoverwritteninmemory.
TheywillnotcatchdataerrorscausedbyincorrectconfigurationoruseofFreeRTOS.*/
/*只有在定义了configASSERT()时才有效,这些测试可能会捕获内存中被覆盖的链表数据结构。
他们不会捕捉到由于不正确的配置或使用FreeRTOS而导致的数据错误*/
listTEST_LIST_INTEGRITY ( pxList );
listTEST_LIST_ITEM_INTEGRITY ( pxNewListItem );
/*Insertthenewlistitemintothelist,sortedinxItemValueorder.*/
/*将新链表项插入链表中,按xItemValue顺序排序*/
/*Ifthelistalreadycontainsalistitemwiththesameitemvaluethenthenewlistitemshouldbeplacedafterit.
ThisensuresthatTCBswhicharestoredinreadylists(allofwhichhavethesamexItemValuevalue)getashareoftheCPU.
However,ifthexItemValueisthesameasthebackmarkertheiterationloopbelowwillnotend.
Thereforethevalueischeckedfirst,andthealgorithmslightlymodifiedifnecessary.*/
/*如果链表中已包含具有相同排序值的链表项,则应将新的链表项放在该链表项之后。
这确保了存储在就绪链表中的TCB(任务控制块)(所有这些链表都具有相同的xItemValue值)获得CPU的份额。
但是,如果xItemValue与后标记相同,则下面的迭代循环将不会结束。
因此,首先检查该值,必要时对算法进行轻微修改*/
if ( xValueOfInsertion == portMAX_DELAY )
{
pxIterator = pxList ‐> xListEnd . pxPrevious ;
}
else
{
/****NOTE***********************************************************/
/*Ifyoufindyourapplicationiscrashingherethenlikelycausesarelistedbelow.
Inadditionseehttps://www.FreeRTOS.org/FAQHelp.htmlformoretips,andensureconfigASSERT()isdefined!
https://www.FreeRTOS.org/a00110.html#configASSERT
/*如果你发现你的应用程序在这里崩溃,那么下面列出了可能的原因。
此外,请参阅https://www.FreeRTOS.org/FAQHelp.html有关更多提示,请确保已定义configASSERT()!
https://www.FreeRTOS.org/a00110.html#configASSERT
1)Stackoverflow‐seehttps://www.FreeRTOS.org/Stacks‐and‐stack‐overflow‐checking.html
1)堆栈溢出‐请参阅https://www.FreeRTOS.org/Stacks‐and‐stack‐overflow‐checking.html
2)Incorrectinterruptpriorityassignment,especiallyonCortex‐Mpartswherenumericallyhighpriorityvaluesdenotelowactualinterruptpriorities,whichcanseemcounterintuitive.
Seehttps://www.FreeRTOS.org/RTOS‐Cortex‐M3‐M4.htmlandthedefinitionofconfigMAX_SYSCALL_INTERRUPT_PRIORITYonhttps://www.FreeRTOS.org/a00110.html
2)不正确的中断优先级分配,尤其是在Cortex‐M部件上,数字上的高优先级值表示实际中断优先级低,这可能会违反直觉。
参考https://www.FreeRTOS.org/RTOS‐Cortex‐M3‐M4.html以及上的configMAX_SYSCALL_INTERRUPT_PRIORITY的定义https://www.FreeRTOS.org/a00110.html
3)CallinganAPIfunctionfromwithinacriticalsectionorwhentheschedulerissuspended,orcallinganAPIfunctionthatdoesnotendin"FromISR"fromaninterrupt.
3)从临界段或调度程序暂停时调用API函数,或从中断调用不以“FromISR”结尾的API函数。
4)Usingaqueueorsemaphorebeforeithasbeeninitialisedorbeforetheschedulerhasbeenstarted(areinterruptsfiringbeforevTaskStartScheduler()hasbeencalled?).
4)在初始化队列或信号量之前或在启动调度程序之前使用它(是否在调用vTaskStartScheduler()之前触发中断?)。
5)IftheFreeRTOSportsupportsinterruptnestingthenensurethatthepriorityofthetickinterruptisatorbelowconfigMAX_SYSCALL_INTERRUPT_PRIORITY.
5)如果FreeRTOS端口支持中断嵌套,则确保tick中断的优先级等于或低于configMAX_SYSCALL_interrupt_priority。
/***********************************************************************/
for ( pxIterator = ( ListItem_t * ) & ( pxList ‐> xListEnd ); pxIterator ‐> pxNext ‐> xItemValue <= xValueOfInsertion ; pxIterator = pxIterator ‐> pxNext ) /*lint!e826!e740!e9087TheminiliststructureisusedasthelistendtosaveRAM.Thisischeckedandvalid.*/
/*lint!e440Theiteratormovestoadifferentvalue,notxValueOfInsertion.*/
{
/*Thereisnothingtodohere,justiteratingtothewantedinsertionposition.*/
/*这里没有什么可做的,只是迭代到所需的插入位置*/
}
}
pxNewListItem ‐> pxNext = pxIterator ‐> pxNext ;
pxNewListItem ‐> pxNext ‐> pxPrevious = pxNewListItem ;
pxNewListItem ‐> pxPrevious = pxIterator ;
pxIterator ‐> pxNext = pxNewListItem ;
/*Rememberwhichlisttheitemisin.Thisallowsfastremovaloftheitemlater.*/
/*记住该链表项在哪个链表中。这样以后可以快速删除该项目*/
pxNewListItem ‐> pxContainer = pxList ;
( pxList ‐> uxNumberOfItems ) ++ ;
}
/*‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐*/
uxNumberOfItems=2
*pxIndex
ListItem_t
链表节点索引指针
UBaseType_t
链表节点计数器32bit
节点排序值
*pxNext
*pxPrevious
structxLIST_ITEM
structxLIST_ITEM
xMINI_LIST_ITEM(MiniListItem_t)
xItemValue=0xffffffffUL
uint32_t/uint16_t(TickType_t)
xListEnd
xLIST(List_t)
链表头结点结构体
指向链表下一个节点
指向链表前一个节点
*pxList
xItemValue=1
*pxNext
*pxPrevious
*pvOwner
*pvContainer
内核对象
链表对象
xLIST(List_t)
void
structxLIST_ITEM
structxLIST_ITEM
uint32_t/uint16_t(TickType_t)
节点排序值
xLIST_ITEM(ListItem_t)
指向链表下一个节点
指向链表前一个节点
链表节点结构体
xItemValue=3
*pxNext
*pxPrevious
*pvOwner
*pvContainer
内核对象
链表对象
xLIST(List_t)
void
structxLIST_ITEM
structxLIST_ITEM
uint32_t/uint16_t(TickType_t)
节点排序值
xLIST_ITEM(ListItem_t)
指向链表下一个节点
指向链表前一个节点
链表节点结构体
NULL
xItemValue=2
*pxNext
*pxPrevious
*pvOwner
*pvContainer
内核对象
链表对象
xLIST(List_t)
void
structxLIST_ITEM
structxLIST_ITEM
uint32_t/uint16_t(TickType_t)
节点排序值
xLIST_ITEM(ListItem_t)
指向链表下一个节点
指向链表前一个节点
链表节点结构体
*pxNewListItem
uxNumberOfItems=3
*pxIndex
ListItem_t
链表节点索引指针
UBaseType_t
链表节点计数器32bit
节点排序值
*pxNext
*pxPrevious
structxLIST_ITEM
structxLIST_ITEM
xMINI_LIST_ITEM(MiniListItem_t)
xItemValue=0xffffffffUL
uint32_t/uint16_t(TickType_t)
xListEnd
xLIST(List_t)
链表头结点结构体
指向链表下一个节点
指向链表前一个节点
*pxList
xItemValue=1
*pxNext
*pxPrevious
*pvOwner
*pvContainer
内核对象
链表对象
xLIST(List_t)
void
structxLIST_ITEM
structxLIST_ITEM
uint32_t/uint16_t(TickType_t)
节点排序值
xLIST_ITEM(ListItem_t)
指向链表下一个节点
指向链表前一个节点
链表节点结构体
xItemValue=3
*pxNext
*pxPrevious
*pvOwner
*pvContainer
内核对象
链表对象
xLIST(List_t)
void
structxLIST_ITEM
structxLIST_ITEM
uint32_t/uint16_t(TickType_t)
节点排序值
xLIST_ITEM(ListItem_t)
指向链表下一个节点
指向链表前一个节点
链表节点结构体
xItemValue=2
*pxNext
*pxPrevious
*pvOwner
*pvContainer
内核对象
链表对象
xLIST(List_t)
void
structxLIST_ITEM
structxLIST_ITEM
uint32_t/uint16_t(TickType_t)
节点排序值
xLIST_ITEM(ListItem_t)
指向链表下一个节点
指向链表前一个节点
链表节点结构体
*pxNewListItem
*
pxIterator