Compile error in lv_fs_fatfs.c when attempting to use sdmmc

ESP-IDF V6.01 lvgl 9.5

project build fails with the following error:

C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/15.2.0/../../../../riscv32-esp-elf/bin/ld.exe: esp-idf/lvgl__lvgl/liblvgl__lvgl.a(lv_fs_fatfs.c.obj): in function `fs_dir_read':
C:/ESP-IDF Projects/Latest-version-V6-compatible/Waveshare/Test_fatfs/managed_components/lvgl__lvgl/src/libs/fsdrv/lv_fs_fatfs.c:278:(.text.fs_dir_read.part.0.constprop.0+0x48): undefined reference to `f_readdir'
collect2.exe: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

The failure appears to be in this section the loop starts at line 268:

    do {
        res = f_readdir(dir_p, &fno);
        if(res != FR_OK) return LV_FS_RES_UNKNOWN;

        if(fno.fname[0] == 0) break; /* End of the directory */

        if(fno.fattrib & AM_DIR) {
            lv_snprintf(fn, fn_len, "/%s", fno.fname);
        }
        else lv_strlcpy(fn, fno.fname, fn_len);

    } while(lv_strcmp(fn, "/.") == 0 || lv_strcmp(fn, "/..") == 0);

    return LV_FS_RES_OK;
}

This is my project code:

#include <stdio.h>
#include <stdlib.h>
#include "esp_log.h"
#include "vfs_fat_internal.h"
#include "sdmmc_cmd.h"
#include "driver/sdmmc_host.h" // Updated for ESP-IDF v6.0 legacy driver refactoring
#include "tinyusb.h"
#include "tusb_msc_storage.h"

static const char *TAG = "sd2pc";
static sdmmc_card_t *s_card = NULL;

esp_err_t sd2pc_init_storage(void)
{
    ESP_LOGI(TAG, "Configuring SDMMC peripheral storage layer...");

    sdmmc_host_t host = SDMMC_HOST_DEFAULT();

    // Waveshare ESP32-P4-Nano board paths utilize high-speed 4-bit configurations
    sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
    slot_config.width = 4;

    esp_err_t ret = sdmmc_host_init();
    if (ret != ESP_OK)
        return ret;

    ret = sdmmc_host_init_slot(host.slot, &slot_config);
    if (ret != ESP_OK)
        return ret;

    s_card = malloc(sizeof(sdmmc_card_t));
    if (s_card == NULL)
    {
        return ESP_ERR_NO_MEM;
    }

    ret = sdmmc_card_init(&host, s_card);
    if (ret != ESP_OK)
    {
        free(s_card);
        s_card = NULL;
        return ret;
    }

    ESP_LOGI(TAG, "SD Card identified successfully.");
    return ESP_OK;
}

void sd2pc_init_usb_msc(void)
{
    if (s_card == NULL)
    {
        ESP_LOGE(TAG, "Cannot launch USB MSC: SD Card not initialized!");
        return;
    }

    ESP_LOGI(TAG, "Binding SD card block map to TinyUSB stack...");

    const tinyusb_msc_sdmmc_config_t config_sdmmc = {
        .card = s_card};
    ESP_ERROR_CHECK(tinyusb_msc_storage_init_sdmmc(&config_sdmmc));

    const tinyusb_config_t tusb_cfg = {
        .device_descriptor = NULL,
        .string_descriptor = NULL,
        .external_phy = false // Native configuration for the high-speed on-chip ESP32-P4 PHY
    };

    ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
    ESP_LOGI(TAG, "USB MSC Online. Ready to interface via PC USB-OTG port.");
}

Any ideas?

Hi @DickyOZ,

Could you share your SDK configuration?
You probally need to enable this config: CONFIG_FATFS_LFN_HEAP

1 Like

Thank you for your reply, This is the config generated code for fatfs:

# FAT Filesystem support
#
# default:
CONFIG_FATFS_VOLUME_COUNT=2
# default:
# CONFIG_FATFS_LFN_NONE is not set
# default:
CONFIG_FATFS_LFN_HEAP=y
# default:
# CONFIG_FATFS_LFN_STACK is not set
# default:
# CONFIG_FATFS_SECTOR_512 is not set
# default:
CONFIG_FATFS_SECTOR_4096=y
# default:
# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set
# default:
CONFIG_FATFS_CODEPAGE_437=y
# default:
# CONFIG_FATFS_CODEPAGE_720 is not set
# default:
# CONFIG_FATFS_CODEPAGE_737 is not set
# default:
# CONFIG_FATFS_CODEPAGE_771 is not set
# default:
# CONFIG_FATFS_CODEPAGE_775 is not set
# default:
# CONFIG_FATFS_CODEPAGE_850 is not set
# default:
# CONFIG_FATFS_CODEPAGE_852 is not set
# default:
# CONFIG_FATFS_CODEPAGE_855 is not set
# default:
# CONFIG_FATFS_CODEPAGE_857 is not set
# default:
# CONFIG_FATFS_CODEPAGE_860 is not set
# default:
# CONFIG_FATFS_CODEPAGE_861 is not set
# default:
# CONFIG_FATFS_CODEPAGE_862 is not set
# default:
# CONFIG_FATFS_CODEPAGE_863 is not set
# default:
# CONFIG_FATFS_CODEPAGE_864 is not set
# default:
# CONFIG_FATFS_CODEPAGE_865 is not set
# default:
# CONFIG_FATFS_CODEPAGE_866 is not set
# default:
# CONFIG_FATFS_CODEPAGE_869 is not set
# default:
# CONFIG_FATFS_CODEPAGE_932 is not set
# default:
# CONFIG_FATFS_CODEPAGE_936 is not set
# default:
# CONFIG_FATFS_CODEPAGE_949 is not set
# default:
# CONFIG_FATFS_CODEPAGE_950 is not set
# default:
CONFIG_FATFS_CODEPAGE=437
# default:
CONFIG_FATFS_MAX_LFN=255
# default:
CONFIG_FATFS_API_ENCODING_ANSI_OEM=y
# default:
# CONFIG_FATFS_API_ENCODING_UTF_8 is not set
# default:
CONFIG_FATFS_FS_LOCK=0
# default:
CONFIG_FATFS_TIMEOUT_MS=10000
# default:
CONFIG_FATFS_PER_FILE_CACHE=y
# default:
CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y
# default:
# CONFIG_FATFS_USE_FASTSEEK is not set
# default:
CONFIG_FATFS_USE_STRFUNC_NONE=y
# default:
# CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set
# default:
# CONFIG_FATFS_USE_STRFUNC_WITH_CRLF_CONV is not set
# default:
CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0
# default:
# CONFIG_FATFS_IMMEDIATE_FSYNC is not set
# default:
# CONFIG_FATFS_USE_LABEL is not set
# default:
CONFIG_FATFS_LINK_LOCK=y
# default:
CONFIG_FATFS_USE_DYN_BUFFERS=y

#
# File system free space calculation behavior
#
# default:
CONFIG_FATFS_DONT_TRUST_FREE_CLUSTER_CNT=0
# default:
CONFIG_FATFS_DONT_TRUST_LAST_ALLOC=0
# end of File system free space calculation behavior
# end of FAT Filesystem support

By default .CONFIG_FATFS_LFN_HEAP=y I will try setting it explicitly.
SDK Config editor shows:

"IDF_EXPERIMENTAL_FEATURES": false}, "warnings": {}}


{"version": 2, "set": { "FATFS_LFN_NONE": true }}

---------------------------ERROR--------------------------

Set FATFS_LFN_NONE


-----------------------END OF ERROR-----------------------
{"version": 2, "values": {"FATFS_LFN_NONE": true, "FATFS_LFN_HEAP": false}, "ranges": {}, "visible": {"FATFS_MAX_LFN": false, "component-config-fat-filesystem-support-api-character-encoding-C:-esp-v6.0.1-esp-idf-components-fatfs-Kconfig-126": false, "FATFS_API_ENCODING_ANSI_OEM": false, "FATFS_API_ENCODING_UTF_8": false}}

Thank you for your help. After fiddling with the config I now have a clean compile! All I have to do now is get my bugs out of the project :grinning:e

Caution: altering managed component code will cause ESP-IDF to spit the dummy when it detects a checksum fail in the file you have altered.

Bootloader binary size 0x5dc0 bytes. 0x240 bytes (2%) free.
[7/9] Linking CXX executable Test_fatfs.elf
FAILED: Test_fatfs.elf 

I can get rid of that error but it cases another and I just go round in circles.

Hi @DickyOZ,

Could you check if you have enabled the following setting: CONFIG_VFS_SUPPORT_DIR?

Given that Espressif created an abstraction layer for FatFS, it’s important to understand what was implemented behind the scenes.

That config setting does not exist. But VFS_SUPPORT_DIR does.

I’ve messed around with this test project so much that it is now total mess. I will start again from square one, one step at a time.

No problem, if you have a public repository, I can help you set up and test your code.

Thank you for the much needed offer of help. My first task is to completely uninstall ESP-IDF and VS-CODE. Much of what I did was came from Copilot. A lot of its instructions were just plain wrong and I was foolish enough not to keep a proper record of everything it did to my environment. I will reinstall and check that the projects I wrote without the help of AI still work and then start an new project using ESP32-P4 nano, lvlg and setup USB OTG to access the SD card via the connection to my PC USB using a seperate core (the Waveshare ESP32P4 nano has a single USB OTG port). Once that works OK I will add the fatfs code. On my original attempt I got the filesystem to work but it conflicted with lvgl; I was trying to to get fs to run on the second core and let lvgl run on the first core. It was at that point the I got ‘help’ from Copilot :confused: