红叶何时落水
列表是一个存放整个系统任务实时信息的数据结构,与单个任务本身是没有关系的是用来调度器用于控制任务的工具
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;
获取列表下一项的函数
这个函数改变了pxIndex的指向,开始了遍历,它不破坏列表结构
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \
{ \
List_t * const pxConstList = ( pxList ); \
/* Increment连续增加 the index to the next item and return the item, ensuring */ \
/* we don't return the marker used at the end of the list. */ \
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \
{
//如果指向了结尾,那就从头开始遍历,列表是双向链表 \
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
}
\
( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \
}
mini列表 xListEnd使用这种类型
struct xMINI_LIST_ITEM
{
configLIST_VOLATILE TickType_t xItemValue; //只是为了节省空间,当然以此来表明xListEnd的特殊性,它只用于表示当前已经到达列表的尾部
struct xLIST_ITEM * configLIST_VOLATILE pxNext;
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
};
列表初始化
void vListInitialise( List_t * const pxList )
{
/* The list structure contains a list item which is used to mark the
end of the list. To initialise初始化 the list the list end is inserted
as the only list entry. */
pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd );/*初始化开始,先把index指向end表示当前为空*/
/* The list end value is the highest possible value in the list to
ensure it remains at the end of the list.保证xListEnd项值为最大值 */
pxList->xListEnd.xItemValue = portMAX_DELAY;
/* The list end next and previous pointers point to itself so we know
when the list is empty.暂时指向自身,表明列表还是空的 ,构建一个双链表结构*/
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. */
pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
}
列表项初始化
列表项是不断插入删除动态游走于各个列表的
void vListInitialiseItem( ListItem_t * const pxItem )
{
/* Make sure the list item is not recorded as being on a list. */
//当前这个列表项不属于任何列表
pxItem->pvContainer = NULL;
}
列表项的升序插入
//这个函数仅仅完成了链表项的插入,pxIndex的值没有发生变化
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem )
{
ListItem_t *pxIterator;
const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
//如果要插入的项的项值为最大值的话, pxIterator指向xListEnd的前一个
if( xValueOfInsertion == portMAX_DELAY )
{
pxIterator = pxList->xListEnd.pxPrevious;
}
else
{
//开始循环,从第一项开始,找到合适的位置,循环完毕后,pxIterator指向合适位置的前一项
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. */
{
/* 这是一个环形链表,pxList->xListEnd->xItemValue为第一个,另外,这是升序排列
<= 注定了插入的相同项值的新项,会被放在后面,portMAX_DELAY正好相反,xListEnd永远是最后一个
}
}
//双向链表的插入操作
pxNewListItem->pxNext = pxIterator->pxNext;
pxNewListItem->pxNext->pxPrevious = pxNewListItem;
pxNewListItem->pxPrevious = pxIterator;
pxIterator->pxNext = 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;
/* Make sure the index is left pointing to a valid item.
如果要被删除的这个项正在运行,那么pxindex指向前一个项*/
if( pxList->pxIndex == pxItemToRemove )
{
pxList->pxIndex = pxItemToRemove->pxPrevious;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
pxItemToRemove->pvContainer = NULL;
( pxList->uxNumberOfItems )--;
return pxList->uxNumberOfItems;
}
这个函数会将列表项插入pxindex的前面,所谓的尾部
vListInsertEnd();它有啥用???prvAddNewTaskToReadyList时用到,有很大用途