首頁>技術>

​​​​​​​​​​​​​​​​​​​​​​​​​​​​​摘要:本文會給大家介紹下LiteOSStudio的映象分析工具,這可是一個評估、最佳化映象檔案RAM、ROM佔用大小的利器。

大家都知道嵌入式開發板由於受成本限制,晶片的RAM、Flash等硬體資源有限,比如有些低成本的開發板只有內建的64KB ROM、20KB RAM。在豐富功能特性程式設計時,一些看似無害的改變,都可能導致編譯出的映象膨脹,超出開發板的資源限制。對於硬體資源相對寬裕的開發板,合理的映象大小規劃,也會提升效能。本文會給大家介紹下LiteOS Studio的映象分析工具,這可是個評估、最佳化映象檔案RAM、ROM佔用大小的利器。

開發環境準備

前期的系列文章,我們掌握瞭如何安裝LiteOS Studio,如何新建STM32F769IDISCOVERY和Qemurealview-pbx-a9工程。這次我們以STM32F429IGTx開發板為例,建立工程的方式是一樣的,開發板選擇STM32F429IGTx即可。映象分析特性對任何LiteOS工程都是適用的,我們只是以該開發板為例。工程建立完畢後,執行編譯,輸出如下:

終端控制檯輸出顯示編譯成功了,可執行檔案Huawei_LiteOS.elf對應的text段為74774 bytes,data段大小1444 bytes,bss段13080 bytes,dec表示前面三段大小的合計,為89268bytes。這些text、data、bss資料代表什麼?有什麼意義?我們繼續,後文中會詳細解釋。

LiteOS 映象分析特性

點選LiteOS Studio工具欄的調測工具Debug Tools按鈕,開啟除錯工具,選擇映象分析,這就是本文要給大家介紹的LiteOS Studio的映象分析工具。填寫可執行檔案路徑、Map檔案路徑等,如圖:

記憶體區域

記憶體區域頁面評估分析LiteOS開發板工程對記憶體的細分使用情況。對於STM32F429IGTx開發板,顯示的記憶體區域region包含FLASH、RAM、CCMRAM,展示的資訊包含每個記憶體區域的名稱、起始記憶體地址、總大小、空閒大小、已用大小,使用比例。在這個記憶體區域頁面,除了數值展示分析,還提供餅圖可以宏觀的評估每個區域的使用、剩餘情況。如下圖所示,FLASH總大小 1024Kb,RAM總大小192Kb,對FLASH、RAM的使用率較低,剛剛超7%。對於CCMRAM更是沒有使用,CCM(Core CoupledMemory)是給STM32F4核心專用的全速64KB RAM。

詳細資訊

繼續點選詳細資訊選項卡開啟映象分析詳細資訊頁面,該頁面展示每個記憶體區域包含的記憶體段section,記憶體段包含的符號symbol的詳細資訊。 比如FLASH下面包含.isr_vector、.text、.rodata等記憶體段, 記憶體段又包含分配在該段的程式符號。每一行展示的資訊包含執行地址VMA(Virtual Memory Address)、裝載地址LMA(Load Memory Address)、記憶體段/符號的大小。其中,LMA表示程式裝載的記憶體地址;VMA表示程式執行時的記憶體地址。嵌入式系統中RAM記憶體空間有限,一般把程式放在FLASH中,LMA地址為Flash中的地址,等到程式執行時,再載入到RAM中的執行地址VMA。記憶體段.data、.vector_ram就屬於這種情況,VMA、LMA地址不一樣,並且在FLASH、RAM均出現。

在使用詳情頁面,支援排序和搜尋過濾,支援程式符號快速跳轉到原始碼行。我們可以很直觀的評估每個記憶體段、程式符號的使用大小情況,可以快速定位到潛在可最佳化的資源消耗大戶。

如圖:

從映象分析圖表中,可以看出text、data段存放在Flash儲存,data、bss段資料存放在RAM儲存。那麼,連結器linker是怎麼知道如何把各個段的符號資料存放在ROM、RAM的?這就要靠連結指令碼。

連結指令碼和Text、Data、BSS Section段

連結指令碼包含一些規則來約束連結器如何把函式、變數放到ROM或RAM,STM32F429IGTx工程的連結指令碼位置在targets\Cloud_STM32F429IGTx_FIRE\liteos.ld。我們分欄同時展示映象分析頁面和連結指令碼,如下圖,可以看出映象分析頁面展示的記憶體段使用情況和連結指令碼中所定義的是一致的,開發板的記憶體使用情況在LiteOS Studio 映象分析頁面得到非常直觀的展示。

記憶體段.ccmram在連結指令碼中沒有定義,已使用大小的也為0 byte。對於記憶體段.data、.vector_ram,連結指令碼中使用關鍵字 RAM AT> FLASH,來表示裝載地址、實際執行地址分別在FLASH、RAM。

連結指令碼片段1如下,定義了中斷處理向量.isr_vector、程式.text存放在Flash儲存,使用的關鍵字為>FLASH,其中FLASH在上文的MEMORY{......}中定義。

連結指令碼片段2如下,定義了.vector_ram、.data存放在Flash儲存,在程式啟動時,會從Flash複製到RAM。使用的關鍵字為 >RAM AT> FLASH,其中RAM在上文的MEMORY{}中定義。

連結指令碼片段3如下,定義了.bss、._user_heap_stack佔用RAM儲存。使用的關鍵字為 >RAM。

現在來總結一下,通常是這樣的:

Text段

Text儲存在只讀的ROM記憶體區域,包含向量表、程式程式碼、只讀常量資料。

Data段

表示初始化過的變數。儲存在FLASH、RAM。連結器分配data段資料在Flash區域,在startup啟動時,從ROM中複製到RAM。ROM中儲存的是隻讀的副本,開發板重啟也不會改變;RAM中儲存的是讀寫副本,在程式執行過程中,變數值可能會變化。

BSS段

表示未初始化的變數。RAM中未初始化的資料,在程式啟動時初始化為0。

其他記憶體段

.user_heap_stack記憶體堆,malloc()申請記憶體使用此區域;.ARM.attributes、.debug_frame等儲存除錯資訊。

Map對映檔案、ASM反彙編檔案

在程式編譯連結時需要指定連結指令碼,編譯成功後會生成map對映檔案,儲存程式、資料的記憶體對映資訊。對映檔案是比較重要的輔助分析檔案,可以獲取程式中的函式、變數如何分配到RAM、ROM。在使用映象分析功能的時候,我們指定了Map對映檔案

out\Cloud_STM32F429IGTx_FIRE\Huawei_LiteOS.map。反彙編檔案是另外一個比較重要的檔案,如果一個函式佔用了太多的text程式碼段、data資料段時,此時可以分析反彙編程式碼。

利用映象分析特性結合反彙編檔案,我們很方便評估函式是否可以進一步最佳化改進。以main函式為例,在對映檔案中的片段如下, main函式的存放地址為0x08000ea0,函式佔用空間大小0x38 bytes(=56 bytes)。

這個資料在LiteOS Studio映象分析頁面也可以快速查閱到:

下面是main()函式反彙編片段。可以看出,我們是C程式碼和反彙編混合展示的。第一列8000ea0是地址,第二列是彙編指令的機器碼、然後是彙編程式碼。

函式開始地址為0x8000ea0,結束地址為0x8000ed4,函式佔用空間大小=0x8000ed4-0x8000ea0+0x4=0x38bytes。如果函式長度過長,結合分析反彙編程式碼行,進行定位最佳化。

動手試驗時間

我們動手編碼建立些不同型別的變數、函式,看看這些會分配到哪些記憶體段,實際分配是否符合我們已掌握的知識。增加下述程式碼片段到targets\Cloud_STM32F429IGTx_FIRE\Src\user_task.c檔案中的函式UINT32 app_init(VOID)的上方,在該UINT32app_init(VOID)函式內首行增加對 ABC_FunName(0);的呼叫。

重新編譯,點選映象分析頁面的重新整理按鈕重新展示。我們新增的符號都以ABC_開頭,我們以這個關鍵字搜尋一下,可以看出來,ABC_FunName函式屬於.text程式碼段,全域性初始化的變數ABC_global_init屬於.data段,全域性未初始化變數ABC_global_noInit屬於.bss段。靜態函式ABC_Static_FunName、函式棧沒有在這個區域展示。這符合我們已掌握的知識,如下圖,大家也可以自行嘗試一下。

本文介紹了嵌入式開發中的記憶體佈局、連結指令碼,對映檔案,透過例項演示瞭如何利用LiteOS Studio的映象分析特性,如何結合反彙編檔案來評估函式空間佔用。 LiteOS Studio是我們LiteOS物聯網開發的利器!歡迎大家去使用這個特性,並分享使用心得,有任何問題、建議,都可以留言給我們https://gitee.com/LiteOS/LiteOS_Studio/issues。謝謝。

22
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 為什麼現代系統需要一個新的程式設計模型?