# ESP32USBMSC **Repository Path**: chiyoooo/esp32-usbmsc ## Basic Information - **Project Name**: ESP32USBMSC - **Description**: 基于ESP32S3 SDMMC库的USB MSC库 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-05-04 - **Last Updated**: 2025-05-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ESP32USBMSC 库 这是一个用于 ESP32 的 USB Mass Storage Class (MSC) 库,可以将 ESP32 的 SD 卡作为 USB 大容量存储设备使用。 ## 依赖 - PlatformIO Arduino 框架 - ESP32S3 开发板 - SDIO 读卡模块 ## 安装 1. 在你的 PlatformIO 项目的 platformio.ini 文件中添加如下内容: ```ini lib_deps = https://gitee.com/chiyoooo/esp32-usbmsc.git ``` 2. 编译时 PlatformIO 会自动拉取该库,无需手动复制文件。 ## 使用方法 ### 基本使用 ```cpp #include "ESP32USBMSC.h" void setup() { Serial.begin(115200); // 初始化 SD_MMC Serial.println("Mounting SDcard"); SD_MMC.setPins(40, 39, 41, 42, 48, 38); if (!SD_MMC.begin("/sdcard", false)) { Serial.println("Mount Failed"); return; } // 设置 U 盘信息 usbMsc.setVendorID("MyCompany"); usbMsc.setProductID("MyUSBDrive"); usbMsc.setProductRevision("1.0"); // 初始化 USB MSC Serial.println("Initializing MSC"); if (!usbMsc.begin(&SD_MMC)) { Serial.println("Failed to initialize USBMSC"); return; } // 打印 SD 卡信息 Serial.printf("Card Size: %lluMB\n", SD_MMC.totalBytes() / 1024 / 1024); Serial.printf("Sector: %d\tCount: %d\n", SD_MMC.sectorSize(), SD_MMC.numSectors()); } void loop() { delay(-1); } ``` ### 引脚配置 默认的 SD_MMC 引脚配置: - CLK: GPIO 40 - CMD: GPIO 39 - D0: GPIO 41 - D1: GPIO 42 - D2: GPIO 48 - D3: GPIO 38 你可以根据你的硬件配置修改这些引脚。 ### 功能说明 1. `setVendorID(const char *vendorID)` - 设置 USB 设备的厂商 ID - 参数:厂商 ID 字符串 2. `setProductID(const char *productID)` - 设置 USB 设备的产品 ID - 参数:产品 ID 字符串 3. `setProductRevision(const char *revision)` - 设置 USB 设备的产品版本 - 参数:版本字符串 4. `begin(void* storageDevice)` - 初始化 USB MSC - 参数:存储设备指针(通常是 SD_MMC 对象) - 返回值:初始化是否成功 5. `registerUsbEventCallback(UsbEventCallback cb)` - 注册 USB 事件回调函数 - 参数:回调函数指针(函数原型为 void callback(int32_t event_id, void \*event_data)) - 作用:用于接收 USB 连接、断开、挂起、恢复等事件通知,便于在主程序中处理 USB 状态变化。例如可以在回调中打印日志、切换状态灯等。 - 示例: ```cpp void myUsbEventHandler(int32_t event_id, void *event_data) { switch (event_id) { case ARDUINO_USB_STARTED_EVENT: Serial.println("USB 连接"); break; case ARDUINO_USB_STOPPED_EVENT: Serial.println("USB 断开"); break; case ARDUINO_USB_SUSPEND_EVENT: Serial.println("USB 挂起"); break; case ARDUINO_USB_RESUME_EVENT: Serial.println("USB 恢复"); break; default: break; } } // 注册回调 usbMsc.registerUsbEventCallback(myUsbEventHandler); ``` 6. `setAutoMountFlag(bool flag)` / `getAutoMountFlag()` - 控制和查询 MSC(U 盘)是否自动挂载的标志(该标志保存在 Flash 中,掉电不丢失)。 - `setAutoMountFlag(true)`:下次重启后自动挂载 MSC,U 盘会出现在 PC。 - `setAutoMountFlag(false)`:下次重启后不挂载 MSC,U 盘不会出现在 PC。 - `getAutoMountFlag()`:返回当前自动挂载标志的值。 - 典型用法: ```cpp // 切换挂载状态并重启 usbMsc.setAutoMountFlag(!usbMsc.getAutoMountFlag()); ESP.restart(); ``` ## 注意事项 1. 目前只在 ESP32S3 平台上测试通过,其他平台未测试 2. 使用 SDMMC 库,速度会比使用 SD 库更快,官方例程是使用 SD 库。 3. esp32-arduino SDK 这 MSC 部分代码不支持 SDMMC 库,因此此处用的是 PIO 官方推出的 arduino SDK (出处:https://community.platformio.org/t/porting-sd2usbmsc-example-to-platformio-missing-sd-mmc-methods/46822) 4. 确保 SD 卡格式化为 FAT32 文件系统 5. 受限于 SDMMC 的读写限制,每次只能操作一个扇区,所以速度较慢,简单测试后开始速度最高可以达到 710kb/s,平均速度 355kb/s 左右。 6. SDIO 的引脚一定要有物理上拉,否则无法正常读写。 7. 实现挂载后的 SD 卡状态检测,防止拔出 USB 后,马上读写导致的程序崩溃 ## 许可证 MIT License ## todolist 1. 兼容 SD 库 2. 目前只在 esp32S3 上完成测试,等待更多平台测试 3. 速度测试 4. 能动态获取 TF 卡的容量和使用情况 5. 文件变化后,能触发某个回调函数 1. 在 USB MSC(U 盘)模式下,ESP32 无法直接、实时感知 PC 端的文件变化(如增删文件),也无法自动触发本地回调。 2. USB MSC 协议本质:ESP32 作为 U 盘时,只是"扇区级别"的桥接,PC 直接操作 FAT 文件系统,ESP32 本地的文件系统(FATFS)并不参与,也不会收到任何"文件变化"通知。 3. 没有文件系统事件同步:USB MSC 协议没有"文件变化事件"机制,ESP32 无法得知 PC 端的文件操作。FATFS 缓存机制 4. ESP32 本地的 FATFS 只有在重新挂载时才会重新扫描目录,平时不会主动感知变化。 6. 结合下来看,4、5 的功能不好实现 7. BUG:如果插着 USB 进行重启,能正常显示 U 盘,但是回调没有正常触发,会导致串口没有输出具体见 examample/get_sd_ready/get_sd_ready.cpp 重新拔插 USB 后能正常触发回调