我正在编写嵌入式 STMicro.com STM32 处理器代码并使用 STMicro.com 的 USB 驱动程序。STM32处理器上没有运行其他软件。这有点不寻常,但我们已经成功地将 STM32 处理器配置为根据命令从 USB/CDC 设备切换到 USB/MSC 设备。问题是找到一种方法从 USB/MSC 切换回 USB/CDC。
为了解决这个问题,我相信我可以使用 USB 电缆将基于 STM32 的设备连接到 Ubuntu 计算机并发送 SCSI 弹出命令。然而这并不总是有效。我发现我必须至少发送两次 SCSI 弹出命令。有时,在我的 STM32 代码看到 1 个弹出事件之前,有多达 5 次。为什么?
为了验证 STM32 代码是否有效,我将基于 STM32 的设备连接到 Windows 10 计算机。使用 Windows 文件资源管理器中的弹出功能,我能够看到 Windows 10 计算机发送到基于 STM32 的设备的每个弹出事件。因此,STM32 代码和 STMicro.com USB 驱动程序似乎可以工作(适用于 Windows 10)。
更深入...
当基于 STM32 的设备连接到 Ubuntu 计算机时,我运行了 STM32 处理器调试器。在调试 STMicro.com 的 USB 驱动程序时,我观察到可以看到所有 USB/MSC SCSI Eject 命令。但是,在我的代码看到 EJECT 状态之前,驱动程序会用其他 USB/MSC 状态(例如 LOCK 和 UNLOCK)重写弹出标志。以下是可以在 github.com 上找到的 STMicro.com 代码片段:
if ((params[4] & 0x3U) == 0x1U) /* START=1 */
{
hmsc->scsi_medium_state = SCSI_MEDIUM_UNLOCKED;
}
else if ((params[4] & 0x3U) == 0x2U) /* START=0 and LOEJ Load Eject=1 */
{
hmsc->scsi_medium_state = SCSI_MEDIUM_EJECTED;
}
else if ((params[4] & 0x3U) == 0x3U) /* START=1 and LOEJ Load Eject=1 */
{
hmsc->scsi_medium_state = SCSI_MEDIUM_UNLOCKED;
}
else
{
/* .. */
}
当出现以下情况时,Ubuntu 是否发送的不仅仅是 SCSI 弹出命令:
eject -s /dev/sdx
...使用命令?有没有办法只从 Ubuntu 通过 USB/MSC 连接发送 SCSI 弹出命令?
ject 发送“ALLOW MEDIUM REMOVAL”,然后发送“START STOP”SCSI 命令来弹出设备。
我查看了弹出的源代码。在'eject -s'期间发生的是eject_scsi函数的调用,在此期间发生以下情况:
allowedRmBlk、startStop1Blk 和 startStop2Blk 是实际源代码中使用的内容,但我还显示了代码中与它们一起使用的实际命令(如它们的定义) - startStop1Blk 和 startStop2Blk 之间的区别是:
我不确定“仅发送 SCSI EJECT 命令”是什么意思,但假设您的意思是负责弹出的 SCSI 命令,那么弹出只会发出它们。
根据Seagate 的 SCSI 命令参考,START STOP UNIT 是处理弹出的正确命令。摘录如下: