在我们的 Linux 盒子中,我们有 USB -> 串行设备,它始终被标识为
/dev/ttyACM0
.所以我写了一个应用程序,直到昨天,一切都运行良好。但突然(是的,在远程演示期间......)设备停止工作。经过快速研究,我发现连接更改为/dev/ttyACM1
.这有点不合时宜,但现在我遇到了一个问题 - 如何明确地识别我的设备?例如,存储驱动器可以使用 UUID 进行初始化,尽管 UUID/dev/sd**
已发生变化。有什么方法可以为串行设备做到这一点吗?
现在我使用一个愚蠢的解决方法:
for(int i = 0; i < 10; i ++)
{
m_port = std::string("/dev/ttyACM") + (char)('0' + i);
m_fd = open(m_port.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
}
这关联到我们使用的设备。
答案1
由于我们正在讨论 USB 设备并假设您有 udev,因此您可以设置一些 udev 规则。
我猜,这只是一个疯狂的猜测,某人或某事拔掉/删除了设备,然后将其重新插入/再次添加了设备,这导致了数字的增加。
现在,首先您需要供应商和产品 ID:
$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 011: ID 0403:6001 FTDI FT232 USB-Serial (UART) IC
接下来,您需要序列号(如果您有多个):
# udevadm info -a -n /dev/ttyUSB1 | grep '{serial}' | head -n1
ATTRS{serial}=="A6008isP"
现在,让我们创建一个 udev 规则:
UDEV 规则通常分散在/etc/udev/rules.d
.创建一个名为的新文件99-usb-serial.rules
,并将以下行放入其中,我有三个设备,每个设备都有不同的序列号:
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A6008isP", SYMLINK+="MySerialDevice"
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A7004IXj", SYMLINK+="MyOtherSerialDevice"
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="FTDIF46B", SYMLINK+="YetAnotherSerialDevice"
ls -l /dev/MySerialDevice
lrwxrwxrwx 1 root root 7 Nov 25 22:12 /dev/MySerialDevice -> ttyUSB1
如果您不需要序列号,则来自供应商的具有相同芯片的任何设备都将获得相同的符号链接,在任何给定时间只能插入一个。
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="MySerialDevice"
答案2
UDEV 规则是个好主意,但许多设备没有串行或具有相同的串行,这不能解决 ttyACM0 到 ttyACM1 的问题
尝试
systemctl stop ModemManager systemctl 禁用 ModemManager
PS我不是魔术师,我只是在学习,但友谊可以帮助我们创造真正的奇迹