FreeRTOS列表和列表項

列表和列表項是FreeRTOS的一個數(shù)據(jù)結(jié)構(gòu), FreeRTOS內(nèi)核調(diào)度大量使用了列表(list)和列表項(list item)數(shù)據(jù)結(jié)構(gòu)。
FreeRTOS列表使用指針指向列表項。一個列表(list)下面可能有很多個列表項(list item),每個列表項都有一個指針指向列表。


一、什么是列表和列表項

列表概念上和鏈表有點相似,用來追蹤FreeRTOS中的任務(wù)。與列表相關(guān)的東西都在list.c和list.h中。

typedef struct xLIST
{
    listFIRST_LIST_INTEGRITY_CHECK_VALUE    
    configLIST_VOLATILE UBaseType_t uxNumberOfItems;//用來記錄列表中列表項的數(shù)量
    ListItem_t * configLIST_VOLATILE pxIndex;       //pxIndex,用來記錄當(dāng)前列表項索引號,用于遍歷列表
    MiniListItem_t xListEnd;            //列表中最后一個列表項,用來表示列表結(jié)束               
    listSECOND_LIST_INTEGRITY_CHECK_VALUE           
} List_t;

  1. uxNumberOfItems表示該列表中掛接的列表項數(shù)目,0表示列表為空。
  2. 列表項類型指針用于遍歷列表,列表初始化后,這個指針指向&xListEnd。通過宏listGET_OWNER_OF_NEXT_ENTRY()來獲取列表中的下一個列表項。
  3. 列表項xListEnd用于標(biāo)記列表結(jié)束。xListEnd.xItemValue被初始化為一個常數(shù),其值與硬件架構(gòu)相關(guān),為0xFFFF(16位架構(gòu))或者0xFFFFFFFF(32位架構(gòu))。

列表項
列表項就是存放在列表中的項目。

struct xLIST_ITEM
{
    listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE       /*用于檢測列表項數(shù)據(jù)是否完整*/
    configLIST_VOLATILE TickType_t xItemValue;      //列表項值  
    struct xLIST_ITEM * configLIST_VOLATILE pxNext; //下一列表項 
    struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; //上一個列表項,同pxNext配合可實現(xiàn)雙向鏈表功能
    void * pvOwner;             //記錄此鏈表項歸誰所有,指向一個任務(wù)TCB                  
    void * configLIST_VOLATILE pvContainer;     //記錄此列表項歸哪個列表,指向包含該列表項的列表       
    listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE  /*用于檢測列表項數(shù)據(jù)是否完整*/       
};
typedef struct xLIST_ITEM ListItem_t;                   

  1. xItemValue是列表項值,通常是一個被跟蹤的任務(wù)優(yōu)先級或是一個調(diào)度事件的計數(shù)器值。
    如果任務(wù)因為等待從隊列取數(shù)據(jù)而進(jìn)入阻塞狀態(tài),則任務(wù)的事件列表項的列表項值保存任務(wù)優(yōu)先級有關(guān)信息,狀態(tài)列表項的列表項值保存阻塞時間有關(guān)的信息。

迷你列表項
既然有了全功能版的列表項,為什么還要聲明迷你版的列表項呢?
這是因為列表結(jié)構(gòu)體需要一個列表項成員,但又不需要列表項中的所有字段,所以才有了迷你版列表項。

struct xMINI_LIST_ITEM
{
    listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE           
    configLIST_VOLATILE TickType_t xItemValue;      //列表項值  
    struct xLIST_ITEM * configLIST_VOLATILE pxNext; //下一列表項 
    struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; //上一個列表項,同pxNext配合可實現(xiàn)雙向鏈表功能     
};
typedef struct xMINI_LIST_ITEM MiniListItem_t;      

二、列表和列表項初始化

新創(chuàng)建或定義的列表需要對其做初始化處理,列表的初始化可以通過vListInitialise()函數(shù)來完成。
列表結(jié)構(gòu)體中包含一個列表項成員,主要用于標(biāo)記列表結(jié)束。初始化列表就是把這個列表項插入到列表中

void vListInitialise( List_t * const pxList )
{
     /*列表索引指向列表項*/
     pxList->pxIndex = ( ListItem_t * )&( pxList->xListEnd );                  
     /* 設(shè)置為最大可能值 */
     pxList->xListEnd.xItemValue =portMAX_DELAY;
 
     /* 列表項xListEnd的pxNext和pxPrevious指針指向了它自己 */
     pxList->xListEnd.pxNext = (ListItem_t * ) &( pxList->xListEnd );
     pxList->xListEnd.pxPrevious= ( ListItem_t * ) &( pxList->xListEnd );
     pxList->uxNumberOfItems = ( UBaseType_t) 0U;
 
     /* 設(shè)置為已知值,用于檢測列表數(shù)據(jù)是否完整*/
     listSET_LIST_INTEGRITY_CHECK_1_VALUE(pxList );
     listSET_LIST_INTEGRITY_CHECK_2_VALUE(pxList );
}

列表項的初始比較簡單,只要確保列表項不在任何列表中即可。

void vListInitialiseItem( ListItem_t * const pxItem )
{
    pxItem->pvContainer = NULL;/不屬于任何list
//初始化用于完成性檢查的變量
    listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
    listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
}

其他內(nèi)容,在實際使用時進(jìn)行賦值。

三、列表項插入和刪除

列表項所在的位置取決于列表項的列表項值(xItemValue)

3.1 列表項插入

vListInsert(List_t *const pxList, ListItem_t *const pxNewListItem)
參數(shù):列表項要插入的列表和要插入的列表項
要插入的位置由列表項中成員變量xItemValue來決定。

void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem )
{
    ListItem_t *pxIterator;
//獲取要插入的值
    const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
// 檢查列表和列表項的完整性
    listTEST_LIST_INTEGRITY( pxList );
    listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );

/*將新的列表項插入到列表,根據(jù)xItemValue的值降序插入列表。*/
    if( xValueOfInsertion == portMAX_DELAY )      // 插入末尾
    {
        pxIterator = pxList->xListEnd.pxPrevious;
    }
    else
    {
        

        for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd );\
                     pxIterator->pxNext->xItemValue <= xValueOfInsertion;\
                     pxIterator = pxIterator->pxNext )
        { }// empty
    }
//插入中間位置時,插在Interator后面
    pxNewListItem->pxNext = pxIterator->pxNext;
    pxNewListItem->pxNext->pxPrevious = pxNewListItem;
    pxNewListItem->pxPrevious = pxIterator;
    pxIterator->pxNext = pxNewListItem;

//列表項在列表中了,列表項成員變量pvContainer記錄此列表項屬于哪個列表
    pxNewListItem->pvContainer = ( void * ) pxList;
//表示又加了一個列表項
    ( pxList->uxNumberOfItems )++;
}

portMAX_DELAY:如果列表中存在與新列表項xItemValue值相同的列表項,則新插入的列表項位于它之后。如果列表項的xItemValue值等于portMAX_DELAY(列表結(jié)束標(biāo)記,我們在講列表數(shù)據(jù)結(jié)構(gòu)時,說到每個列表數(shù)據(jù)結(jié)構(gòu)體中都有一個列表項成員xListEnd,用于標(biāo)記列表結(jié)束。xListEnd.xItemValue被初始化為一個常數(shù),其值與硬件架構(gòu)相關(guān),為0xFFFF或者0xFFFFFFFF。這個常數(shù)在移植層定義,即宏portMAX_DELAY),則表示到達(dá)了列表結(jié)束位置。

3.2 將列表項插入到列表末端

void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem )
{
ListItem_t* const pxIndex = pxList->pxIndex;
 
         /*檢查列表和列表項數(shù)據(jù)的完整性,僅當(dāng)configASSERT()定義時有效。*/
         listTEST_LIST_INTEGRITY( pxList );
         listTEST_LIST_ITEM_INTEGRITY(pxNewListItem );
 
         /*向列表中插入新的列表項*/
         pxNewListItem->pxNext = pxIndex;
         pxNewListItem->pxPrevious =pxIndex->pxPrevious;
 
         mtCOVERAGE_TEST_DELAY();
 
         pxIndex->pxPrevious->pxNext =pxNewListItem;
         pxIndex->pxPrevious = pxNewListItem;
 
         pxNewListItem->pvContainer = ( void* ) pxList;
 
         ( pxList->uxNumberOfItems )++;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 多任務(wù)系統(tǒng) 1.FreeRTOS 是一個搶占式的實時多任務(wù)系統(tǒng), 那么其任務(wù)調(diào)度器也是搶占式的,運行過程如下圖所示...
    Swinner閱讀 1,500評論 0 1
  • 一、Linux系統(tǒng)概述 不加引號可理解為宏,直接替換,單引號中特殊字符會被解釋為普通字符,雙引號中$,,'還是特殊...
    赤果_b4a7閱讀 1,632評論 0 2
  • 目錄: 一:列表、列表項、迷你列表項結(jié)構(gòu)二:列表和列表項的初始化三:列表項插入四:列表項遍歷五:列表項末尾插入六:...
    外附魂骨閱讀 402評論 0 0
  • @(嵌入式) 簡述 前面了解了 FreeRTOS 的內(nèi)存管理,接下來看看任務(wù)調(diào)度,這也是一個操作系統(tǒng)中最重要的一部...
    orientlu閱讀 2,228評論 2 2
  • 用兩張圖告訴你,為什么你的 App 會卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 14,003評論 2 59

友情鏈接更多精彩內(nèi)容