c++ - 在 Linux 中无需拔出即可软重置 USB 设备
问题描述
问题: 我有 USB 设备连接到远程 linux 机器。我想使用文件描述符重置它们。
我使用通用端口名称连接到一个端口/dev/usbTTYXX
。不幸的是,我很快发现这是一种不好的方法,因为它们是按顺序生成的。如果我首先插入一个 tty 设备,它将生成ttyUSB0
,如果我插入第二个 tty 设备,它将生成TTYUSB1
,依此类推。不幸的是,我有太多不同的ttyUSB
设备和其他破坏此顺序的设备。简而言之,它只是对用户不友好,是一场噩梦。我发现最好使用/dev/serial/by-id
. 这是最好的选择,因为它们看起来非常独特,即使在重新启动后也不会改变,尽管插入 USB 的顺序也会重新启动。
所以我可以像这样以更健壮的方式打开一个端口。(我什至为此有一个json)
// old
int serial_port = open("/dev/ttyUSB1", O_RDWR | O_NOCTTY);
// new
int serial_port = open("/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_AC00MET6-if00-port0", O_RDWR | O_NOCTTY);
无论我重新连接多少,USB 设备都不会改变(与 /dev/ttyUSB0 不同)。无论如何,我发现这段代码可能会对设备执行软重置,所以我不需要重新插入它。这是源代码:
如果我使用这个文件描述符/dev/bus/usb/001/010
,它就可以工作。/dev/bus/usb/XXX/YYY
其中 XXX 是总线号(在 Pi 上几乎总是 001),YYY 是设备号(从 lsusb 获取这两个)。同样 lsusb 似乎也经常变化。(更麻烦的是,我有类似的 USB 设备适配器使用相同的产品和供应商 ID!)
但是,如果我使用/dev/ttyUSB0
或通过 id 使用/dev/serial/by-id/
. 我得到的错误是Error in ioctl: Inappropriate ioctl for device.
.
问题:如何将 ioctrl USBDEVFS_RESET 方法与 /dev/serial/by-id/
文件 simlinks 一起使用?
/* usbreset -- send a USB port reset to a USB device */
#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];
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);
if (rc < 0) {
perror("Error in ioctl");
return 1;
}
printf("Reset successful\n");
close(fd);
return 0;
}
解决方案
推荐阅读
- excel - Excel - 找到包含 X 元素的最佳数量
- shell - 通过 CI 将本地无版本文件复制/提交到 SVN 版本文件
- php - 删除图像背景在 php imagick 中无法正常工作
- html - 从 Excel 公式进行 Google 搜索并将结果放入单元格中
- openedge - 访问过程库中的单例对象时访问冲突
- javascript - 在浏览器中调整 ImageData 大小的快速方法?
- javascript - 循环通过香草JS中的对象内部的对象
- reactjs - 使用 Typescript 导入 React-Select 失败
- acumatica - 如何将自定义 ZPL 标签从移动设备打印到连接到设备集线器的打印机?
- rabbitmq - RabbitMQ - “Not Before”过滤器