Hi everyone,
Try to register two instances in VFS:
* SDMMC (`esp_vfs_fat_sdmmc_mount_config_t`)
* Custom TinyUSB MSC FAT instance (`esp_vfs_fat_conf_t`) with diskio functions implementations (with `tuh_msc_read10` and `tuh_msc_write10`)
In order to have two mounting points: `/sdcard` and `/usb`
Actually, with the following code, I can mount both of them, but after mounting USB, there is a conflict in paths: the `/sdcard` path gives me files from `/usb`, but the USB one gives me the correct files.
```c
void bsp_mount_sdcard(void)
{
esp_err_t ret;
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
#ifdef CONFIG_SD_FORMAT_IF_MOUNT_FAILED
.format_if_mount_failed = true,
#else
.format_if_mount_failed = false,
#endif
.max_files = 5,
.allocation_unit_size = 16 * 1024};
const char mount_point[] = SDCARD_BASE_PATH;
ESP_LOGI(TAG, "Initializing SD card");
ESP_LOGI(TAG, "Using SDMMC peripheral");
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
host.max_freq_khz = SDMMC_FREQ_DEFAULT;
host.slot = SDMMC_HOST_SLOT_0;
sd_pwr_ctrl_ldo_config_t ldo_config = {
.ldo_chan_id = 4,
};
sd_pwr_ctrl_handle_t pwr_ctrl_handle = NULL;
ret = sd_pwr_ctrl_new_on_chip_ldo(&ldo_config, &pwr_ctrl_handle);
if (ret != ESP_OK)
{
ESP_LOGE(TAG, "Failed to create a new on-chip LDO power control driver");
return;
}
host.pwr_ctrl_handle = pwr_ctrl_handle;
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
slot_config.width = 4;
slot_config.clk = BSP_SD_CLK;
slot_config.cmd = BSP_SD_CMD;
slot_config.d0 = BSP_SD_D0;
slot_config.d1 = BSP_SD_D1;
slot_config.d2 = BSP_SD_D2;
slot_config.d3 = BSP_SD_D3;
slot_config.flags |= SDMMC_SLOT_FLAG_INTERNAL_PULLUP;
ESP_LOGD(TAG, "Mounting sdcard to filesystem");
ret = esp_vfs_fat_sdmmc_mount(mount_point, &host, &slot_config, &mount_config, &card);
if (ret != ESP_OK)
{
if (ret == ESP_FAIL){
ESP_LOGE(TAG, "Failed to mount filesystem. "
"If you want the card to be formatted, set the SD_FORMAT_IF_MOUNT_FAILED menuconfig option.");
}
else{
ESP_LOGE(TAG, "Failed to initialize the card (%s). "
"Make sure SD card lines have pull-up resistors in place.",
esp_err_to_name(ret));
}
return;
}
ESP_LOGD(TAG, "Sdcard mouted to Filesystem");
sdmmc_card_print_info(stdout, card);
}
```
```c
void mount_task(void *param)
{
mount_info_t mount_info;
while (1)
{
if (xQueueReceive(mount_queue, &mount_info, portMAX_DELAY) == pdTRUE)
{
if (isUsbMscMounted)
{
ESP_LOGW("MOUNT_TASK", "USB MSC already mounted, skipping");
// notification
continue;
}
ESP_LOGD("MOUNT_TASK", "Starting mount process for device %d", mount_info.dev_addr);
printf("%.8s %.16s rev %.4s\r\n",
mount_info.vendor_id,
mount_info.product_id,
mount_info.product_rev);
printf("Disk Size: %" PRIu32 " MB\r\n",
mount_info.block_count / ((1024 * 1024) / mount_info.block_size));
printf("Block Count = %" PRIu32 ", Block Size: %" PRIu32 "\r\n",
mount_info.block_count, mount_info.block_size);
uint8_t const drive_num = mount_info.dev_addr - 1;
char drive_path[8];
snprintf(drive_path, sizeof(drive_path), "%d:", drive_num);
ESP_LOGD("MOUNT_TASK", "Mounting dev_addr %d as drive %d (%s)",
mount_info.dev_addr, drive_num, drive_path);
FATFS *fs = &fatfs[drive_num];
esp_vfs_fat_conf_t config = {
.base_path = USB_DIR,
.fat_drive = drive_path,
.max_files = 5};
esp_err_t err = esp_vfs_fat_register_cfg(&config, &fs);
if (err != ESP_OK)
{
ESP_LOGE("MOUNT_TASK", "Failed to register VFS: %s", esp_err_to_name(err));
continue;
}
ESP_LOGD("MOUNT_TASK", "VFS registered successfully");
usb_diskio_impl.init = &usb_disk_initialize;
usb_diskio_impl.status = &usb_disk_status;
usb_diskio_impl.read = &usb_disk_read;
usb_diskio_impl.write = &usb_disk_write;
usb_diskio_impl.ioctl = &usb_disk_ioctl;
ff_diskio_register(drive_num, &usb_diskio_impl);
ESP_LOGD("MOUNT_TASK", "FFDISKIO registered for drive %d", drive_num);
ESP_LOGD("MOUNT_TASK", "Attempting to mount filesystem...");
FRESULT mount_result = f_mount(fs, drive_path, 1);
if (mount_result != FR_OK)
{
ESP_LOGE("MOUNT_TASK", "f_mount failed: %d", mount_result);
ff_diskio_register(drive_num, NULL);
esp_vfs_fat_unregister_path(ROX_USB_DIR);
continue;
}
isUsbMscMounted = true;
}
}
vTaskDelay(pdMS_TO_TICKS(2000));
}
```
Config information:
* Maximum Number of Virtual Filesystems: 8
* Host FS: Maximum number of the host filesystem mount points: 8
* ESP-IDF v5.4.0
* ESP32-P4 (Waveshare DevKit)
VFS path conflict issue between TinyUSB MSC and SDMMC
Re: VFS path conflict issue between TinyUSB MSC and SDMMC
Hi dhugoexe,
You're encountering a VFS conflict where both /sdcard and /usb end up pointing to the same underlying FATFS drive, likely due to overlapping or reused drive numbers (e.g., 0:).
When you mount the USB disk, it's likely using the same drive letter (0:) as the SD card, which causes /sdcard to unexpectedly point to the USB contents.
Assign distinct FATFS drive letters (0:, 1:) to each mount point.
Example Fix
For SD card (uses esp_vfs_fat_sdmmc_mount, which auto assigns 0: internally):
For USB MSC, manually assign drive 1::
If you need to remount the USB drive:
SD uses 0: (default by esp_vfs_fat_sdmmc_mount)
USB should use 1: or higher
Match fat_drive string (e.g., "1:") to what ff_diskio_register() and f_mount() expect
You're encountering a VFS conflict where both /sdcard and /usb end up pointing to the same underlying FATFS drive, likely due to overlapping or reused drive numbers (e.g., 0:).
When you mount the USB disk, it's likely using the same drive letter (0:) as the SD card, which causes /sdcard to unexpectedly point to the USB contents.
Assign distinct FATFS drive letters (0:, 1:) to each mount point.
Example Fix
For SD card (uses esp_vfs_fat_sdmmc_mount, which auto assigns 0: internally):
Code: Select all
esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, &card);
Code: Select all
uint8_t usb_drive = 1; // Ensure this is different from SD's drive
char usb_fat_drive[3];
snprintf(usb_fat_drive, sizeof(usb_fat_drive), "%u:", usb_drive);
esp_vfs_fat_conf_t usb_cfg = {
.base_path = "/usb",
.fat_drive = usb_fat_drive,
.max_files = 5
};
FATFS *usb_fs;
esp_err_t err = esp_vfs_fat_register_cfg(&usb_cfg, &usb_fs);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to register USB VFS: %s", esp_err_to_name(err));
return;
}
ff_diskio_register(usb_drive, &usb_diskio_impl);
FRESULT fres = f_mount(usb_fs, usb_fat_drive, 1);
if (fres != FR_OK) {
ESP_LOGE(TAG, "Failed to mount USB drive: %d", fres);
esp_vfs_fat_unregister_path("/usb");
ff_diskio_register(usb_drive, NULL);
return;
}
Code: Select all
f_mount(NULL, usb_fat_drive, 1);
esp_vfs_fat_unregister_path("/usb");
ff_diskio_register(usb_drive, NULL);
USB should use 1: or higher
Match fat_drive string (e.g., "1:") to what ff_diskio_register() and f_mount() expect
Who is online
Users browsing this forum: Bing [Bot], Google [Bot] and 4 guests
