>_ DevTrendszh

语言

首页

语言

板块

前端 后端 移动端 DevOps AI / ML 游戏开发 区块链 嵌入式 安全
C

如何使用 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 集线器支持电源管理。

相关项目