lvgl 經典編譯錯誤解決之道:section `.bss' is not within region `dram0_0_seg'

#NodeMCU# #PlatformIO#或#Arduino IDE#
能規避 lvgl+TFT_eSPI 經典編譯錯誤(如下所示)的點不多。
Linking .pio\build\nodemcu\firmware.elf
ld.exe: address 0x3fffd538 of .pio\build\nodemcu\firmware.elf section `.bss' is not within region `dram0_0_seg'
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\nodemcu\firmware.elf] Error 1
因爲我們在源碼上能做的事情不多:
(1)在 lvgl 庫的 lv_conf.h 中將這個自定義內存分配標誌
/* 1: use custom malloc/free, 0: use the built-in `lv_mem_alloc` and `lv_mem_free` */
#define LV_MEM_CUSTOM 0
從0改爲1。
(2)在 TFT_eSPI 庫的 User_Setup.h 裏,選完 driver 之後,再選擇如下屏幕設置選項的其中之一
//#define ST7735_GREENTAB
//#define ST7735_GREENTAB2
//#define ST7735_GREENTAB3
#define ST7735_GREENTAB128    // For 128 x 128 display
(3)在 TFT_eSPI 庫的 User_Setup.h 裏,關閉下面的宏定義,不使用SPIFFS:
// Comment out the #define below to stop the SPIFFS filing system and smooth font code being loaded
// this will save ~20kbytes of FLASH
#define SMOOTH_FONT
同樣,在與 driver 對應的 Setup7_ST7735_128x128.h 裏,註釋掉下面的宏定義:
#define SMOOTH_FONT//註釋掉,避免spiffs-deprecation-warning
(4)在 platformio.ini 中增加一條編譯選項,表明開發板有 PSRAM 可用:
build_flags = -D BOARD_HAS_PSRAM
 
小結:
實驗證明,宏定義 LV_MEM_CUSTOM 從 0 改爲 1,對 LVGL+TFT_eSPI 編譯時不再提示
“section `.rodata' will not fit in region `dram0_0_seg'”
“section `.bss' is not within region `dram0_0_seg'”錯誤,有關鍵性幫助。這時 lvlg 將使用 stdlib.h 頭文件內的函數進行內存分配,從而可以充分使用到 SRAM 和 PSRAM 的內存。
這種錯誤說白了就是,編譯出來的數據量太大,DRAM 放不下了。我們知道,代碼被分爲許多個section,常見的如:
.bss
.text
.rodata
.data
可以簡單理解爲,IRAM 是用來存放指令的,而 DRAM 用來存放數據的。
如下圖所示, ESP32 內部存儲器(SRAM)有 3 個存儲塊 SRAM0、SRAM1 和SRAM2。
SRAM 以兩種方式使用:一種用於指令存儲,稱爲 IRAM(用於執行代碼,text 段),另一種用於數據存儲,稱爲 DRAM(用作 .bss 段,.data 段和堆)。SRAM0 和 SRAM1 可以用作連續的 IRAM,而 SRAM1 和 SRAM2 可以用作連續的 DRAM 地址空間。
0
圖1 ESP32 SRAM 佈局
編譯報錯的地址段“address 0x3fffd538”就落在上圖中的 DRAM 中。
我們再來看一下 DRAM 的內存佈局,如下圖所示。
0
圖2 DRAM 佈局
上圖顯示了應用程序的典型(簡化)DRAM 佈局。由於 DRAM 地址從 SRAM2 的末尾開始,並向後增加,因此鏈接階段空間的分配從 SRAM2 的末尾開始。
  • 前 8KB(0x3FFA_E000–0x3FFA_FFFF)用作某些 ROM 內置函數的數據空間;
  • 鏈接器緊接着將已初始化的數據段放在第一個 8KB 存儲器之後;
  • 接下來是未初始化的 .bss 段;
  • 數據段和 .bss 段之後剩餘的內存被配置爲堆,典型的動態內存分配一般分配至該位置。
所以,數據段和 .bss 段的大小取決於應用程序,lvgl 的編譯錯誤就發生於此。
 
參考資源:
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章