如何对 Raspberry Pi 上的 USB 设备进行电源循环?

如何对 Raspberry Pi 上的 USB 设备进行电源循环?

我的 Raspberry Pi 上的 Netgear WiFi 棒(使用 ath9k_htc 驱动程序)会定期进入不良状态,导致 dmesg 中出现 USB 读取错误。此状态无法通过系统重置来纠正,但需要对 USB 设备进行完全电源循环,方法是拔下它并重新插入 USB 棒,或对整个计算机进行电源循环。

我读到,可以使用 USB 集线器以编程方式循环为 USB 设备供电。因此,我根据此帖子中的信息,使用我的内部 4 端口 USB 2.0 集线器尝试了此操作:

https://stackoverflow.com/questions/1163824/linux-usb-turning-the-power-on-and-off

但是,即使发出以下命令后,USB WiFi 棒上的灯仍然亮着,尽管它确实使 wlan0 设备消失。我在 Belkin 4 端口集线器上尝试过,结果相同。有人有什么想法吗?

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

我的 USB 连接详情:

pi@fpi-16 ~ $ sudo lsusb -t
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=dwc_otg/1p, 480M
    |__ Port 1: Dev 2, If 0, Class=hub, Driver=hub/3p, 480M
        |__ Port 1: Dev 3, If 0, Class=vend., Driver=smsc95xx, 480M
        |__ Port 2: Dev 4, If 0, Class=hub, Driver=hub/4p, 480M
            |__ Port 1: Dev 5, If 0, Class=vend., Driver=rt2800usb, 480M
            |__ Port 3: Dev 6, If 0, Class=vend., Driver=ath9k_htc, 480M

答案1

如果您的 USB 主机驱动程序被编译为内核模块,您可以尝试卸载它并重新加载它。这通常也应该完全关闭 USB(我在其他有故障的 USB 硬件需要电气重置的设备上这样做,而不是专门在我没有的 Rasperry Pi 上)。因此,检查您是否将其视为模块(lsmod)或将其编译为模块,然后对其进行 rmmod(以及最终的所有依赖项)并再次重新加载它,它应该可以解决问题。

答案2

这个应用程序可以满足您的需要:https://github.com/codazoda/hub-ctrl.c

有关安装和使用说明,请参阅 README.md。

可能需要一些反复试验才能确定哪个集线器和端口与每个 USB 端口相对应,这似乎因 Raspberry Pi 型号而异。

通过发送 ap 0 命令(关闭电源)然后发送 ap 1(打开电源),可以在单个命令中实现电源循环。

答案3

先决条件:从以下网址下载并编译 usbresethttps://gist.github.com/x2q/5124616 用 编译gcc -o usbreset usbreset.c。GCC 应该已经安装在你的树莓派上了。然后chmod +x usbreset

如果您只有一个 USB 设备,您可以重置该设备,这样就可以正常工作。如果您有许多 USB 设备,则应该重置 USB 集线器。

要查找 USB 设备的 ID,请运行 lsusb。您应该会看到类似以下内容:总线 001 设备 009:ID 152d:0578 JMicron Technology Corp. / JMicron USA Technology Corp. 总线 001 设备 008:ID 1f75:0621 Innostor Technology Corporation 总线 001 设备 007:ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 快速以太网适配器 总线 001 设备 002:ID 0424:9514 Standard Microsystems Corp. SMC9514 集线器 总线 001 设备 001:ID 1d6b:0002 Linux Foundation 2.0 根集线器

我正在写的集线器是SMC9514集线器。

创建 .sh 文件:

#!/bin/bash

USBNAME=0424:9514 #Put here the usb ID
LSUSB=$(lsusb | grep --ignore-case $USBNAME)
FOLD="/dev/bus/usb/"$(echo $LSUSB | cut --delimiter=' ' --fields='2')"/"$(echo $LSUSB | cut --delimiter=' ' --fields='4' | tr --delete ":")
echo $LSUSB
echo $FOLD

sudo ./usbreset $FOLD; #The path where you have the usbreset executable

并在启动时运行它:bash usbreset.sh

在安装任何已正常工作的 USB 设备之前,您必须运行 usbreset.sh。例如,我的 Pi 有一个永久连接的 SSD 和两个由继电器板供电的 HDD。我必须在安装 SSD 之前运行重置命令,否则它将无法工作。

它也适用于您的设备。

希望能帮助到你。

相关内容