[STM32F7] MSC 主机库 USBH_MSC_BOT_REQ_GetMaxLUN 无应答

[复制链接]
33|11
唐纳德d 发表于 2026-9-17 17:40 | 显示全部楼层 |阅读模式
我在STM32F777NI的应用程序使用 USB 主机库去读写 U 盘。

使用的固件包版本是 stm32cubef7 V1.12.0。程序调用`USBH_MSC_BOT_REQ_GetMaxLUN`之后就卡死了; U 盘响应这条命令。

我查阅了 USB 相关规范文档https://www.usb.org/sites/default/files/usbmass‑ufi10.pdf

文档里面的原文如下:

3.2.2 逻辑单元号 (LUN)
逻辑单元号字段用于指定处理命令块的逻辑单元。尽管 SFF‑8070i 标准说明,块层级的逻辑单元号会在后续版本标准中废弃;但 UFI 命令块仍然使用块层级 LUN,因为并不存在控制层 LUN。(控制层 LUN 设置于 ATAPI 块设备选择寄存器,而 UFI 设备没有该寄存器。)
如果 UFI 设备仅支持单个逻辑单元,则它的逻辑单元号应当为 0。除 INQUIRY(查询)命令之外,如果 UFI 设备收到一个不支持的逻辑单元号,设备应当中止该命令;设置检测键为 ILLEGAL REQUEST(非法请求),附加检测码为 LOGICAL UNIT NOT SUPPORTED(不支持该逻辑单元)。

按照规范,设备可以不对 GetMaxLUN 这条请求做出应答。我把这一条代码注释之后,带 FAT 文件系统的 U 盘就可以正常工作了。

请问这属于库里面的 Bug,还是我的操作问题?

公羊子丹 发表于 2026-9-18 09:44 | 显示全部楼层
这个你判断得对:按 USB MSC BOT 规范,GetMaxLUN 是'可选'请求,设备可以不响应(返回 STALL 或不理)。很多 U 盘就不支持它。CubeF7 的 USBH_MSC 库里如果对 GetMaxLUN 的响应没做容错,一遇到不支持的盘就卡死,这是库的健壮性问题,不是你的操作问题。
周半梅 发表于 2026-9-18 09:45 | 显示全部楼层
我赌根因在库函数的超时/STALL 处理。USBH_MSC_BOT_REQ_GetMaxLUN 内部应该处理'设备 STALL 该请求'的情况并继续(BOT 规范里 GetMaxLUN 被 STALL 是合法的,代表只有 1 个 LUN)。如果库里把它当成致命错误或死等,就会卡死。注释掉那行能用正好说明这点。
帛灿灿 发表于 2026-9-18 09:46 | 显示全部楼层
补充:你注释掉 GetMaxLUN 后 FAT 能用,是因为绝大多数 U 盘只有一个 LUN(LUN=0),不用查询默认就用 0。所以对普通 U 盘,跳过 GetMaxLUN 是安全的。只有遇到多 LUN 设备(比如带读卡器的复合设备)才需要它。你的做法对单 LUN 场景没毛病。
童雨竹 发表于 2026-9-18 09:47 | 显示全部楼层
想问下你用的具体是哪个函数路径?CubeF7 V1.12 的 USBH_MSC 里,GetMaxLUN 通常在 MSC_InterfaceInit 或类似阶段调用。建议看一下它周围有没有超时返回路径,以及 USBH_MSC_BOT_Process 里对 STALL/NAK 的处理。找到卡死的确切位置(是死等标志还是循环),就能判断是不是库 bug。
万图 发表于 2026-9-18 09:47 | 显示全部楼层
从规范看,GetMaxLUN 请求的响应:设备支持就返回 1 字节 LUN 数,不支持就 STALL。主机收到 STALL 应视为'设备只有 1 个 LUN'并继续,这是规范明确的。所以库如果卡死,要么是没处理 STALL,要么是 UR(不可恢复错误)后没恢复。可以对比 CubeF4 的新版本库看是否已修。
Wordsworth 发表于 2026-9-18 09:48 | 显示全部楼层
测试建议:换几个不同品牌的 U 盘试,看是不是所有盘都卡,还是只有某些盘卡。如果只有特定盘卡,那就坐实是'该盘不支持 GetMaxLUN'触发的库鲁棒性问题;如果所有盘都卡,可能是你的工程配置或枚举阶段其他问题。
Bblythe 发表于 2026-9-18 09:49 | 显示全部楼层
我之前用 Cube 的 USBH MSC 也遇到过类似'某类设备卡死',一般是库对非标准响应处理不完善。解决办法要么升级 CubeF7 到新版(可能修了),要么自己打补丁:在 GetMaxLUN 调用处加超时,失败就当 LUN=0 继续。这种补丁社区里应该有人贴过。
Pulitzer 发表于 2026-9-18 09:50 | 显示全部楼层
补充个点:GetMaxLUN 卡死除了 STALL 未处理,还可能是 control transfer 的状态阶段没走完。BOT 的 control 传输要经过 SETUP/DATA/STATUS 三阶段,如果设备在 STATUS 阶段不响应,主机会等超时。库的超时如果太长或没设,就表现成卡死。检查 control transfer 的超时参数。
Uriah 发表于 2026-9-18 09:50 | 显示全部楼层
问一下你的项目后面要支持多 LUN 设备吗?如果只是普通 U 盘读写,注释掉 GetMaxLUN 完全可用,而且更稳。如果要做读卡器这类多 LUN 设备,那就得修库,让它正确处理 STALL 并能拿到真实 LUN 数。按需求决定是绕过还是修复。
Clyde011 发表于 2026-9-18 09:51 | 显示全部楼层
从结论看,这基本可以判定为 CubeF7 V1.12 库的鲁棒性缺陷(未正确处理 GetMaxLUN 的 STALL/无应答),不是你的使用问题——因为你的操作完全符合规范,库应该容错却没容错。建议把现象和复现步骤反馈到 ST 社区,同时用超时补丁先让产品跑起来。
Stahan 发表于 2026-9-18 14:38 | 显示全部楼层
这应该是库的问题,建议升级库到最新版或者自己添加超时处理。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

206

主题

207

帖子

0

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