[STM32F4] 把 RAM 磁盘枚举成 USB 大容量存储设备

[复制链接]
34|4
lilaiju 发表于 2026-11-5 20:55 | 显示全部楼层 |阅读模式

我想实现 RAM 磁盘作为 USB 大容量存储设备,实现 PC 和 STM 开发板之间的数据交互。我使用这个 mbed 工程:https://os.mbed.com/users/va009039/code/F401RE_USBMSD_RAM/
固件可以正常运行,但是 Windows 无法识别开发板为 USB 磁盘。
#define PACKET_SIZE 32
#define blocks_data (1024 * 512)
FATFileSystem fs("fs");

SERIAL setup Serial pc(USBTX, USBRX, 230400);

THREADs Thread ramfs_thread;

void ram_disk_setup() { int connect1 = 0;

/* Size of RAM file system exposed to PC as USB MassStorage */ HeapBlockDevice heap_bd(blocks_data, 512);

MBRBlockDevice::partition(&heap_bd, 1, 0x0b, 0, 512 * 512);

MBRBlockDevice part1(&heap_bd, 1);

RAMFS ramfs1("ram1", &part1);

format with FS FATFileSystem::format(&part1); create FS object and mount FS FATFileSystem fat1("fat", &part1);

USBRAMFS usbmsd1(&ramfs1);

while(true) { if (usbmsd1.connect() && 1 != connect1) { connect1 = 1; printf("Connected to PC - 1\r\n"); }

only try once per second Thread::wait(9000); } }

int main(void) { osStatus err; wait(5);

printf("\r\nUSB Serial done\r\n");

err = ramfs_thread.start(callback(ram_disk_setup)); if (err) { printf("ERROR > send_hid_thread not created\r\n"); } ramfs_thread.join(); }

遗忘领域 发表于 2026-11-6 10:06 | 显示全部楼层
检查你的驱动程序是否正确安装,或者尝试更新固件版本。我之前遇到过类似问题,更新驱动后解决了。
七毛钱 发表于 2026-11-6 12:41 | 显示全部楼层
你现在用的Mbed官方在线构建工具2026年7月已经停止服务了,你这个旧的F401RE USBMSD_RAM工程很可能是用旧版Mbed OS在线编译的,放到本地新环境编译很容易出枚举逻辑不兼容的问题,优先换成活跃维护的Mbed Community Edition来编译就能规避不少底层bug。
classroom 发表于 2026-11-6 13:24 | 显示全部楼层
代码里你定义的blocks_data是1024个512字节块,后面给MBR分区划空间的时候又写死了512*512,直接把后半段一半RAM空间给浪费了,还容易让分区表出现边界对齐错误,Windows识别大容量存储时找不到有效分区自然就不认。
cr315 发表于 2026-11-6 14:42 | 显示全部楼层
STM32F4的USB全速外设默认端点最大包长是64字节,你代码里硬写PACKET_SIZE 32,小于USB规范定义的BULK端点全速模式最小工作包长的合理范围,直接会导致USB大容量存储的BOT传输握手失败,主机没法识别设备类描述符。
duo点 发表于 2026-11-6 15:20 | 显示全部楼层
你用的USBRAMFS类是Mbed旧版USB库的遗留API,现在Mbed CE社区版里已经把它重构成了更兼容标准UFI命令的USBMSD类,旧类对Windows最新系统的大容量存储协议支持有缺陷,很容易出现枚举不识别的问题。
flycamelaaa 发表于 2026-11-6 15:55 | 显示全部楼层
代码里调用usbmsd1.connect()之前,你没有执行HeapBlockDevice的初始化操作,裸申请完堆空间没做硬件块设备初始化,底层根本读不到有效的FAT引导扇区,Windows挂载的时候扫不到合法FAT文件系统直接就报错。
jcky001 发表于 2026-11-6 19:43 | 显示全部楼层
你在main函数开头加了5秒的wait(5)延时,启动后等串口初始化完再跑线程,但Windows冷启动枚举USB设备的窗口期很短,延时太久主机错过了设备接入的初始枚举脉冲,系统直接就跳过设备识别流程了。
onlycook 发表于 2026-11-6 18:10 | 显示全部楼层
Mbed原生的RAM块设备默认没有做4字节对齐,你STM32F4的内核开启了数据Cache的情况下,USB外设直接通过DMA访问RAM磁盘数据时,会出现缓存一致性错误,主机读到乱码的分区表自然没法正常识别为可移动磁盘。
powerantone 发表于 2026-11-6 18:44 | 显示全部楼层
你现在代码里的FAT格式化逻辑写在RAM里,每次设备上电生成的分区校验信息完全不一致,Windows的即插即用服务检测到无效的MBR分区签名时,会直接把设备标记为未知大容量存储,不会分配盘符也不会弹出识别提示。
probedog 发表于 2026-11-6 20:10 | 显示全部楼层
你开的独立线程里Thread::wait(9000)相当于每9秒才调用一次connect,轮询间隔太长了,USB大容量存储枚举需要设备快速响应主机的复位和类专属请求,9秒的间隔远远超过主机的请求超时阈值,握手直接超时失败。
solty 发表于 2026-11-6 21:18 | 显示全部楼层
你用的旧版Mbed USB库没有正确配置USB大容量存储的厂商和产品ID,和Windows内置的通用USB大容量存储驱动的兼容表不匹配,系统就算枚举到设备也没法自动匹配到对应的驱动,直接就显示未知设备。
spicy 发表于 2026-11-6 12:45 | 显示全部楼层
你引用的这个旧工程的配套离线开发工具已经停止支持了,如果你不想折腾环境配置,完全可以改用官方推荐的Mbed Studio本地编译环境,它自带兼容STM32F4的USB库,能直接把RAM磁盘枚举逻辑跑通。
EmmaTT 发表于 2026-11-7 15:00 | 显示全部楼层
先检查FAT格式化是否正确,确保MBR分区表无误,同时确认PACKET_SIZE设置与USB规范一致,再试试更换新的USBRAMFS类库。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

233

主题

234

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部