Help setting correct memory placement to save RAM in ESP32 (S3) + PlatformIO


My GUI seems having lots of objects. The builder (PlatformIO) sayings the RAM is reaching full. Sometimes the board is reset and the traceback debug saying related to memory allocation. If I reduce the objects in LVGL, the board stop reset & running fine.

Checking size .pio\build\esp32-s3-devkitc-1\firmware.elf
RAM: [======== ] 76.1% (used 249432 bytes from 327680 bytes)
Flash: [== ] 21.9% (used 731661 bytes from 3342336 bytes)

I tried to allocate the memory by a custom ESP32: define LV_MEM_POOL_ALLOC ps_malloc in lv_conf.h, it says fine the RAM is reduced from 76.1% to 36.1%. It is good however I afraid of the PSRAM is much slower than the internal RAM, so I do not thinking using the PSRAM option.

Instead I trying first to move some large data such as font / image definition into PSRAM or flash. In Arduino there is the PROGMEM keyword to do that but in LVGL the keyword in variable declaration is LV_ATTRIBUTE_LARGE_CONST. I cannot find any clear guide on the Internet about correct use of __attribute__ for my case, PlatformIO + VSCode + Arduino. What I tried so far was adding a new section like this:

#define LV_ATTRIBUTE_LARGE_CONST __attribute__ ((section(".psram_section")))

I found some “scripts” in ...\PlatformIO\packages\toolchain-xtensa-esp32s3\lib\ldscripts that mentioning the linker script with sections, but I don’t know how & where to set correct .psram_section that fits my target.

Please help. Thanks.

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

  • ESP32-S3-DevKitC-1-N8R2 dual USB C - 8 MB Flash, 2 MB PSRAM
  • Arduino with PlatformIO + VSCode
  • Custom display driver for 8-bit 16 bpp parallel display, not using TFT_eSPI but myself code for LT7683 parallel LCD driver chip.

What LVGL version are you using?


What do you want to achieve?

Trying to save some space in RAM by putting large read only variables into other places.

What have you tried so far?

If I replace the lv_conf.h

        #undef LV_MEM_POOL_INCLUDE
        #undef LV_MEM_POOL_ALLOC

with the custom PSRAM mem allocator for ESP32 lib (got these code on the Internet):

    #ifdef ESP32
    # if LV_MEM_ADR == 0
    #     define LV_MEM_POOL_INCLUDE <esp32-hal-psram.h>
    #     define LV_MEM_POOL_ALLOC ps_malloc
    # endif

The estimated RAM consumming is saying countable low:

RAM: [==== ] 36.1% (used 118360 bytes from 327680 bytes)
Flash: [== ] 21.9% (used 731673 bytes from 3342336 bytes)

However, I afread of PSRAM is much slower than the internal RAM, so I trying to not use the PSRAM for all memory allocation.

Code to reproduce

    #ifdef ESP32
    # if LV_MEM_ADR == 0
    #     define LV_MEM_POOL_INCLUDE <esp32-hal-psram.h>
    #     define LV_MEM_POOL_ALLOC ps_malloc
    # endif


#define LV_ATTRIBUTE_LARGE_CONST __attribute__ ((section(".psram_section")))

Screenshot and/or video

Putting some more functionals I see the RAM even increased into ~300%

Advanced Memory Usage is available via “PlatformIO Home > Project Inspect”
RAM: [==========] 297.1% (used 973488 bytes from 327680 bytes)
Flash: [=== ] 34.7% (used 1161225 bytes from 3342336 bytes)

I manually increase the dram0_0_seg len to bigger value in \PlatformIO\packages\framework-arduinoespressif32\tools\sdk\esp32s2\ld\memory.ld in order to be able to build the ELF file.

Then use the tool Binary Size Analysis for ELF that is so it can visual all the biggest mem alloc in a pie chart:

It tells me how much percent the fonts cost, and the biggest mem in .dram0.bss section is because of my LVGL Canvas buffer allocation, it costs 778 KB (cbuf):


    lv_obj_t * canvas = lv_canvas_create(ui_Panel_O_Vuong);
    lv_canvas_set_buffer(canvas, cbuf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_IMG_CF_TRUE_COLOR);

Now I sure need to move the embeded fonts, image & the canvas buffer into other part out off DRAM…
Maybe using ps_malloc manually for placing into PSRAM… Will try and report later.