TeenyUSB MSC U盘开发指南用FatFs打造你自己的闪存U盘设备【免费下载链接】TeenyUSBLightweight USB device and host stack for STM32 and other MCUs. Ready for USB 3.0 device.项目地址: https://gitcode.com/gh_mirrors/te/TeenyUSBTeenyUSB 是一个轻量级单片机 USB 协议栈支持 STM32、CH565W 等主流 MCU 的 USB 设备与主机模式。本指南带你用 TeenyUSB 的 MSC大容量存储类功能把 MCU 做成一台电脑即插即用的 U 盘并配合项目内置的 FatFs 文件系统直接在 U 盘上读写文件——无需任何驱动Windows/macOS/Linux 全平台免驱识别。1. 三分钟了解 MSC 设备架构 把 MCU 变成 U 盘本质上就是让单片机应答标准的 SCSI 命令。TeenyUSB 在class/msc/目录下提供了完整的 MSC BOTBulk-Only Transport协议实现模块路径作用MSC 设备类tusbd_msc.cBOT 协议状态机、SCSI 命令解析MSC 设备接口tusbd_msc.htusb_msc_device_t结构与回调定义BOT 协议定义tusb_msc.hCBW/CSW 包格式SCSI 命令定义tusb_scsi.hINQUIRY、READ(10)、WRITE(10) 等命令复合设备示例composite_device.c含 MSC U 盘的完整可编译例程USB 传输由底层 API 与中断回调完成而应用层只需要关心三件事写三个块级回调函数get_cap容量、block_read读块、block_write写块填一个结构体把回调挂到tusb_msc_device_t上在主循环里调用tusb_msc_device_loop()处理命令。这就是 TeenyUSB teeny迷你的精髓——MSC 设备类代码只有几百行却能让电脑把你的 MCU 识别成标准可移动磁盘。2. 用 TeenyDT 生成带 MSC 接口的描述符USB 描述符不需要手写项目自带基于 Lua 的描述符生成工具TeenyDT源码见 TeenyDT/。在 composite_desc.lua 中MSC 接口只需 6 行配置Interface{ bInterfaceClass 0x08, -- MSC bInterfaceSubClass 0x06, -- SCSI bInterfaceProtocol 0x50, -- BOT EndPoint(IN(4), BulkDouble, 64), EndPoint(OUT(4), BulkDouble, 64), }生成后的teeny_usb_desc.c/h由脚本自动产出其中BulkDouble表示按高速/全速自动调整端点包长。三个值0x08 / 0x06 / 0x50是 U 盘识别的身份证操作系统看到它们就会加载大容量存储驱动。3. 实现块设备回调告诉协议栈数据存哪里MSC 层只操作 512 字节的块存储介质可以是 RAM、NOR Flash、SD 卡甚至 NAND。以 composite_device.c 中的 RAM 盘为例tusb_msc_device_t msc_dev { .backend msc_device_backend, .ep_in 4, .ep_out 4, .max_lun 0, // 1个逻辑单元 .get_cap msc_get_cap, // 返回块数/块大小 .block_read msc_block_read, .block_write msc_block_write, };RAM 盘示例代码 L233-L272START_ADDR指向 RAM 尾部的空闲区域BLOCK_COUNT按芯片 RAM 计算读写就是memcpy速度最快适合功能演示Flash 盘示例代码 L275-L297START_ADDR从 Flash 偏移 20KB 处开始块大小取 Flash 扇区大小写入调用flash_write()适合做真正的闪存 U 盘但注意 Flash 擦写寿命有限。两个回调的返回值约定很清晰返回实际读写的字节数出错返回 -1协议栈会自动填充相应的 SCSI Sense 错误码如MEDIUM_ERROR、WRITE_FAULT宿主机就能看到读写失败提示。⚠️常见坑MSC_DATA_PACKET_LENGTH数据缓冲区必须 ≥ 512否则 composite_device.c 末尾的编译期检查会直接报错。配置好结构体后只需在主循环中周期性调用tusb_msc_device_loop(msc_dev);示例代码 L229电脑即可看到一块可移动磁盘。4. 用 FatFs 让 U 盘支持文件读写 裸盘只是一堆块数据接上 FatFs 后电脑才能看到.txt、.jpg这样的文件。项目已在 third_part/fatfs/ 内置完整的 FatFs 源码ff.c / ff.h文件系统核心FAT12/16/32 读写ffconf.h功能裁剪配置diskio.c底层磁盘适配胶水层FatFs 通过diskio.c与具体存储解耦其中预留了 RAM/MMC/USB 三种物理盘的定义。接入自己的存储只需实现四个胶水函数以 RAM 盘为例DRESULT RAM_disk_read(BYTE *buff, LBA_t sector, UINT count) { memcpy(buff, (void*)START_ADDR sector*512, count*512); return RES_OK; }然后挂载并验证f_mount(fs, , 1); // 挂载盘0 FRESULT res f_open(file, hello.txt, FA_READ); f_read(file, buf, sizeof(buf), bytes); // 读出U盘里的文件由于 TeenyUSB 的block_read/block_write回调与disk_read/disk_write参数几乎一致起始块地址 块数 缓冲区FatFs 层可以零拷贝地直接调用 MSC 的同一套存储函数一套介质驱动同时服务于USB 对外服务和自己读自己的盘两个方向。提示FAT 的根目录表、FAT 表会频繁改写。若介质是 Flash建议在diskio.c中加一层块缓存或把 FAT 表映射到 RAM可显著延长 Flash 寿命。5. 一键编译验证项目使用arm-none-eabi-gcc工具链编译MSC 已集成在 composite 复合设备示例中HID CDC WinUSB MSC 四合一git clone https://gitcode.com/gh_mirrors/te/TeenyUSB cd TeenyUSB git submodule update --init # 拉取mcu_lib的STM32库 cd sample make comp支持的验证板卡包括 STM32F072/F103/F107/F303/F407/F723/F767/H743 及 CH565WUSB 3.0 设备各板卡配置见 sample/boards/。烧录后插线到电脑设备管理器中应看到 TeenyUSB 厂商名的可移动磁盘SCSI INQUIRY 回复默认是TeenyUSB / MSC BOT DEMO可在 tusbd_msc.c 的msc_scsi_inquiry()中改成你自己的品牌名。6. 常见问题排查清单 ✅现象原因与对策电脑识别为未知设备描述符 MSC 三字节不对确认0x08/0x06/0x50并用 TeenyDT 重新生成磁盘容量为 0 或异常get_cap返回的block_num计算错误注意减去程序与栈占用的空间读写偶发失败block_read/block_write返回了 -1检查地址越界与 Flash 扇区对齐FatFs 挂载失败FR_NO_FILESYSTEM裸盘无 FAT 表先用电脑格式化一次或调用f_mkfs()初始化编译报错 buffer 太小把MSC_DATA_PACKET_LENGTH提到 ≥ 512进阶方向tusb_msc_device_t支持max_lun多逻辑单元和可选的scsi_opsis_ready、loadEject、inquiry可以实现可弹出语义和自定义 INQUIRY 品牌信息主机侧的 tusbh.c 同样实现了 MSC Host 类同一块板还能反过来读取插入的 U 盘——设备与主机双角色这正是 TeenyUSB 相比同类轻量栈的优势所在。祝你的第一块MCU 自制 U 盘点亮成功【免费下载链接】TeenyUSBLightweight USB device and host stack for STM32 and other MCUs. Ready for USB 3.0 device.项目地址: https://gitcode.com/gh_mirrors/te/TeenyUSB创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考