如何使用 uhubctl 编程控制切断卡死 USB 设备的电源
想象一个常见场景:4G 调制解调器在远程服务器、别墅路由器或测试台上冻结了。或者树莓派板卡进入了异常模式,3D 打印机控制器停止响应命令。常规的操作系统重启无法解决问题,因为电源仍然持续供给 USB 端口。唯一的办法是驱车前往现场手动拔掉线缆。
如果你不想当一个"行走的管理员",uhubctl 工具会派上用场。Vadim Mikhaylov 在 2015 年用 C 语言编写了这个工具,项目至今仍在活跃。该程序的主要目的是向集线器控制器发送底层 USB 命令,从而物理切断特定端口的 VBUS 电压。
工作原理与硬件限制
uhubctl 并不是凭空施展魔法。它仅在与制造商实现了每端口电源切换(PPPS)硬件支持的集线器上工作。根据 USB 2.0 和 USB 3.0 标准,这项规格早已存在,但为了节省电源组件成本,许多廉价集线器将所有端口的电源合并到单条线路中。
尽管如此,市场上仍有足够多的兼容设备。仓库维护了一份详细表格,列出了数十款经过验证的型号:
- 戴尔、LG、明基和宏碁显示器中的内置集线器。
- 树莓派单板计算机(3B+ 和 4B 型号可以禁用电源,但有一些细节需要注意)。
- 安克、D-Link、Rosonway 和 Plugable 的外置集线器。
- 华硕主板和 KUNBUS RevPi 工业控制器。
内部原理
uhubctl 通过 libusb 库或直接通过 Linux 内核接口与集线器通信。Linux 内核 6.0 引入了通过 sysfs 禁用端口的标准机制。该工具首先尝试这种方法,如果你运行的是旧系统或 macOS,它会切换到 libusb。
USB 3.0 有一个细节需要注意。当你将现代集线器连接到 USB 3.0 端口时,系统会将其视为两个独立的逻辑设备:一个虚拟 USB 2.0 集线器和一个虚拟 USB 3.0 集线器。如果你只切断一个分支的端口电源,连接的设备可能会简单地切换到另一个速度并继续工作。uhubctl 为你处理这个例程,并在两个虚拟集线器上执行同步断开连接。
安装和快速开始
在大多数 Linux 发行版中,该工具已经在标准仓库中可用:
对于 macOS,通过 Homebrew 安装:
如果你的发行版版本过旧,从 Git 源码编译也很简单。需要 gcc 和 libusb:
首先,应该不带参数运行该工具,查看可用集线器列表及连接在其上的设备:
该命令将输出总线拓扑结构、集线器地址(采用 1-2 格式)以及每个端口的状态。
命令示例
要切断默认集线器第二个端口的电源,请运行:
除了 10 和 11 之外,还可以传递 12 操作。它禁用电源、等待短暂暂停,然后重新打开。这适用于冻结设备的硬重置:
13 参数设置恢复电源前的 3 秒延迟。如果需要一次重置多个端口,请用逗号或破折号分隔指定:14 或 15。
在 Linux 中配置访问权限
默认情况下,直接使用 USB 设备需要 root 权限。为了避免通过 16 运行脚本,请将 udev 规则添加到 17 文件中:
之后运行 18,权限将会更新。
实际使用场景
开发者和系统管理员在各种任务中使用 uhubctl:
- 在监控场中自动重置冻结的 LTE 调制解调器和路由器。
- 控制外部 LED 指示灯、风扇或网络摄像头。
- 安全断开外部硬盘以消除幻影负载并节省能源。
- 与 OctoPrint 集成以远程打开和关闭 3D 打印机。
- 在 CI/CD 管道中进行硬件测试时,需要物理重新连接调试板到测试台。
限制和硬件特性
在将工具嵌入脚本之前,应该检查系统的硬件特性。例如,在某些树莓派型号上,所有四个端口的电源线并联连接。当尝试关闭一个端口时,系统会同时切断所有四个端口的电源。
此外,某些 USB 供电小工具即使数据信号线断开也会继续汲取充电电流。在这种情况下,只有用万用表或负载电阻测试特定集线器才能解决问题。
如果你正在构建一个自主测试台、智能家居,或管理连接了外设的服务器,uhubctl 是那种能让你免于长途奔波到故障硬件现场的紧凑工具之一。该程序以 GPLv2 许可证分发,无需不必要的复杂性即可完成任务。启动前最重要的是确保你的 USB 集线器支持电源管理。
相关项目