用 Linux 控制 USB 电源(开/关)

有没有可能通过 Linux 手动从 USB 接口打开/关闭电源?

有这个外部 USB 冷却风扇(你用来冷却自己,而不是 PC 的那种) ,这将是很好的,能够控制它从终端,因为我想把风扇的位置远离。

我想这对于很多其他的东西也是有用的,因为有很多 USB 玩具。也许是空气净化器,等等(我听说他们不是真的工作)。

296300 次浏览

注意。 这个答案中的信息与较旧的内核相关(直到2.6.32)。有关新内核的信息,请参见 Tlwhitec 的回答

# disable external wake-up; do this only once
echo disabled > /sys/bus/usb/devices/usb1/power/wakeup


echo on > /sys/bus/usb/devices/usb1/power/level       # turn on
echo suspend > /sys/bus/usb/devices/usb1/power/level  # turn off

(您可能需要将 usb1更改为 usbN)

来源: Document/usb/power-management. txt. gz

根据 译自: 美国《科学》杂志网站(http://www.kernel.org/doc/Document/usb/power-management. txt),从内核 2.6.32的 USB 电源管理有几个变化,这似乎解决在 2.6.38。现在,您需要等待设备变成 无所事事,它由特定的设备驱动程序控制。驱动程序需要支持它,否则设备将永远不会达到这种状态。不幸的是,现在用户没有机会强制执行此操作。然而,如果你足够幸运,你的设备可以空闲,那么要关闭它,你需要:

echo "0" > "/sys/bus/usb/devices/usbX/power/autosuspend"
echo "auto" > "/sys/bus/usb/devices/usbX/power/level"

约2.6.38或以上的谷粒:

echo "0" > "/sys/bus/usb/devices/usbX/power/autosuspend_delay_ms"
echo "auto" > "/sys/bus/usb/devices/usbX/power/control"

这从字面上意味着,在设备空闲的那一刻启动 停职

因此,除非你的风扇是某种“智能”设备,可以看作是一个设备,并由驱动程序控制,你可能不会有太多的运气在目前的内核。

我已经找到了这些解决方案,至少适用于正确配置的 TerminasFE 1.1 USB 集线器芯片:

要关闭集线器所有 USB 端口的电源,您可以使用以下方法解除集线器与内核的绑定:

echo "1-4.4.4" > /sys/bus/usb/drivers/usb/unbind

重新启动电源-你可以使用

echo "1-4.4.4" > /sys/bus/usb/drivers/usb/bind

2.在每个端口单独切换电源比较棘手: 我可以使用 巨大的能量来控制每个端口——但它有一个缺点: hubpower 首先断开 usbdevfs,这会导致所有 USB 设备从系统断开,至少在 ubuntu 上是这样:

usb_ioctl.ioctl_code = USBDEVFS_DISCONNECT;
rc = ioctl(fd, USBDEVFS_IOCTL, &usb_ioctl);

禁用了 ioctl之后,我可以在不拆卸所有设备的情况下关闭单独的端口电源——但是电源会立即恢复(可能是因为内核看到了一个未初始化的设备) ,这会导致 USB 设备只是做一个“冷重启”,这是我通常想做的。我的补丁是 给你

echo '2-1' |sudo tee /sys/bus/usb/drivers/usb/unbind

为 Ubuntu 工作

来自 Intel 的 PowerTOP 允许您实时地切换设备,例如 usb 外围设备。

sudo apt install powertop
sudo powertop
  • 选项卡到“可调参数”。
  • 向下滚动到你的设备。
  • 点击进入切换节电模式(很好/很糟糕)

enter image description here

请注意,很糟糕表示设备始终处于打开状态。切换到 很好将在预设的非活动保存时间后关闭设备(默认为2000ms)。

有关如何使这些更改永久化的详细信息,请参阅 PowerTOP文档。< bR > 它为您生成配置脚本(与本线程的其他海报所描述的非常相似)。

注意: 这些脚本不影响 USB 引脚电源(总是打开)。
这些只发送驱动程序协议来激活和停用设备。 < br > < br > 如果你想控制引脚功率,你可以使用支持的智能 USB 集线器,或者更好的是 微控制器

你可以使用我的工具 < strong > uhubctl 来控制兼容 USB 集线器的每个端口的 USB 电源。

USB 5v 的电源总是开着的(即使在计算机关机的时候,在一些计算机上和一些端口上也是如此)您可能需要编程一个 Arduino 与某种交换机,并通过串行库控制它从 USB 插入到计算机。

换句话说,结合 这个开关教程和 这个教程通过串行库通信 Arduino 插入通过 USB。

我在连接我的机器人手机时遇到了一个问题,我不能给我的手机充电,因为电源开关一开一关..。 PowerTop 让我找到了这个设置,对于修复这个问题很有用(auto value 导致了这个问题) :

echo 'on' | sudo tee /sys/bus/usb/devices/1-1/power/control

为什么人们发布这样的问题是由于可怕的-实际上是“ 邪恶”-USB 自动暂停“ 特写”。

自动挂起电源-关闭一个“空闲”的 USB 设备,除非设备的驱动程序正确支持这一功能,设备可以成为无法联系。因此,为 USB 接口供电是问题的症状,而不是问题本身。

我将告诉你如何禁用 全球性的自动挂起,取消需要手动切换 USB 端口的开关:

简短的回答:

您不需要单独编辑“ < em > 自动暂停 _ 延迟 _ ms ”: USB 自动挂起可以在全局范围内禁用,坚持不懈可以使用以下命令:

sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT="/&usbcore.autosuspend=-1 /' /etc/default/grub


update-grub


systemctl reboot

一个 Ubuntu 18.04 屏幕截图如下在“长答案”的结尾说明我的结果是如何实现的。

答案很长:

的确,USB 电源管理内核文档声明自动挂起将被废弃,取而代之的是用来禁用 USB 自动挂起的“ < em > 自动暂停 _ 延迟 _ ms ”:

"In 2.6.38 the "autosuspend" file will be deprecated
and replaced by the "autosuspend_delay_ms" file."

然而 我的测试显示,在 < em >/etc/default/grub 中设置 usbcore.autosuspend=-1如下所示,可以作为 USB 自动挂起功能的 全球开关——你需要编辑单个的“ < em > 自动暂停 _ 延迟 _ ms ”文件。

上面链接的同一个 文件状态的值“0”是 启动,而 没有的值是 残疾人:

power/autosuspend_delay_ms


<snip> 0 means to autosuspend
as soon as the device becomes idle, and negative
values mean never to autosuspend.  You can write a
number to the file to change the autosuspend
idle-delay time.

在下面的带注释的 Ubuntu 18.04 屏幕截图中,说明了我的结果是如何实现的(并且是可重复的) ,请注意 < em > 自动暂停 _ 延迟 _ ms 中的默认值是“0”(启用)。

然后注意,在 Grub 中 仅此而已设置为 usbcore.autosuspend=-1后,这些值在重新启动后现在为负值(残疾人)。这将节省我的麻烦编辑个别值,现在可以脚本禁用 USB 自动挂起。

screengrab: autosuspend values Before and after globally editing

希望这使得禁用 USB 自动挂起变得更加容易和更加脚本化

到目前为止,我得出的结论是,你 不能控制 USB 端口的电源。5V 的 USB 总是提供,它是否使用取决于设备。你可以用5V 风扇或灯来检查。 我尝试了各种方法(断开/重新连接/绑定/取消绑定/重置信号) 。到目前为止最好的是绑定/解除绑定,因为它强制设备的冷重启(但没有电源循环)。

我想出了一个在 Python 脚本中重置 USB 设备、端口和控制器的解决方案,它支持上述所有方法。 你可以在我的 Github 页面找到这个脚本

用法:

usb_reset.py -d 8086:1001 --reset-hub

该脚本使用了以下解决方案来重置 USB 集线器/控制器:

解除 USB 端口/控制器的绑定最好通过:

echo "myhub" > "/sys/bus/usb/drivers/usb/unbind"
echo "myhub" > "/sys/bus/usb/drivers/usb/bind"

/sys/bus/usb/devices/*中找到 myhub 的地方

或者文字控制器:

echo "mycontroller" > "/sys/bus/pci/drivers/unbind"
echo "mycontroller" > "/sys/bus/pci/drivers/bind"

/sys/bus/pci/drivers/[uoex]hci_hcd/*:*中找到 mycontroller 的位置