Fail to read file with STDIO (v8.4.0)

Description

I’m unable to read a file using STDIO

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

ESP32-WROOM (ESP32-2432S032C board)
PlatformIO

What LVGL version are you using?

8.4.0

What do you want to achieve?

Read a file from filesystem using STDIO

What have you tried so far?

I first confirmed I can upload a file, and read it with SPIFFS.

platformio.ini

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
board_build.partitions = no_ota.csv
...

I placed a file icon.gif (size 4614 bytes) in the data subdir of my project.
Then used PlatformIO Project Tasks > esp32dev > Platform > Build Filesystem Image and Upload Filesystem Image to upload the file.

The following code:

#include "SPIFFS.h"

void files_init(void) {
  if (SPIFFS.begin(true)) {
    File file = SPIFFS.open("/icon.gif", FILE_READ);
    if (file) {
      uint32_t size = file.size();
      Serial.print("Size: ");
      Serial.println(size);
      file.close();
    }
    SPIFFS.end();
  }
}

reports a correct filesize:

Size: 4614

Now that I know that the file is in the filesystem, I try to open it in LVGL.

lv_conf.h

#define LV_USE_FS_STDIO 1
#if LV_USE_FS_STDIO
    #define LV_FS_STDIO_LETTER 'A' 
    #define LV_FS_STDIO_PATH "/" 
    #define LV_FS_STDIO_CACHE_SIZE 0
#endif
void files_init(void) {
  lv_fs_file_t f;
  lv_fs_res_t res;
  res = lv_fs_open(&f, "A:icon.gif", LV_FS_MODE_RD);
  if (res != LV_FS_RES_OK) {
    printf("fs_open FAIL: res=%d\n", res);
  }
  
  char letters[10];
  lv_fs_get_letters(letters);
  Serial.print("Drives: ");
  Serial.println(letters);
fs_open FAIL: res=12
Drives: A

I had a look at the source to verify that LVGL indeed has all callback functions implemented for STDIO.
I’m sure I’m missing something very obvious, but right now I’m stumped.

Tracked down where things are failing, but still don’t understand why…

fsopen() in lv_fs_stdio.c is properly called.
It calls fopen("icon.gif", "rb") but returns NULL.

Next theory was that my file was not in the correct place.
So I tried writing a new file:

void files_init(void) {
  lv_fs_file_t f;
  lv_fs_res_t res;
  res = lv_fs_open(&f, "A:test.txt", LV_FS_MODE_WR);
  printf("res: %d\n", res);
  lv_fs_close(&f);
}

Also fails with res: 12 (LV_FS_RES_UNKNOWN).

maybe try to add / to path lv_fs_open(&f, "A:/icon.gif", LV_FS_MODE_RD);

I tried adding the /, and also tried with uppercase name.
Still fails with LV_FS_RES_UNKNOWN.

so it seems there is no binding fopen()SPIFFS.open(). And if you just call fopen("icon.gif", "rb") file will not open. I don’t know how to configure PlatfomIO to link stdio with SPIFFS (if this is possible).
Maybe somebody will help with it.

Anyway you can use lv_fs - driver . In this case you need ro realize open(), close(), read() function which will use SPIFFS.open/close/read functions. Here, here, here some examples.

I must be missing something.

Isn’t the whole idea of setting #define LV_USE_FS_STDIO 1 in lv_conf.h that all callbacks are predefined in lv_fs_stdio.c?

Your are correct. So in this case when you call lv_fs_open() fs_open() from lv_fs_stdio.c called, where in turn fopen(buf, flags) is called. But it seems the problem is that the fopen()does not open the file from SPIFFS. Maybe there is some option in IDE to configure stdio to use SPIFFS.

I’m showing my lack of knowledge about ESP32 filesystem here :grin:
Back to the docs to see if I can make sense of this…

Ok, at least I have an explanation for the LV_FS_RES_UNKNOWN I think.
After including stdlib.h I now get an LV_FS_RES_NOT_EX, which makes sense if STDIO is not supported.

Did a (partial) implementation of an SPIFFS driver.
Things were very confusing, as all examples I had were using different (older?) function signatures.
lv_img_set_src with a file from “disk” is now working :tada: