用一台PC做的服务器,USB上插了个串口工具,每次重启系统,这个设备都无法自动打开,必须手动插拔一下,所以需要一个能重新上电USB设备的脚本。
使用udev规则断电、上电USB设备,实现命令行重新插拔USB的效果,我使用的脚本如下,仅供参考:
#!/bin/bash
# USB设备的ID,通过lsusb 查看, 一定要改为自己的
usb_id="1111:2222"
# USB设备的供电状态文件路径,这里的usbX根据实际情况改为usb0或usb1..... 等
power_file="/sys/bus/usb/devices/【usbX】/power/control"
# 检查USB设备是否已连接
if lsusb | grep -q "$usb_id"; then
# 打开USB口的供电
echo "on" > "$power_file"
echo "USB口已打开供电"
else
echo "USB设备未连接"
fi
通过lsusb命令USB设备的ID:
qgbf@rangotec.com# lsusb
Bus 003 Device 002: ID 8087:8001 Intel Corp. Integrated Hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:8009 Intel Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 002 Device 002: ID c251:f001 Keil Software, Inc. CMSIS-DAP
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
我的STM32下载调试器的ID是 【c251:f001】,把脚本里的的ID替换为这个ID。
把脚本里的usbX 替换为实际的 usb2。 然后运行即可实现重新插拔的效果。
如果不确定usbX到底是哪个,可以进入到对应的目录,如usb3目录,目录下有个power/control文件,这个文件就是用来控制电源的,通过写入on或者0来上电或者断电。
新建usb-reset.c 文件,粘贴以下内容:
/*重启usb硬件端口*/
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <linux/usbdevice_fs.h>
int main(int argc, char **argv)
{
const char *filename;
int fd;
int rc;
if (argc != 2) {
fprintf(stderr, "Usage: usbreset device-filename\n");
return 1;
}
filename = argv[1];//表示usb的ID
fd = open(filename, O_WRONLY);
if (fd < 0) {
perror("Error opening output file");
return 1;
}
printf("Resetting USB device %s\n", filename);
rc = ioctl(fd, USBDEVFS_RESET, 0);//ioctl是设备驱动中,对I/O设备进行管理的函数
if (rc < 0) {
perror("Error in ioctl");
return 1;
}
printf("Reset successful\n");
close(fd);
return 0;
}
然后gcc编译一下:
qgbf@rangotec.com$ gcc usb-reset.c -o usb-reset
赋予执行权限:
qgbf@rangotec.com$ chmod +x usb-reset
然后执行程序:
./usb-reset /dev/bus/usb/002/002
完事。
注意事项:
重新上电后还是无法读usb串口设备,执行完重置命令后等待1~2秒后再打开串口。