在stm32f407ve芯片上
使用cubemx生成的MSC主机例程;
如下的当时使用的软件包
在使用usb主机库驱动U盘,当插入U盘时,发现打印的串口信息一直都会出现2个LUN;
经过排查,发现st官方的库中,关于lun的识别出现了问题
发现MSC库中获取LUN相关代码有问题
代码如下
其中
status = USBH_MSC_BOT_REQ_GetMaxLUN(phost, (uint8_t *)(void *)&MSC_Handle->max_lun);
MSC_Handle->max_lun = (MSC_Handle->max_lun > MAX_SUPPORTED_LUN)? MAX_SUPPORTED_LUN : (uint8_t )(MSC_Handle->max_lun) + 1U;
这两行代码,造成的这个问题;
具体解释如下:
ST 实现驱动程序“最大 LUN”部分的方式令人困惑,因为它不符合usb.org 规范中“获取最大 LUN”的定义(请参阅 https://www.usb.org/document library/mass-storage-bulk-only_10 并搜索“aet max lun”)。 ST实现了MSc,Handle->max lun值来指示LuN的“数量”而 USB.org 将其定义为“最大 LUN 索引”(即,有 2 个 LUN 时最大 LUN 索引为 1。) 主要代码修复是增加从 USB 驱动器读取的“最大 lun”值,然后再将其用于 ST 的其余部分 司机。 ST 如何实现驱动程序的另一个问题是 MSC Handle->max lun 被定义为 uint32 t,但是 调用 USB 驱动器来检索它需要一个 (uint8 t *),因此只有该值的低 8 位被设置,留下 高 24 位不变。因此,在使用或之前必须清除高 24 位(或类型转换为 uint8 t) 比较该值。 在上述代码修改之前,具有 1 个 LUT 的驱动器返回一个具有非常大值的 MSc Handle->max lun (如预期,低 8 位为零,但高 24 位是一些较大的值),因此 MSC Handle->max lun 得到 限制为最大支持的 LUN,为 2,而不是 1,并且驱动器无法安装。
简单来说,当你插入U盘,U盘返回LUN为1的时候,USB函数只会写入buf的低8位,造成高24位的值为未知,导致返回的值作为32位解析后显示特别大。之后在经过三目运算符的纠错后,被修改为默认的最大值,这是一般是2; 而U盘本身不支持2,所以在进行lun为2的轮询时,出现了驱动加载的失败。
下面是原文
STM32Cube USB Host Mass Storage Class problem: som... - STMicroelectronics Community
那么如何解决呢
我刚开始想着既然只有低八位有效,那就在获取到LUN值后,清零高24位即可;具体
MSC_Handle->max_lun &= 0x000000FF;
事实也是如此,插入U盘后成功的只有一位LUN值了
但是这样是有风险的,因为谁也不知道高24位也许就变成了其他用处的地址了呢。
之后我再采用了宁外的方法,即再请求LUN之前,将32位的区域清零;
如上,结果也是正常的;
参考文章:STM32Cube USB Host Mass Storage Class problem: som... - STMicroelectronics Community