我使用的笔记本电脑通常放在我的办公桌上。它有一堆我使用的 USB 外围设备(音频接口、MIDI 控制器、鼠标、键盘)。我通过有源 USB 集线器连接它们。这通常可以正常工作,但每当我在计算机处于唤醒状态时断开设备连接时,它往往会搞砸。
我认为连接到集线器的设备没有收到关机命令。由于它们仍由集线器供电,因此它们保持唤醒状态。
当我重新连接我的笔记本电脑时,它们无法正确初始化,因为它们已经处于唤醒状态,所以我必须断开集线器与计算机的连接,断开集线器与集线器的电源,然后重新连接两者以使一切正常运行。
每次都会造成轻微的烦恼。我在使用多个集线器时都遇到过这种情况,但找不到任何好的解决办法。
我正在使用 Ubuntu,但偶尔双启动到 Windows 时也会出现同样的问题。
有没有人找到解决这个问题的可行方法?(例如:一个更智能的 USB 集线器,在断开连接时会关闭电源,或者在连接 USB 设备时运行一些黑客命令。)
答案1
您的“有源 USB 集线器”中显然存在一些非常糟糕的集线器控制器 IC,或者电路板设计有误,无法正确处理 VBUS。而且,您关于 USB 设备处于“唤醒”状态和“未接收关机命令”的概念有点不对。
根据 USB 规范,当上游端口上的 VBUS 消失时,每个 USB 设备(包括 USB 集线器)都必须将 USB 接口重置为默认状态(未连接/未枚举状态)。为此,所有普通集线器(和设备)都有一个特殊的逻辑输入(通常),称为“VBUS_SENSE”。输入通常通过电平转换器连接到 VBUS(如果转换是在内部完成的,则直接连接到 VBUS)。此输入的功能是 (a) 当没有 VBUS 时不上拉 D+,以及 (b) 如果没有 VBUS 则重置 USB 接口。
如果 VBUS 断开连接后又重新连接,USB 集线器必须将其所有下游端口设置为“禁用”无电源状态。当集线器的上游端口接收到“USB_RESET”状态时(D+/D- 线均变为低电平持续 10-50 毫秒),也必须发生相同的情况。
现在,确实,如果您有一个使用“联动”电源且没有高侧开关的廉价自供电(由外部 AC-DC 适配器供电)集线器,则所有连接的下游设备将继续接收 VBUS。断开集线器的上游端口后,USB 通信将停止,所有设备将进入低功耗 SUSPEND 状态。它们不是“唤醒”,而是“暂停”。设备也不需要接收任何“关机”命令,SUSPEND 会在总线不活动 3 毫秒后自动发生。在此状态下,设备保留其先前的枚举(分配的 USB 地址)。因此,当(如果以某种方式)通信恢复时,它们将仅响应旧地址。
如上所述,如果 VBUS 消失,普通 USB 集线器将禁用所有下游端口上的传输逻辑。因此,当 VBUS 恢复时(例如,重新连接到其他主机后),下游流量不会恢复,因为所有端口均已禁用。集线器从根端口接收到 USB_RESET 后,将重新枚举集线器。然后,主机软件将使用新分配的集线器地址检查所有下游端口的状态。如果端口状态显示为“已连接”,则端口将接收“PORT_RESET”命令,该命令反过来将生成 USB_RESET 到相应的连接设备,并将端口置于“启用”状态,开始空闲流量。连接的设备会将其 USB 串行接口重置为“默认”(addr=0 endpont=0)状态。主机将继续对设备进行标准枚举,并分配下一个可用的有效(非零)地址。所有其他设备都不会接收任何流量,因为所有其他端口仍处于禁用状态。
然后主机将移至显示连接的另一个端口,枚举过程重复。即使所有流量都通过启用的端口广播,已枚举的设备也会忽略新的枚举流量,因为它们已针对单个非零 USB 地址进行配置。因此,所有连接的设备最终都会显示在 USB 设备树中。
因此,如果您将集线器电缆从一台 PC 重新连接到另一台笔记本电脑,则必须禁用集线器端口,并且必须重新开始上述过程。如果没有,那么您的集线器已损坏。很可能是电路板设计未实现 VBUS_SENSE 功能,而是使用外部电源来保持感测处于活动状态。即使如此,上游端口上的 USB_reset 也会在新连接后跟进,并且集线器必须重置 USB 接口并禁用其端口。如果它不这样做,那就真的很糟糕。事实上,我还没有遇到过端口禁用功能损坏的集线器 IC。这些包括 TI 集线器、SMSC/Microchip、Terminix、Genesis Logic、VIA labs、Alcor。你一定有一些独特且非常盗版的东西。