Enumerasi perangkat Linux yang konsisten

13

Dalam kotak Linux kami, kami memiliki USB -> perangkat serial yang selalu diidentifikasi sebagai /dev/ttyACM0. Jadi saya sudah menulis aplikasi dan sampai kemarin, semuanya bekerja dengan baik. Tapi tiba-tiba (yeah, selama presentasi jarak jauh ...) perangkat berhenti bekerja. Setelah riset cepat, saya menemukan bahwa koneksi berubah menjadi /dev/ttyACM1. Itu agak terlalu cepat, tapi sekarang saya punya masalah - bagaimana cara mengidentifikasi perangkat saya dengan jelas? Seperti, misalnya, drive penyimpanan dapat diinisialisasi dengan menggunakan UUID meskipun /dev/sd**telah berubah. Apakah ada cara untuk melakukannya untuk perangkat serial?

Sekarang saya menggunakan solusi bodoh:

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);
}

The Link ke perangkat yang kita gunakan.

folibis
sumber

Jawaban:

19

Karena kita berbicara perangkat USB dan dengan asumsi Anda memiliki udev, Anda dapat mengatur beberapa aturan udev.

Saya kira, dan ini hanya tebakan liar, seseorang atau sesuatu mencabut / melepas perangkat dan memasangnya kembali / menambahkan perangkat lagi, yang menambah nomornya.

Sekarang, pertama-tama Anda membutuhkan ID vendor dan produk:

$ 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

Selanjutnya, Anda memerlukan nomor seri (jika Anda memiliki beberapa):

# udevadm info -a -n /dev/ttyUSB1 | grep '{serial}' | head -n1
    ATTRS{serial}=="A6008isP"

Sekarang, mari buat aturan udev:

Aturan UDEV biasanya tersebar ke banyak file di /etc/udev/rules.d. Buat file baru yang disebut 99-usb-serial.rulesdan letakkan baris berikut di sana, saya memiliki tiga perangkat, masing-masing dengan nomor seri yang berbeda:

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

Jika Anda tidak menginginkan nomor seri, perangkat apa pun dari vendor dengan chip yang sama akan mendapatkan symlink yang sama, hanya satu yang dapat dicolokkan pada waktu tertentu.

SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="MySerialDevice"

Diambil dari sini

sampah
sumber
3
Jika Anda memiliki distribusi linux baru-baru ini, kemungkinan besar itu sudah secara otomatis membuat perangkat sebagai /dev/serial/by-id/usb-XXXX_USB2.0-Serial-if00-port0. Ini mungkin cukup untuk Anda tanpa aturan udev khusus.
Josef berkata Reinstate Monica
1
Sayangnya, banyak perangkat tanpa nama semuanya memiliki nomor seri "0123456789abcdef". Di situlah menjadi menarik.
Mosvy
@mosvy apakah nomor seri tidak dapat diubah?
OganM
@ OganM mereka dapat diubah ... jika Anda dapat me-rooting perangkat.
Mosvy