Ubuntu 重连usb设备(断电和不断电方案)亲测可行
0. Preface
有时再测试过程中,需要通过指令的方法重新连接设备,有时需要断电,有时不能断电,所以有两个方案:
1. 断电方案
- 这里要从github上下一个包
hub_ctrl
git clone https://github.com/yy502/hub-ctrl
sudo apt-get install libusb-dev gcc
- 进入hub-ctrl的路径以及编译
cd hub-ctrl
gcc -o hub-ctrl hub-ctrl.c -lusb -std=c99
- 然后运行
sudo ./hub-ctrl/hub-ctrl
就可以查看当前各个usb口的设备供电情况,如下
will@will-Dell-G15-5511:~/Packages$ sudo ./hub-ctrl/hub-ctrl
Hub 0 (Bus 4, Dev 1) - ganged power switching
Hub 1 (Bus 3, Dev 1) - no power switching├─ Port 1: power├─ Port 2: power├─ Port 3: power low-speed connect enable├─ Port 4: power high-speed connect enable├─ Port 5: power high-speed connect enable├─ Port 6: power high-speed connect enable├─ Port 7: power├─ Port 8: power├─ Port 9: power├─ Port 10: power├─ Port 11: power├─ Port 12: power├─ Port 13: power├─ Port 14: power connect enable├─ Port 15: power└─ Port 16: power
Hub 2 (Bus 2, Dev 1) - no power switching├─ Port 1: low-speed├─ Port 2: low-speed├─ Port 3: low-speed├─ Port 4: low-speed
> Cannot read port 5 status
Hub 3 (Bus 1, Dev 1) - no power switching└─ Port 1: power
如果我想power off其中一个设备的供电,如hub1的port4,是一个usb鼠标设备,运行sudo ./hub-ctrl/hub-ctrl -H 1 -P 4 -p 0
,然后看到以下输出:
> Hub:1 Bus:0 Devive:0 Port:4 power->off
这时这个usb口的供电已经被断开了。这时再一次查看usb设备供电情况,显示如下:
will@will-Dell-G15-5511:~/Packages$ sudo ./hub-ctrl/hub-ctrl
Hub 0 (Bus 4, Dev 1) - ganged power switching
Hub 1 (Bus 3, Dev 1) - no power switching├─ Port 1: power├─ Port 2: power├─ Port 3: power low-speed connect enable├─ Port 4:├─ Port 5: power high-speed connect enable├─ Port 6: power high-speed connect enable├─ Port 7: power├─ Port 8: power├─ Port 9: power├─ Port 10: power├─ Port 11: power├─ Port 12: power├─ Port 13: power├─ Port 14: power connect enable├─ Port 15: power└─ Port 16: power
Hub 2 (Bus 2, Dev 1) - no power switching├─ Port 1: low-speed├─ Port 2: low-speed├─ Port 3: low-speed├─ Port 4: low-speed
> Cannot read port 5 status
Hub 3 (Bus 1, Dev 1) - no power switching└─ Port 1: power
可以看到hub1中的port4口已经没有了power的字符,说明已经断电了,其实直接看看这个口对应的设备有没有亮电源灯也能知道。
- 然后重新供电的指令是
sudo ./hub-ctrl/hub-ctrl -H 1 -P 4 -p 1
,只改变了最后一个参数-p,从0变成1就打开电源。
上面这个指令有3个参数,第一个-H指的是hub的编号,第二个-p指的是port编号。最后一个参数-p指的power on/off
PS:至于怎么知道对应的hub和port编号,插拔一下设备是最简单的方法。
2. 不断电方案
- 首先需要知道hub和port编号,这里可以直接用指令
lsusb -t
,会输出所有hub和port信息,如下:
will@will-Dell-G15-5511:~$ lsusb -t
/: Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/8p, 10000M|__ Port 4: Dev 3, If 0, Class=Communications, Driver=cdc_ncm, 5000M|__ Port 4: Dev 3, If 1, Class=CDC Data, Driver=cdc_ncm, 5000M|__ Port 4: Dev 3, If 2, Class=Vendor Specific Class, Driver=, 5000M|__ Port 4: Dev 3, If 3, Class=Vendor Specific Class, Driver=, 5000M|__ Port 4: Dev 3, If 4, Class=Vendor Specific Class, Driver=, 5000M|__ Port 4: Dev 3, If 5, Class=Vendor Specific Class, Driver=, 5000M|__ Port 4: Dev 3, If 6, Class=Vendor Specific Class, Driver=, 5000M
/: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/16p, 480M|__ Port 3: Dev 9, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M|__ Port 5: Dev 3, If 0, Class=Video, Driver=uvcvideo, 480M|__ Port 5: Dev 3, If 1, Class=Video, Driver=uvcvideo, 480M|__ Port 6: Dev 4, If 0, Class=Imaging, Driver=usbfs, 480M|__ Port 6: Dev 4, If 1, Class=Vendor Specific Class, Driver=usbfs, 480M|__ Port 6: Dev 4, If 2, Class=Vendor Specific Class, Driver=ipheth, 480M|__ Port 14: Dev 5, If 0, Class=Wireless, Driver=btusb, 12M|__ Port 14: Dev 5, If 1, Class=Wireless, Driver=btusb, 12M
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 10000M
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M
上面是接上设备的输出,下面显示的是没接上设备的输出:
will@will-Dell-G15-5511:~$ lsusb -t
/: Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/8p, 10000M
/: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/16p, 480M|__ Port 3: Dev 9, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M|__ Port 5: Dev 3, If 0, Class=Video, Driver=uvcvideo, 480M|__ Port 5: Dev 3, If 1, Class=Video, Driver=uvcvideo, 480M|__ Port 6: Dev 4, If 0, Class=Imaging, Driver=usbfs, 480M|__ Port 6: Dev 4, If 1, Class=Vendor Specific Class, Driver=usbfs, 480M|__ Port 6: Dev 4, If 2, Class=Vendor Specific Class, Driver=ipheth, 480M|__ Port 14: Dev 5, If 0, Class=Wireless, Driver=btusb, 12M|__ Port 14: Dev 5, If 1, Class=Wireless, Driver=btusb, 12M
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 10000M
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M
因此就可以知道这个设备是由bus 4和port 1供电的。
unbind
和bind
操作
在terminal输入echo '4-1' | sudo tee /sys/bus/usb/drivers/usb/unbind
即可解除绑定状态,会有如下输出
4-1
过1-2秒然后重新绑定,输入echo '4-1' | sudo tee /sys/bus/usb/drivers/usb/bind
,会有如下输出:
4-1
以上即完成了一次对特定usb设备的重新连接。
可以写成一个sh文件来执行,如下,文件名usb_rebind.sh
#!/bin/bash# Unbind the USB device
sudo bash -c 'echo "4-1" > /sys/bus/usb/drivers/usb/unbind'# Wait for 2 seconds
sleep 2# Bind the USB device
sudo bash -c 'echo "4-11" > /sys/bus/usb/drivers/usb/bind'
PS: 我也试过更具体的操作如’4-1.3’这类的,但是会报错,如下所示。所以现在直接到上一级重新设置绑定状态。有大神知道的,欢迎留言告知,感谢。
4-1.3
tee: /sys/bus/usb/drivers/usb/bind: No such device