Hello world fails to build in 8.x but runs fine in 7.11.0

Description

My hello world demo, which works on 7.11.0, won’t build on 8.x. I’m getting some warnings about library stuff, but no errors about my own code, and then I just get this error:

"region `dram0_0_seg’ overflowed by 1301976 bytes
collect2: error: ld returned 1 exit status
*** [.pio/build/esp32-s3-devkitc-1-n8/firmware.elf] Error 1

What MCU/Processor/Board and compiler are you using?

ESP32, VS Code PlatformIO extension using Arduino platform and LVGL 8.3.7 (platformIO library)

What do you want to achieve?

I want to display “hello” then “world” and have the words change every second. Once it’s working, I’m going to migrate my remote controlled car dashboard to LVGL.

What have you tried so far?

Updated lv_conf.h using the 8.x template, updated function calls to 8.x where appropriate.
I’ve spent days asking chatgpt and googling and reading everything I can. This is as stripped down as I can get it. I’m hoping I’m missing something obvious.
-I tried cleaning the library and rebuilding it, and I got an error that took me to a github page about too many rebuilds requested, which I didn’t understand.

Code to reproduce

#include <TFT_eSPI.h> // Include the graphics library
#include <lvgl.h>

#define LV_HOR_RES_MAX 240
#define LV_VER_RES_MAX 320

TFT_eSPI tft = TFT_eSPI(); /* Create instance of the TFT_eSPI class */

// Buffer for LittlevGL to draw
static lv_disp_draw_buf_t disp_buf;
static lv_color_t buf[LV_HOR_RES_MAX * LV_VER_RES_MAX * 10]; // Declare a buffer for 10 lines

// Called by the LittlevGL library to write to the display // eSPI
void disp_flush(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * color_p)
{
    uint32_t w = (area->x2 - area->x1 + 1);
    uint32_t h = (area->y2 - area->y1 + 1);

    tft.startWrite();
    tft.setAddrWindow(area->x1, area->y1, w, h);
    tft.pushColors((uint16_t *)color_p, w * h, true);
    tft.endWrite();

    lv_disp_flush_ready(disp);
}

void lvgl_init() {
    // Initialize LVGL
    lv_init();

    // Initialize your display buffer
    lv_disp_draw_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);

    // Initialize a display driver
    lv_disp_drv_t disp_drv;               /*Descriptor of a display driver*/
    lv_disp_drv_init(&disp_drv);          /*Basic initialization*/
    disp_drv.hor_res = LV_HOR_RES_MAX;
    disp_drv.ver_res = LV_VER_RES_MAX;
    disp_drv.flush_cb = disp_flush;    /*Set your driver function*/
    disp_drv.draw_buf = &disp_buf;
    // disp_drv.buffer = &disp_buf;          /*Assign the buffer to the display*/
    lv_disp_drv_register(&disp_drv);      /*Finally register the driver*/

    // Initialize TFT
    tft.begin();
    tft.setRotation(3); // Use landscape orientation
}

lv_obj_t *label; // global
void create_hello_world_label() {
    label = lv_label_create(lv_scr_act()); // create a label on the default (active) screen
    lv_label_set_text(label, "Hello, world!"); // set the label text
    lv_obj_center(label); // center the label on the screen
}

void setup() {
    Serial.begin (115200);  // Open serial port
    // Initialize the display
    lvgl_init();

    create_hello_world_label();
}


// Add an array of words to cycle through
const char* words[] = {"Hello", "World", "ESP32", "Arduino", "LVGL"};
const int num_words = sizeof(words) / sizeof(words[0]);  // Calculate the number of words
int word_index = 0;  // Start with the first word

void update_hello_world_label(const char* word) {
    lv_label_set_text(label, word);  // Update the label text
    lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); // Re-center the label on the screen
}

unsigned long last_serial_time = millis();
unsigned long current_serial_time = last_serial_time;
unsigned long last_time = millis();
unsigned long current_time = last_time;

void loop() {
    current_time = millis();
    lv_tick_inc(current_time - last_time);
    last_time = current_time;
    // Update the display
    lv_task_handler();
    current_serial_time = millis();
    if (current_serial_time - last_serial_time == 1000) {
        last_serial_time = current_serial_time;
        // Update the hello world text every second
        word_index = (word_index + 1) % num_words;  // Cycle through the words
        update_hello_world_label(words[word_index]);  // Update the label with the new word
    }

    delay(1); // Allow some delay for system tasks
}

seems your keyboard make glitch here right is /10

Great catch! So now it builds, but the device immediately enters a reboot loop.

Rebooting…
␀�ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0xc (RTC_SW_CPU_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)
Saved PC:0x4204cd52
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3808,len:0x3ac
load:0x403c9700,len:0x9b4
load:0x403cc700,len:0x28d8
entry 0x403c98bc
Core 1 register dump:
PC : 0x420081b5 PS : 0x00060a30 A0 : 0x8200c46b A1 : 0x3fcebd30
A2 : 0x00000009 A3 : 0x3fc9a234 A4 : 0x3fc9a234 A5 : 0xfffffffe
A6 : 0x00000130 A7 : 0x00000000 A8 : 0x00000001 A9 : 0x3fcebd10
A10 : 0x3fcebd30 A11 : 0x00000000 A12 : 0x00000002 A13 : 0x019b0000
A14 : 0x00000000 A15 : 0x00000000 SAR : 0x00000020 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000021 LBEG : 0x42008192 LEND : 0x4200819d LCOUNT : 0x00000000

Backtrace: 0x420081b2:0x3fcebd30 0x4200c468:0x3fcebd80 0x42001f08:0x3fcebdb0 0x42028419:0x3fcebdd0

ELF file SHA256: bf141757a33c8a3a

This is question???

Thank you for calling that out, my bad :grinning:
What I’ve found: All of the code runs properly, and I can get Serial printlns to show up, as long as I comment out lv_task_handler(); If I run the lv_task_handler, I get the reboot loop. I now have three questions:

  1. Is there anything in this code that could cause an immediate reboot loop?
  2. If not, is there anything in lv_conf.h that could be doing it?
  3. How would you go about troubleshooting this?

Add into platformio.ini monitor line

monitor_filters = esp32_exception_decoder, default

this show you backtrace info…
And my tip issue is you espi config. Before lvgl use you need working display part.
Too maybe lvconf file mistakes is possible …

This code needs to be placed before your LVGL init code.

Also, what ESP are you using? and if it is the S3 how much RAM does it have. I would also like to know what pins you have the display attached to.

It seems to be some kind of a hardware issue. Read here.

some suggestions as to what can be causing it are in that link.

Here is one solution
“Solution is press boot button on the esp32 board when run the code, its simple”

The ESP is an espressif esp32-s3-devkitc-1-n8, if I’m reading their site correctly, it has 8 MB QD Flash RAM.

For Pins I have:
TFT_MISO 13
TFT_MOSI 11
TFT_SCLK 12
TFT_CS 10 // Chip select control pin
TFT_DC 3 // Data Command control pin
TFT_RST -1 // Set TFT_RST to -1 if display RESET is connected to ESP32 board RST
TOUCH_CS 39 // Chip select pin (T_CS) of touch screen

What’s odd is that if I don’t use LVGL, I can use TFT-eSPI or Adafruit for a simple hello world. And I can use LVGL 7.11.0 with either driver for a more complex hello world. It’s only LVGL 8.3.7 that gives me the boot loop. The reset button didn’t help :frowning: I also see something in the link you shared about changin Flash Frequency to 40 from 80, will see if I can find that setting in VSCode Platformio

Here is the backtrace info. I think my tft_espi config is ok because it works with LVGL 7.11.0
I was looking at lv_conf.h for 8.3.7 but the only lines I’ve changed are:
#if 1 /*Set it to "1" to enable content*/
and

/*Use a custom tick source that tells the elapsed time in milliseconds.
*It removes the need to manually update the tick with `lv_tick_inc()`)*/
#define LV_TICK_CUSTOM 0

i’ve tried manually doing lv_tick_inc(), and I’ve tried setting this to 1 and commenting out my lv_tick_inc()). The rest of that file is just how it was as a template.

Backtrace: 0x420083db:0x3fcebd30 0x4200c42c:0x3fcebd80 0x42001ecf:0x3fcebdb0 0x420283dd:0x3fcebdd0

#0 0x420083db:0x3fcebd30 in get_max_row at .pio/libdeps/esp32-s3-devkitc-1-n8/lvgl/src/core/lv_refr.c:970
(inlined by) refr_area at .pio/libdeps/esp32-s3-devkitc-1-n8/lvgl/src/core/lv_refr.c:577
(inlined by) refr_invalid_areas at .pio/libdeps/esp32-s3-devkitc-1-n8/lvgl/src/core/lv_refr.c:532
(inlined by) _lv_disp_refr_timer at .pio/libdeps/esp32-s3-devkitc-1-n8/lvgl/src/core/lv_refr.c:324
#1 0x4200c42c:0x3fcebd80 in lv_timer_exec at .pio/libdeps/esp32-s3-devkitc-1-n8/lvgl/src/misc/lv_timer.c:313
(inlined by) lv_timer_handler at .pio/libdeps/esp32-s3-devkitc-1-n8/lvgl/src/misc/lv_timer.c:109
#2 0x42001ecf:0x3fcebdb0 in loop() at .pio/libdeps/esp32-s3-devkitc-1-n8/lvgl/src/lv_api_map.h:37
(inlined by) loop() at src/main.cpp:87
#3 0x420283dd:0x3fcebdd0 in loopTask(void*) at ~/.platformio/packages/framework-arduinoespressif32/cores/esp32/main.cpp:50

I’ve moved the lines accordingly, but I’m still in a boot loop :frowning:

Pin 39 you cannot use. That is reserved for the SPIRAM I believe. I will double check the ESP32 data sheet on that. want to say 37, 38 and 39 are reserved.

EDIT

It’s pins 35, 36, 37 if you have octal SPIRAM and or octal SPI Flash. Your board is using quad so you should be fine.

OK so you have the version that only has additional flash memory and no additional RAM so your pins are fine.

What size display are you using. the amount of memory the ESP32 has is very small and you could be using it all. Between platformio, LVGL, tft_espi and the ESPIDF I wouldn’t be surprised if that is what is happening. The ESP32 you have has 512k of RAM. depending on your display resolution this could cause an issue. if you are using say a 800 x 600 display you will be consuming almost 100K just for the buffer alone. I believe if you use tft_espi there is quite a bit of additional overhead from using that.

what version of the ESP IDF are you using? I would upgrade it if possible as that was one of the solutions for the boot issue you are having.

The screen is 320 x 240.
I don’t believe we’re using ESPIDF as its own library, we import Arduino.h and have access to ESPIDF stuff through that though.
The TFT+eSPI version is bodmer/TFT_eSPI@^2.5.31

When I build and upload, I see this in the terminal:

Advanced Memory Usage is available via “PlatformIO Home > Project Inspect”
RAM: [=== ] 26.3% (used 86232 bytes from 327680 bytes)
Flash: [= ] 14.5% (used 486273 bytes from 3342336 bytes)

I thought the display driver libraries use the ESPIDF. The ESPIDF MUST be present in order for you to be able to use the Arduino IDE. It’s a portion of the IDF anyway. but it is there.

I would also double check that you have the SPIRAM turned off.

I’ve been searching for ways to do that explicitly, do you know how?
Here’s my platformio.ini config, I think that using the board = line tells platformio that i don’t have SPIRAM

platform = espressif32
board = esp32-s3-devkitc-1
framework = arduino
board_build.mcu = esp32s3
board_build.f_cpu = 240000000L
board_build.f_flash = 80000000L
board_build.flash_mode = dio
monitor_speed = 115200
build_flags = ‘-D ESP32_S3_DEVKIT’
upload_speed = 900000

lib_deps =
lvgl/lvgl@^8.3.7
bodmer/TFT_eSPI@^2.5.31

monitor_filters = esp32_exception_decoder, default

I haven’t seen anything in the code, or in lv_conf.h or User_Setup.h about SPIRAM

I don’t know anything about platformio. I can tell you that the error you are getting is hardware related error. It’s a hardware error due to software settings.