Однозначный tty для USB-устройств в FreeBSD

от автора

Несколько лет назад пришлось решать следующую задачу. К хосту под управлением FreeBSD подключается несколько однотипных USB-устройств. Программное обеспечение хоста работает с ними через файлы символьных устройств. Понятно, что при произвольном переключении шнурков USB или при перезагрузке хоста, файлы символьных устройств нумеруются (в общем случае) совсем не в том порядке, как при первом подключении. В моем случае USB-устройства — конвертеры интерфейсов на которых висят шины RS-485 с приборами. Никаких возможностей автоматически определить по приборам в шине, какие шины повисли на каком порту нет. Таким образом непонятно, какие файлы символьных устройств каким физическим устройствам соответствуют в данный момент. Кому интересно решение, прошу под кат. Несмотря на специфичность задачи, способ универсальный.

Идея. При подключении USB-устройства, определять имя файла символьного устройства, которое выдано системой (типа ttyUx), производителя, тип, s/n устройства и создавать в /dev ссылку с заранее определенным именем для этого s/n, указывающую на уже известный ttyUx. Т.о. наш софт всегда будет работать с известными именами файлов символьных устройств — предопределенными ссылками, которые соответствуют конкретному устройству.

Реализация.

Для того, чтоб узнать подробности про USB-устройство:

usbconfig dump_device_desc ... ugen1.2: <USB-Serial Controller Prolific Technology Inc.> at usbus1, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON   bLength = 0x0012    bDescriptorType = 0x0001    bcdUSB = 0x0110    bDeviceClass = 0x0000    bDeviceSubClass = 0x0000    bDeviceProtocol = 0x0000    bMaxPacketSize0 = 0x0040    idVendor = 0x067b    idProduct = 0x2303    bcdDevice = 0xa7d4    iManufacturer = 0x0001  <Prolific Technology Inc.>   iProduct = 0x0002  <USB-Serial Controller>   iSerialNumber = 0x0003  <0000A7D4>   bNumConfigurations = 0x0001  ... 

Редактируем /etc/devd.conf. Пишем что-то вроде:

# When the ICPCON USB Converter appear... attach 100 {         match "device-name" "uplcom[0-9]";         match "vendor" "0x067b";         match "product" "0x2303";         match "release" "0xa7d4";         action "/usr/local/bin/uplcom2ttyU $device-name /dev/icpcon1"; }; detach 100 {         match "device-name" "ugen+";         match "vendor" "0x067b";         match "product" "0x2303";         match "release" "0xa7d4";         action "rm /dev/icpcon1"; }; 

Думаю, смысл этой записи понятен. Осталось «нарисовать» uplcom2ttyU, который создаст ту самую ссылку, однозначную, в примере — /dev/icpcon1. Для каждого устройства нужно делать в devd.conf соответствующую запись. Не забываем менять имя ссылки (у меня /dev/icpcon1) в двух местах: attach, detach, — мы же хотим, чтоб ссылка исчезала с отключением устройства.

cat /usr/local/bin/uplcom2ttyU #!/bin/sh # arg #1 - $device-name from devd.conf - uplcomX; arg #2 - new link to ttyUX - /dev/..... ln -s $(echo /dev/$1 | sed 's/uplcom/ttyU/g') $2 

Видно, что запись uplcom меняется на ttyU, поскольку в /dev система создает именно ttyUx, где x совпадает с номером uplcom.

Вот и все. Однако, до сих пор целостного описания решения подобной проблемы не найти в Интернет. Разве только мои посты на форуме одного известного ресурса.

ссылка на оригинал статьи http://habrahabr.ru/post/200330/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *