【freertos-kernel】list

freertos list

  • 基本類型
  • 結構體
    • ListItem_t (list.h)
    • List_t (list.h)
  • 宏函數
  • 函數
    • vListInitialise
    • vListInitialiseItem
    • vListInsertEnd
    • vListInsert
    • uxListRemove

基本類型

freertos為了兼容性,重新定義了基本類型,像BaseType_t,TickType_t等等,這些定義都在portable文件夾下對應編譯器文件夾下對應內核文件夾的portmacro.h里。比如armcm3下的BaseType_t就是long類型,我一直以為long是64位,就很奇怪,不應該是32位嗎,問了ai查了資料后才明白了,了解到數據模型。重新定義基本類型可以屏蔽cpu內核和編譯器對數據類型位數的影響,為了讓常用數據類型與cpu位數匹配。看到這我也是第一次對這個問題比以前有更深入一點的研究,為了統一理解,引入了 數據模型 ,有ILP32,LP64,LLP64等等,I表示int,L表示long,P表示指針類型,比如ILP32就是int,long,指針都是32位的,主要是解決一些有位數差異的類型。

結構體

ListItem_t (list.h)

鏈表節點

struct xLIST_ITEM
{listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUEconfigLIST_VOLATILE TickType_t xItemValue;struct xLIST_ITEM * configLIST_VOLATILE pxNext;struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;void * pvOwner;struct xLIST * configLIST_VOLATILE pxContainer;listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE
};
typedef struct xLIST_ITEM ListItem_t;#if ( configUSE_MINI_LIST_ITEM == 1 )struct xMINI_LIST_ITEM{listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUEconfigLIST_VOLATILE TickType_t xItemValue;struct xLIST_ITEM * configLIST_VOLATILE pxNext;struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;};typedef struct xMINI_LIST_ITEM MiniListItem_t;
#elsetypedef struct xLIST_ITEM      MiniListItem_t;
#endif
  • listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUElistSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE見名知義,鏈表節點完整性檢查值,具體定義在本結構體定義的前面,如果configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES配置為1的時候這兩個宏會被定義成TickType_t的字段,如果配置為0就啥也沒有。
  • 關于configLIST_VOLATILE的說明在list.h開頭,鏈表結構體的成員變量是從中斷中被修改的,因此從理論上來說應該將它們聲明為 volatile。然而,這些成員變量僅在“功能上是原子性”的方式下被修改(即在臨界區或調度器掛起期間進行修改),并且它們要么是通過引用傳入函數的,要么是通過一個 volatile 變量進行索引訪問的。因此,在目前為止測試的所有使用場景中,可以省略 volatile 修飾符,從而帶來一定程度的性能提升,而不會對功能行為產生不良影響。目前為止IAR、ARM 和 GCC 編譯器在設置為最大優化級別時所生成的匯編指令已經被檢查過,可以不加,但是隨著編譯器的發展可能會被錯誤優化,遇到這種情況可以在FreeRTOSConfig.h添加#define configLIST_VOLATILE volatile
  • pxNext指向下一個節點。pxPrevious指向前一個結點。pvOwner指向一些與節點相關的其他數據,可能指向任務控制塊等,pxContainer指向當前鏈表項所屬的鏈表,可用于判斷該項是否已加入某個鏈表。xItemValue節點值 我猜測可能和任務分配時間有關
  • 還提供了一種迷你鏈表節點,去除了pvOwnerpxContainer兩個字段,只保留了鏈表結構部分。

List_t (list.h)

給調度器使用的鏈表。

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;
  • uxNumberOfItems當前鏈表中的節點數量。pxIndex用于遍歷鏈表的指針,相當于一個游標。xListEnd是特殊的鏈表節點,從源碼注釋來看,xItemValue是最大可能值,它永遠位于鏈表末尾,作為結束標記(從這里的意思可以看出這里的鏈表可能是升序排序的,后面看調度器的代碼應該就清楚了)。

宏函數

比較簡單,根據名字就基本知道功能,簡單羅列一下。

  • listSET_LIST_ITEM_OWNER( pxListItem, pxOwner )
    設置鏈表節點pxListItem的pxOwner為pxOwner
  • listGET_LIST_ITEM_OWNER( pxListItem )
    返回pxListItem的pvOwner
  • listSET_LIST_ITEM_VALUE( pxListItem, xValue )
    設置pxListItem的值xItemValue為xValue
  • listGET_LIST_ITEM_VALUE( pxListItem )
    返回pxListItem的值xItemValue
  • listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList )
    返回pxList 的頭節點的值xItemValue
  • listGET_HEAD_ENTRY( pxList )
    返回pxList 的頭節點,也是尾節點的下一個節點,可以看出是個雙向循環鏈表
  • listGET_NEXT( pxListItem )
    返回pxListItem的下一個節點
  • listGET_END_MARKER( pxList )
    返回pxList 的尾節點
  • listLIST_IS_EMPTY( pxList )
    返回鏈表是否為空
  • listCURRENT_LIST_LENGTH( pxList )
    返回鏈表長度
  • listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList )
    返回下一個節點(跳過尾節點)的pvOwner給pxTCB
  • listREMOVE_ITEM( pxItemToRemove )
    移除pxItemToRemove節點,把pxIndex移到pxItemToRemove 前一個節點
  • listINSERT_END( pxList, pxNewListItem )
    尾部插入pxNewListItem
  • listGET_OWNER_OF_HEAD_ENTRY( pxList )
    返回頭節點的pvOwner
  • listIS_CONTAINED_WITHIN( pxList, pxListItem )
    pxList是否包含pxListItem
  • listLIST_IS_INITIALISED( pxList )
    pxList 是否初始化了

函數

這些函數的聲明都有PRIVILEGED_FUNCTION宏,特權函數,類似的宏還有特權變量,定義在mpu_wrapper.h
#define PRIVILEGED_FUNCTION attribute( ( section( “privileged_functions” ) ) )
特權函數會分配到特殊的段,為MPU(內存保護單元)提供支持。

vListInitialise


void vListInitialise( List_t * const pxList )
{traceENTER_vListInitialise( pxList );	//調試用的好像,先不管他pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd );	//游標指向尾節點listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) );//設置節點完整性檢查值為1pxList->xListEnd.xItemValue = portMAX_DELAY;pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );#if ( configUSE_MINI_LIST_ITEM == 0 ){pxList->xListEnd.pvOwner = NULL;pxList->xListEnd.pxContainer = NULL;listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) );}#endifpxList->uxNumberOfItems = ( UBaseType_t ) 0U;listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );traceRETURN_vListInitialise();
}

初始化鏈表,初始化鏈表尾節點。

vListInitialiseItem

void vListInitialiseItem( ListItem_t * const pxItem )
{traceENTER_vListInitialiseItem( pxItem );/* Make sure the list item is not recorded as being on a list. */pxItem->pxContainer = NULL;/* Write known values into the list item if* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );traceRETURN_vListInitialiseItem();
}

沒啥好說的

vListInsertEnd

void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem )
{ListItem_t * const pxIndex = pxList->pxIndex;traceENTER_vListInsertEnd( pxList, pxNewListItem );listTEST_LIST_INTEGRITY( pxList );listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );pxNewListItem->pxNext = pxIndex;pxNewListItem->pxPrevious = pxIndex->pxPrevious;/* Only used during decision coverage testing. */mtCOVERAGE_TEST_DELAY();pxIndex->pxPrevious->pxNext = pxNewListItem;pxIndex->pxPrevious = pxNewListItem;/* Remember which list the item is in. */pxNewListItem->pxContainer = pxList;( pxList->uxNumberOfItems ) = ( UBaseType_t ) ( pxList->uxNumberOfItems + 1U );traceRETURN_vListInsertEnd();
}

在pxIndex后面插入新的節點

vListInsert

void vListInsert( List_t * const pxList,ListItem_t * const pxNewListItem )
{ListItem_t * pxIterator;const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;traceENTER_vListInsert( pxList, pxNewListItem );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 ){/* There is nothing to do here, just iterating to the wanted* insertion position. */}}pxNewListItem->pxNext = pxIterator->pxNext;pxNewListItem->pxNext->pxPrevious = pxNewListItem;pxNewListItem->pxPrevious = pxIterator;pxIterator->pxNext = pxNewListItem;pxNewListItem->pxContainer = pxList;( pxList->uxNumberOfItems ) = ( UBaseType_t ) ( pxList->uxNumberOfItems + 1U );traceRETURN_vListInsert();
}

將一個新的節點按其 xItemValue 的大小順序插入到鏈表中,保持鏈表始終按升序排列。

uxListRemove

UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
{List_t * const pxList = pxItemToRemove->pxContainer;traceENTER_uxListRemove( pxItemToRemove );pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;/* Only used during decision coverage testing. */mtCOVERAGE_TEST_DELAY();if( pxList->pxIndex == pxItemToRemove ){pxList->pxIndex = pxItemToRemove->pxPrevious;}else{mtCOVERAGE_TEST_MARKER();}pxItemToRemove->pxContainer = NULL;( pxList->uxNumberOfItems ) = ( UBaseType_t ) ( pxList->uxNumberOfItems - 1U );traceRETURN_uxListRemove( pxList->uxNumberOfItems );return pxList->uxNumberOfItems;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/84124.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/84124.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/84124.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

游戲盾的功有哪些?

游戲盾的功能主要包括以下幾方面&#xff1a; 一、網絡攻擊防護 DDoS攻擊防護&#xff1a; T級防御能力&#xff1a;游戲盾提供分布式云節點防御集群&#xff0c;可跨地區、跨機房動態擴展防御能力和負載容量&#xff0c;輕松達到T級別防御&#xff0c;有效抵御SYN Flood、UD…

PycharmFlask 學習心得:路由(3-4)

對路由的理解&#xff1a; 用戶輸入網址 例如&#xff1a;http://localhost:5000/hello 瀏覽器會向這個地址發起一個 HTTP 請求&#xff08;比如 GET 請求&#xff09; 請求到達 Flask 的服務器 Flask 監聽著某個端口&#xff08;如 5000&#xff09;&#xff0c;收到請求后…

課程與考核

6.1 課程講解與實戰考核 6.1.1 SQL注入篇考核 考核目標&#xff1a;通過手動注入與工具結合&#xff0c;獲取目標數據庫敏感信息。 題目示例&#xff1a; 目標URL&#xff1a;http://vuln-site.com/product?id1 要求&#xff1a; 判斷注入類型&#xff08;聯合查詢/報錯注…

線程池介紹,分類,實現(工作原理,核心組成,拒絕策略),固態線程池的實現+詳細解釋(支持超時取消機制和不同的拒絕策略)

目錄 線程池 介紹 分類 實現 工作原理 核心組成 拒絕策略 固態線程池 功能 std::future 實現 拒絕策略支持 提交任務 超時取消 用戶檢測取消 安全銷毀 代碼 測試 線程池 介紹 線程池(圖解,本質,模擬實現代碼),添加單例模式(懶漢思路代碼)_線程池單例-CSDN博…

紡線機與PLC通訊故障?ETHERCAT/CANopen網關秒解協議難題

在紡織行業智能化轉型浪潮中&#xff0c;設備間高效通信是實現自動化生產的關鍵。JH-ECT009疆鴻智能EtherCAT轉CANopen協議轉換網關&#xff0c;憑借出色的協議適配能力&#xff0c;成功架起倍福PLC與自動紡線機間的通信橋梁&#xff0c;為紡織廠自動化生產注入強勁動力。 紡織…

深度剖析并發I/O模型select、poll、epoll與IOCP核心機制

核心概要&#xff1a;select、poll、epoll 和 IOCP 是四種用于提升服務器并發處理能力的I/O模型或機制。前三者主要屬于I/O多路復用范疇&#xff0c;允許單個進程或線程監視多個I/O流的狀態&#xff1b;而 IOCP 則是一種更為徹底的異步I/O模型。 一、引言&#xff1a;為何需要這…

microsoft中word如何添加個人簽名

https://support.microsoft.com/zh-cn/office/%E6%8F%92%E5%85%A5%E7%AD%BE%E5%90%8D-f3b3f74c-2355-4d53-be89-ae9c50022730 插入簽名圖片 圖片格式選擇裁剪合適的大小 使用的簽名如果不是白色紙張的話可以重新著色 依次點擊圖片格式——顏色——重新著色——黑白50% 設置透…

linux初識--基礎指令

Linux下基礎指令 ls 指令 語法&#xff1a; ls [ 選項 ] [ ?錄或?件 ] 功能&#xff1a;對于?錄&#xff0c;該命令列出該?錄下的所有??錄與?件。對于?件&#xff0c;將列出?件名以及其他信 息。 常?選項&#xff1a; -a 列出?錄下的所有?件&#xff0c;包括以…

實戰:Dify智能體+Java=自動化運營工具!

我們在運營某個圈子的時候&#xff0c;可能每天都要將這個圈子的“熱門新聞”發送到朋友圈或聊天群里&#xff0c;但依靠傳統的實現手段非常耗時耗力&#xff0c;我們通常要先收集熱門新聞&#xff0c;再組裝要新聞內容&#xff0c;再根據內容設計海報等。 那怎么才能簡化并高…

RabbitMQ可靠傳輸——持久性、發送方確認

一、持久性 前面學習消息確認機制時&#xff0c;是為了保證Broker到消費者直接的可靠傳輸的&#xff0c;但是如果是Broker出現問題&#xff08;如停止服務&#xff09;&#xff0c;如何保證消息可靠性&#xff1f;對此&#xff0c;RabbitMQ提供了持久化功能&#xff1a; 持久…

(Java基礎筆記vlog)Java中常見的幾種設計模式詳解

前言&#xff1a; 在 Java 編程里&#xff0c;設計模式是被反復使用、多數人知曉、經過分類編目的代碼設計經驗總結。他能幫助開發者更高效地解決常見問題&#xff0c;提升代碼的可維護性、可擴展性和復用性。下面介紹Java 中幾種常見的設計模式。 單例模式&#xff08;Singlet…

(8)Spring Boot 原生鏡像支持

Spring Boot 原生鏡像支持 ?? 點擊展開題目 在Spring Boot 3.x中,如何設計一個支持GraalVM原生鏡像的微服務?需要特別注意哪些限制? ?? Spring Boot 3.x 原生鏡像概述 Spring Boot 3.x 通過 Spring Native 項目提供了對 GraalVM 原生鏡像的一流支持,使開發者能夠將 S…

不使用SOAP,從PDF表單連接數據庫

不使用SOAP協議&#xff0c;通過XFDF格式實現PDF表單與數據庫交互的方法。該方法兼容免費的Adobe Reader&#xff0c;且無需特殊權限設置。 背景與問題 歷史方案: Adobe曾提供ADBC接口&#xff08;基于ODBC&#xff09;&#xff0c;但在Acrobat 9后被移除。SOAP方案在免費版Rea…

HTTP由淺入深

文章目錄 概述特點URL HTTP 與 HTTPS概述HTTP 工作原理HTTPS 的作用區別總結 請求報文請求行常見請求方法請求頭請求體Content-Type 詳解常見場景 Content-Type 對應關系 響應報文響應行狀態碼詳解1xx&#xff1a;信息響應&#xff08;Informational&#xff09;2xx&#xff1a…

Redis淘汰策略

Redis有八種淘汰策略 noeviction &#xff1a;不進行淘汰&#xff0c;直接報錯。allkeys-lru &#xff1a;隨機淘汰最久未使用的鍵。volatile-lru &#xff1a;從設置了過期時間的鍵中&#xff0c;隨機淘汰最久未使用的鍵。allkeys-random &#xff1a;隨機淘汰某個鍵。volati…

Maven打包SpringBoot項目,因包含SpringBootTest單元測試和Java預覽版特性導致打包失敗

SpringBoot啟用Java預覽版特性&#xff08;無測試類&#xff09; 在pom.xml文件中加入以下配置表示啟用Java預覽版 <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration>…

Makefile快速入門

簡介?&#xff1a; ? Makefile? 是一種用于自動化構建和管理軟件項目的工具文件&#xff0c;通常與 make 命令配合使用。它通過定義?規則?&#xff08;rules&#xff09;來指定如何從源文件生成目標文件&#xff08;如可執行程序或庫&#xff09;&#xff0c;并自動…

RISC-V 開發板 MUSE Pi Pro OpenCV結合Gstreamer實時顯示CSI攝像頭

視頻講解&#xff1a;RISC-V 開發板 MUSE Pi Pro OpenCV結合Gstreamer實時顯示CSI攝像頭_嗶哩嗶哩_bilibili RISC-V 開發板 MUSE Pi Pro OpenCV結合Gstreamer實時顯示CSI攝像頭 安裝opencv相關庫 sudo apt install libopencv-dev python3 python3-opencv 測試使用的CSI攝像頭…

如何用JAVA手寫一個Tomcat

一、初步理解Tomcat Tomcat是什么&#xff1f; Tomcat 是一個開源的 輕量級 Java Web 應用服務器&#xff0c;核心功能是 運行 Servlet/JSP。 Tomcat的核心功能&#xff1f; Servlet 容器&#xff1a;負責加載、實例化、調用和銷毀 Servlet。 HTTP 服務器&#xff1a;監聽端口…

短劇系統開發與抖音生態融合:短視頻時代的新風口與商業機遇

在短視頻內容井噴的時代&#xff0c;“短劇”作為一種新興內容形態&#xff0c;正以驚人的速度搶占用戶注意力。抖音、快手等平臺日均播放量破億的短劇作品&#xff0c;不僅催生了新的內容創作風口&#xff0c;更推動了短劇系統開發的巨大市場需求。本文將深度解析短劇系統開發…