Best way/configuration to load img from Fatfs

Hello there :slight_smile:

Description

I’m trying to understand which is the best configuration to open image file from FATFS on ESP32.
By best configuration I mean the fastest.

First question which type of file should I use ? :

*.bin ?
*.png ?

How to configure/calculate the right cache memory for :

  • LV_MEM_SIZE
  • LV_CACHE_DEF_SIZE
  • LV_FS_FATFS_CACHE_SIZE

Furthermore, what is the limit for those cache memory, where are they store (In RAM I suppose) ?

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

Board : Custom ESP32-WROOM-32E-N16 board
IDE : platformIO
Screen : TFT ILI9341 320 x 240

What LVGL version are you using?

LVGL 9.1

What do you want to achieve?

Find the best way to load img from file (.bin, .png, jpeg)

What have you tried so far?

I’m able to load .bin image from fatfs using the bin decoder. But i’m limited to 2 or 3 images regarding their size.

I edited size of the memory (LV_MEM_SIZE) but not enought :

I edited LV_CACHE_DEF_SIZE but no enought :

Code to reproduce

LV_MEM_SIZE in lv_conf.h:

    /*Size of the memory available for `lv_malloc()` in bytes (>= 2kB)*/
    #define LV_MEM_SIZE (96 * 1024U)          /*[bytes]*/

LV_CACHE_DEF_SIZE in lv_conf.h:

/*Default cache size in bytes.
 *Used by image decoders such as `lv_lodepng` to keep the decoded image in the memory.
 *If size is not set to 0, the decoder will fail to decode when the cache is full.
 *If size is 0, the cache function is not enabled and the decoded mem will be released immediately after use.*/
#define LV_CACHE_DEF_SIZE       0//262144

LV_FS_FATFS_CACHE_SIZE in lv_conf.h :

/*API for FATFS (needs to be added separately). Uses f_open, f_read, etc*/
#define LV_USE_FS_FATFS 1
#if LV_USE_FS_FATFS
    #define LV_FS_FATFS_LETTER 'A'     /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
    #define LV_FS_FATFS_CACHE_SIZE 1024    /*>0 to cache this number of bytes in lv_fs_read()*/
#endif

I’m looking forward to your suggestions.
Thnaks,
Thomas.

Hello,

As for the first question: the type of file you should use is dependant on what kind of decoders you have on your device. I believe pngs are compressed files (uses less space) than .bin, but if your device does not have hardware to decode PNGs, it’s no use.
Keep in mind that the difference between .bin and .png is largely in compression - the final image that has to be loaded into RAM will mostly be the same and still take up large amounts of space in memory.

As for the cache, your LV_MEM_SIZE should be at least as big as the memory your UI usually takes, plus whatever size your largest image is. I believe that is the issue here at this point, LVGL is trying to allocate 230.403 bytes, but you only have 98.304 bytes (96 KB) available for it to allocate. I suggest setting
LV_MEM_SIZE to (240 * 1024U) if your device allows it.

as for LV_CACHE_DEF_SIZE, I’m not sure. Try setting LV_MEM_SIZE first.

Hello Tinus,

Thanks for your feedback, I now see things a bit more clearly.

If I remember well, I tried to increase LV_MEM_SIZE to (128 * 1024U).
There was an error indicating that there is not enough memory for malloc().

I will share the screenshot as soon as I get home.

Thomas.

The error when setting the memory to #define LV_MEM_SIZE (240 * 1024U) /*[bytes]*/

c:/users/pataone/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch3/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio\build\esp32dev\firmware.elf section `.dram0.bss' will not fit in region `dram0_0_seg'
c:/users/pataone/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch3/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: DRAM segment data does not fit.
c:/users/pataone/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch3/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: DRAM segment data does not fit.
c:/users/pataone/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch3/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: region `dram0_0_seg' overflowed by 138888 bytes
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\esp32dev\firmware.elf] Error 1

As I feared, your device does not have enough RAM to allow your LV_MEM_SIZE to be this big. To be honest I am not sure if this is even possible on your microcontroller, is it perhaps an option to use smaller images? If they have to be large, is it an option to create these images at compile-time? See Images — LVGL documentation

You can use the image converter tool to create a .c file from a png.

Hello Tinus,

So far, this is what I have used. I used the online image converter tool and declared my images directly in the code with ‘LV_IMAGE_DECLARE(my_icon_dsc)’.

I now wanted to put my images in FATFS memory. I see that it’s more complicated than I thought :sweat_smile:

So now I see two solutions :

  • Do not use Fatsfs memory and modify the partition on the ESP32. The goal is to reduce the size of the FATFS memory to increase the size of the program memory (where the images will be stored using .c file).

  • Or switch to another ESP32 module with more RAM, maybe the ESP32-S3-WROOM-1 with 8MB PSRAM will be a good candidate.

But how can I be sure that 8MB of RAM will be enought. How can I know the memory my UI will take as you said earlier ?

Thanks,
Thomas.

There are a few things that use a lot of RAM. Those being:

  • LVGL draw buffer(s): these are used for the partial draw operations if you use those.
  • Internal frame buffers if your device supports these, this may be the size of your entire display… I don’t know if the ESP32-WROOM-32E-N16 has this- but on an MCU I use this takes up about 260 KB of RAM already.
  • LVGL memory: this is basically your LVGL “RAM”, it uses this as a memory space in which to “allocate” RAM (the entire area is actually already alocated on compile), memory here gets used and freed as you create and delete objects of any kind.
    To see how much of this “LVGL MEMORY” your UI uses, you can turn on the performance monitor in your lv_conf.h.
    Set
    #define LV_USE_SYSMON 1 and LV_USE_MEM_MONITOR 1. Now see what happens to this memory when you load in an image from your filesytem, my guess is that it will increase a lot.

Hope this helps.

Hello Tinus,

That helped me a lot. Thank you.

I will order new ESP32-S3-WROOM-1 with 8MB PSRAM modules as I said and test it out.
As the module is only around 3€, it’s no very expensive.

Thomas.