1. 程式人生 > >使用Python分析ELF文件優化Flash和Sram空間的案例

使用Python分析ELF文件優化Flash和Sram空間的案例

其中 靜態 特性 ons 空間優化 uart 實現 top odata

1. 背景

Zephyr項目Flash和Ram空間比較緊張,有著非常強烈的優化需求。

優化的前提是量化標的,那麽如何量化Flash和Ram的使用量呢?

在量化之後,首先要對量化結果進行分析,然後采取措施進行空間優化。

2. 基於ELF信息和linker.cmd分析Flash/Ram使用量

linker.cmd文件中規定了不同section在Flash還是在Ram中,還是兼而有之。

這是一個很有用的信息,基於此我們只需要去羅列每個section的symbol,然後統計大小;就可以知道section的信息;進而知道都有那些symbol在(Flash, Ram)中,都與多大。

分析ELF文件可以獲得Sections和Symbols的詳細信息。

Sections信息可以將,Sections的Index和Name對應起來。

Symbols信息可以將Symbol的Name、Size、Index和Sections的Index對應起來。

這樣子就可以對ELF文件形成ELF-->Sections-->Symbols的樹形結構關系。

分析腳本在:elf_analyze_pro.ipynb。

輸出結果是每個sections中symbol大小降序排列的csv文件,和顯示最高top_counts個大小列表。

3. 分析Flash/Ram使用情況

從Flash/Ram總大小使用情況,可以看出Ram空間告急,Flash空間也不樂觀。

由於每個Section按降序排列了所有符號表,所以從最大入手效果最明顯。

同時不同Section都有自己的特性,是A.僅在Ram中,還是B.僅在Flash中,還是C.兩者都占用。

優化的首要目標是C情況,如果能將其從Ram中移出,僅在Flash中使用,那最好不過了。不過肯定會降低速度。

其次優化A情況,靜態變量改成動態分配。針對變量分配浪費情況:不需要的結構體成員、變量類型緊湊等等。

最後是B情況,去掉冗余Log信息,將inline類型函數改成普通函數等等。

4. 優化記錄

4.1 通過const修飾變量,將變量從datas轉移到rodata

由於Section datas既占用了Flash又占用了Sram,存在一些變量可以修改成const類型,即只讀變量。

就可以將此Symbol轉移到rodata區域,使用的時候從Flash讀取。

4.2 通過k_malloc從mem pool中動態申請內存

申請靜態大變量,簡單省事不易錯,但是浪費了有限的Ram空間。

如果可以通過k_malloc從Mem pool中申請,將有助於提高Sram的利用率。

4.3 刪除冗余結構體成員

比如struct uart_driver_api中很多成員,沒有實現,也不會使用到。將其中部分成員註釋掉,有助於降低結構體實例大小。

4.4 變量超配情況

一個標誌位這種情況就沒有必要使用int32這樣的類型了。

4.5 inline類型函數的廢棄

在CPU速度較慢但是ROM空間較大的系統中,使用inline有助於利用空間換時間。

但是在空間非常緊張的系統中,這就變成了缺點。將inline修飾符去掉,該成普通函數,將節省空間,雖然會增加函數調用開銷。

4.6 控制Log使用量

Log存在分級,所以不需要的Log就不需要編譯。

在量產的時候,關閉Log,節省的空間非常可觀。

5. 結語

當然優化的路沒有盡頭,邊走邊記錄吧。

使用Python分析ELF文件優化Flash和Sram空間的案例