freeetos笔记-列表

红叶何时落水

列表是一个存放整个系统任务实时信息的数据结构,与单个任务本身是没有关系的是用来调度器用于控制任务的工具

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时用到,有很大用途

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

红叶落水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值