FreeRTOS列表
生活随笔
收集整理的這篇文章主要介紹了
FreeRTOS列表
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
內核中有很多雙向列表,這些列表可以掛接很多列表項,每條列表都有一個確定的尾節點、列表當前指針、列表項個數
/* 列表結構體 */ typedef struct xLIST {listFIRST_LIST_INTEGRITY_CHECK_VALUE configLIST_VOLATILE UBaseType_t uxNumberOfItems; /* 列表項個數 */ListItem_t *configLIST_VOLATILE pxIndex; /* 當前列表項指針 */MiniListItem_t xListEnd; /* 列表的尾節點 */listSECOND_LIST_INTEGRITY_CHECK_VALUE }List_t;列表尾節點中的有效信息包括:列表項的值、next指針、previous指針
/* 迷你列表項結構體 */ struct xMINI_LIST_ITEM {listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUEconfigLIST_VOLATILE TickType_t xItemValue; /* 列表項的值 */struct xLIST_ITEM *configLIST_VOLATILE pxNext; /* next指針指向后一個列表項 */struct xLIST_ITEM *configLIST_VOLATILE pxPrevious; /* previous指針指向前一個列表項 */ }; typedef struct xMINI_LIST_ITEM MiniListItem_t;列表項的內容包括:列表項的值、next指針、previous指針、所屬TCB指針、正在掛接的列表指針
/* 列表項結構體 */ struct xLIST_ITEM {listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE configLIST_VOLATILE TickType_t xItemValue; /* 列表項的值 */struct xLIST_ITEM *configLIST_VOLATILE pxNext; /* next指針指向后一個列表項 */struct xLIST_ITEM *configLIST_VOLATILE pxPrevious; /* previous指針指向前一個列表項 */void *pvOwner; /* 該指針指向所屬TCB */void *configLIST_VOLATILE pvContainer; /* 指向包含該列表項的列表 */listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE }; typedef struct xLIST_ITEM ListItem_t;列表會掛接很多列表項,如圖所示:
?
?
列表初始化時不包含任何列表項
/* 功能:初始化列表pxList:列表指針 */ void vListInitialise(List_t *const pxList) {/* 列表初始化時只有尾節點,因此將當前指針指向尾節點 */pxList->pxIndex = (ListItem_t *)&(pxList->xListEnd);/* 尾節點的值初始化為0xffffffff */pxList->xListEnd.xItemValue = portMAX_DELAY;/* 列表初始化時只有尾節點,且列表是雙向環形鏈表 */pxList->xListEnd.pxNext = (ListItem_t *)&(pxList->xListEnd);pxList->xListEnd.pxPrevious = (ListItem_t *)&(pxList->xListEnd);/* 列表項的個數初始化為0 */pxList->uxNumberOfItems = (UBaseType_t)0U;listSET_LIST_INTEGRITY_CHECK_1_VALUE(pxList);listSET_LIST_INTEGRITY_CHECK_2_VALUE(pxList); }初始化完成后,如圖所示:
?
?
列表項初始化時不屬于任何列表
/* 功能:初始化列表項pxItem:列表項指針 */ void vListInitialiseItem(ListItem_t *const pxItem) {/* 將列表項所屬列表指針初始化為不指向任何列表 */pxItem->pvContainer = NULL;listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE(pxItem);listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE(pxItem); }列表初始化后,如圖所示:
?
?
列表項插入列表的方式有兩種,一種是直接插入當前指針指向的位置,另一種是按照列表項值從小到大插入
/* 功能:將列表項插入列表pxList:列表指針pxNewListItem:列表項指針 */ void vListInsertEnd(List_t *const pxList, ListItem_t *const pxNewListItem) {/* 當前列表項指針 */ListItem_t *const pxIndex = pxList->pxIndex;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)++; }/* 功能:將列表項按列表值從小到大插入列表中pxList:列表指針pxNewListItem:列表項指針 */ 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);/* 如果列表項值最大,則直接插入列表尾部 */if(xValueOfInsertion == portMAX_DELAY){pxIterator = pxList->xListEnd.pxPrevious;}/* 按列表項值從小到大查找 */else{for(pxIterator = (ListItem_t *)&(pxList->xListEnd); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext){}}/* 將列表項插入列表 */pxNewListItem->pxNext = pxIterator->pxNext;pxNewListItem->pxNext->pxPrevious = pxNewListItem;pxNewListItem->pxPrevious = pxIterator;pxIterator->pxNext = pxNewListItem;/* 將列表項所屬列表指針指向列表 */pxNewListItem->pvContainer = (void *)pxList;/* 列表中列表項個數加一 */(pxList->uxNumberOfItems)++; }?
?
從列表中移除列表項
/* 功能:將列表項從當前所在的列表中移除pxItemToRemove:列表項返回值:移除該列表項后所在列表中列表項的個數 */ 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;mtCOVERAGE_TEST_DELAY();/* 列表當前指針指向該列表項,則將列表當前指針改為指向前一個列表項 */if(pxList->pxIndex == pxItemToRemove){pxList->pxIndex = pxItemToRemove->pxPrevious;}else{mtCOVERAGE_TEST_MARKER();}/* 該列表項不屬于任何列表 */pxItemToRemove->pvContainer = NULL;/* 列表中列表項個數減一 */(pxList->uxNumberOfItems)--;/* 返回列表項個數 */return pxList->uxNumberOfItems; }?
?
列表還提供了一些其他的接口
/* 設置列表項所屬TCB */ #define listSET_LIST_ITEM_OWNER(pxListItem, pxOwner) ((pxListItem)->pvOwner = (void *)(pxOwner))/* 獲取列表項所屬TCB */ #define listGET_LIST_ITEM_OWNER(pxListItem) ((pxListItem)->pvOwner)/* 設置列表項值 */ #define listSET_LIST_ITEM_VALUE(pxListItem, xValue) ((pxListItem)->xItemValue = (xValue))/* 獲取列表項值 */ #define listGET_LIST_ITEM_VALUE(pxListItem) ((pxListItem)->xItemValue)/* 獲取列表頭部列表項的值 */ #define listGET_ITEM_VALUE_OF_HEAD_ENTRY(pxList) (((pxList)->xListEnd).pxNext->xItemValue)/* 獲取列表頭部列表項 */ #define listGET_HEAD_ENTRY(pxList) (((pxList)->xListEnd).pxNext)/* 獲取下一個列表項 */ #define listGET_NEXT(pxListItem) ((pxListItem)->pxNext)/* 獲取列表尾節點 */ #define listGET_END_MARKER(pxList) ((ListItem_t const *)(&((pxList)->xListEnd)))/* 判斷列表是否為空 */ #define listLIST_IS_EMPTY(pxList) ((BaseType_t)((pxList)->uxNumberOfItems == (UBaseType_t)0))/* 獲取列表中當前列表項的個數 */ #define listCURRENT_LIST_LENGTH(pxList) ((pxList)->uxNumberOfItems)/* 將當前列表項指針指向下一個列表項,返回所屬TCB */ #define listGET_OWNER_OF_NEXT_ENTRY(pxTCB, pxList) \ { \List_t *const pxConstList = (pxList); \(pxConstList)->pxIndex = (pxConstList)->pxIndex->pxNext; \if((void *)(pxConstList)->pxIndex == (void *)&((pxConstList)->xListEnd)) \{ \(pxConstList)->pxIndex = (pxConstList)->pxIndex->pxNext; \} \(pxTCB) = (pxConstList)->pxIndex->pvOwner; \ }/* 獲取列表首節點所屬TCB */ #define listGET_OWNER_OF_HEAD_ENTRY(pxList) ((&((pxList)->xListEnd))->pxNext->pvOwner)/* 判斷列表項是否屬于指定列表 */ #define listIS_CONTAINED_WITHIN(pxList, pxListItem) ((BaseType_t)((pxListItem)->pvContainer == (void *)(pxList)))/* 獲取列表項所在列表 */ #define listLIST_ITEM_CONTAINER(pxListItem) ((pxListItem)->pvContainer)/* 判斷列表是否已經初始化(尾節點列表項值為最大可能值0xffffffff) */ #define listLIST_IS_INITIALISED(pxList) ((pxList)->xListEnd.xItemValue == portMAX_DELAY)?
總結
以上是生活随笔為你收集整理的FreeRTOS列表的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 春招快到了,送你一份数据分析常见面试题
- 下一篇: 区块链究竟是什么?看完这篇秒懂!