






























#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 地址空间。

图1 ESP32 SRAM 布局
编译报错的地址段“address 0x3fffd538”就落在上图中的 DRAM 中。
我们再来看一下 DRAM 的内存布局,如下图所示。

图2 DRAM 布局
上图显示了应用程序的典型(简化)DRAM 布局。由于 DRAM 地址从 SRAM2 的末尾开始,并向后增加,因此链接阶段空间的分配从 SRAM2 的末尾开始。
所以,数据段和 .bss 段的大小取决于应用程序,lvgl 的编译错误就发生于此。
参考资源:
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。