私たちのLinuxボックスには、常に/dev/ttyACM0
として識別されるUSB->シリアルデバイスがあります。だから私はアプリケーションを書いて、昨日まで、すべてがうまくいきました。しかし、突然(そう、リモートプレゼンテーション中に...)デバイスが機能しなくなりました。簡単な調査の結果、接続が/dev/ttyACM1
に変わったことがわかりました。それは少し早まったですが、今問題があります-デバイスを明確に識別する方法は?たとえば、/dev/sd**
が変更されていても、UUIDを使用してストレージドライブを初期化できます。シリアルデバイスでそれを行う方法はありますか?
今、私は愚かな回避策を使用します:
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);
}
link は、使用するデバイスへのリンクです。
ここでは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
という新しいファイルを作成し、そこに次の行を挿入します。3つのデバイスがあり、それぞれに異なるシリアル番号が付いています。
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
シリアル番号が必要ない場合は、同じチップを搭載したベンダーのデバイスは同じシンボリックリンクを取得します。同時に接続できるのは1つだけです。
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="MySerialDevice"