How do I correctly make the SD Card work for image widgets on an ESP32 Dev Kit with LVGL v.8.3?

Description

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

ESP 32 Devkit on Arduino IDE

What LVGL version are you using?

8.3

What do you want to achieve?

Setup File system to be able to use an image on an SD Card for LVGL widgets

What have you tried so far?

Code to reproduce

/*Initialize your Storage device and File system.*/
static void fs_init(void)
{
    // E.g. for FatFS initialize the SD card and FatFS itself
    // SD Card Initialization

    if (!SD.begin()) {
      Serial.println("Card Mount Failed");
      return;
    }

    uint8_t cardType = SD.cardType();

    if (cardType == CARD_NONE) {
      Serial.println("No SD card attached");
      return;
    }

    Serial.print("SD Card Type: ");
    if (cardType == CARD_MMC) {
      Serial.println("MMC");
    } else if (cardType == CARD_SD) {
      Serial.println("SDSC");
    } else if (cardType == CARD_SDHC) {
      Serial.println("SDHC");
    } else {
      Serial.println("UNKNOWN");
    }
  
    uint64_t cardSize = SD.cardSize() / (1024 * 1024);
    Serial.printf("SD Card Size: %lluMB\n", cardSize);
    
    Serial.println( "Setup done" );
}

static void * sd_fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode)
{
    File *fp = (File *)lv_mem_alloc(sizeof(File));
    if (fp == NULL)
      return NULL;
    File mySDfile = *fp;

    // Make the path relative to the current directory (the projects root folder)
    char buf[256];
    sprintf(buf, "/%s", path);

    if (mode == LV_FS_MODE_WR)
    {
      // Open a file for write
      mySDfile = SD.open(buf,  FILE_WRITE);
    }
    else if (mode == LV_FS_MODE_RD)
    {
      // Open a file for read
      mySDfile = SD.open(buf, FILE_READ);
    }
    else if (mode == (LV_FS_MODE_WR | LV_FS_MODE_RD))
    {
      // Open a file for read and write
      mySDfile = SD.open(buf,  FILE_WRITE);
    }

    mySDfile = SD.open(buf);
    //make sure at the beginning
    mySDfile.seek(0);

    *fp = mySDfile;

    return fp;
}

static lv_fs_res_t sd_fs_close(lv_fs_drv_t *drv, void *file_p)
{
  File *fp = (File *)file_p;

  fp->close();

  delete (fp); // when close
  return LV_FS_RES_OK;
}

static lv_fs_res_t sd_fs_read(lv_fs_drv_t *drv, void *file_p, void *fileBuf, uint32_t btr, uint32_t *br)
{
    lv_fs_res_t res = LV_FS_RES_NOT_IMP;

    return res;
}

static lv_fs_res_t sd_fs_seek(lv_fs_drv_t *drv, void *file_p, uint32_t pos, lv_fs_whence_t whence)
{
  lv_fs_res_t res = LV_FS_RES_OK;

  File *fp = (File *) file_p;

  // commented out because it is throwing an error
  /* if (whence == LV_FS_SEEK_SET)
  {
      fp->seek(pos, 0);
  }
  if (whence == LV_FS_SEEK_CUR)
  {
      fp->seek(pos, 1);
  }
  if (whence == LV_FS_SEEK_END)
  {
      fp->seek(pos, 2);
  } */
  
  fp->seek(pos);
  return res;
}

static lv_fs_res_t sd_fs_tell(lv_fs_drv_t *drv, void *file_p, uint32_t *pos_p)
{
  File *fp = (File *)file_p;
  *pos_p = fp->position();

  return LV_FS_RES_OK;
}

void sd_fs_init(void)
{
    fs_init();

    /*Add a simple drive to open images*/
    static lv_fs_drv_t fs_drv;
    lv_fs_drv_init(&fs_drv);

    /*Set up fields...
    To use files in image widgets the following callbacks are required:
    - open
    - close
    - read
    - seek
    - tell
    */

    fs_drv.letter = 'S';
    fs_drv.open_cb = sd_fs_open;
    fs_drv.close_cb = sd_fs_close;
    fs_drv.read_cb = sd_fs_read;
    fs_drv.seek_cb = sd_fs_seek;
    fs_drv.tell_cb = sd_fs_tell;
    fs_drv.write_cb = NULL;
    fs_drv.dir_close_cb = NULL;
    fs_drv.dir_open_cb = NULL;
    fs_drv.dir_read_cb = NULL;

    lv_fs_drv_register(&fs_drv);
    Serial.println("drv registered!");
}


void setup()
{
...


    sd_fs_init();

    lv_obj_t * img_bin = lv_img_create(lv_scr_act());
    lv_img_set_src(img_bin, "S:Baboon40.bin");
    lv_obj_align(img_bin, LV_ALIGN_CENTER, 0, 0);
...
}

Screenshot and/or video

This compiles with no errors but when uploaded to my ESP32, it goes into a boot loop with this logs:

SD Card Type: SDHC
SD Card Size: 14910MB
Setup done
drv registered!
Guru Meditation Error: Core  1 panic'ed (InstrFetchProhibited). Exception was unhandled.

Core  1 register dump:
PC      : 0x00000000  PS      : 0x00060230  A0      : 0x800ef870  A1      : 0x3ffb26e0  
A2      : 0x3ffc1348  A3      : 0x3ffc5044  A4      : 0x3ffb2788  A5      : 0x00000004  
A6      : 0x3ffb26f8  A7      : 0xff000000  A8      : 0x800d18cc  A9      : 0x3ffb26b0  
A10     : 0x3ffc5044  A11     : 0x00000000  A12     : 0x00000000  A13     : 0x3f400e94  
A14     : 0x00000000  A15     : 0x3ffc4e48  SAR     : 0x0000001c  EXCCAUSE: 0x00000014  
EXCVADDR: 0x00000000  LBEG    : 0x40086518  LEND    : 0x40086523  LCOUNT  : 0xffffffff  


Backtrace:0xfffffffd:0x3ffb26e00x400ef86d:0x3ffb2700 0x400ddb17:0x3ffb2720 0x400de102:0x3ffb2750 0x400f513f:0x3ffb2770 0x400d1af1:0x3ffb27b0 0x400fee3a:0x3ffb2820 




ELF file SHA256: 0000000000000000

Rebooting...

Most of my references seem to be using older versions of lvgl and I’m having trouble making odds and ends of them.

Thank you!

PS: I’ve checked that the SD card works using the SD.h library example together with this tutorial:

and

I had to add a jumper to make it work (see 2nd video)

I forgot to mention that I am using an ST7796 TFT Screen

First of all install backtrace Plugin to IDE: https://github.com/me-no-dev/EspExceptionDecoder and you will see Error place.
Next: try to add check for successful file open in sd_fs_open():

    mySDfile = SD.open(buf);
+   if (!mySDfile) {
+       lv_mem_free(fp);
+       return NULL;
+    }
    //make sure at the beginning
    mySDfile.seek(0);

may be you file is not opened?

I tried using the ExceptionDecoder and here’s what it returned:

PC: 0x00000000
EXCVADDR: 0x00000000

Decoding stack results
0x400ef7e5: lv_fs_close at C:\Users\User\Documents\Arduino\libraries\lvgl\src\misc\lv_fs.c line 115
0x400dda8f: lv_img_decoder_built_in_info at C:\Users\User\Documents\Arduino\libraries\lvgl\src\draw\lv_img_decoder.c line 295
0x400de07a: lv_img_decoder_get_info at C:\Users\User\Documents\Arduino\libraries\lvgl\src\draw\lv_img_decoder.c line 99
0x400f50b7: lv_img_set_src at C:\Users\User\Documents\Arduino\libraries\lvgl\src\widgets\lv_img.c line 107
0x400d1afd: setup() at D:\clinikapps\repositories\tft_test/tft_test.ino line 271
0x400fe762: loopTask(void*) at C:\Users\User\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.4\cores\esp32\main.cpp line 42

may be you file is not opened?

How do I check this?

Does you apply my last diff?
Did you opening lv_fs.c at 115 line to chek what it doing?