Форум программистов, компьютерный форум, киберфорум
Eddy_Em
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  

Различаем USB-устройства с одинаковыми VID/PID

Запись от Eddy_Em размещена 11.04.2023 в 17:36
Показов 2123 Комментарии 0
Метки c, stm32, usb, железяки, си

В возне с прототипом спектрографа ESPriF, наткнулся на то, что все мои три железяки (контроллер восьми шаговиков, контроллер объектива Canon и контроллер узла калибровки) абсолютно никак в системе не различаются: те же самые VID/PID/Manufacturer (собственно, эмулирую PL2303). Подсказали мне, что можно завести текстовое поле Interface, которое поможет в дальнейшей идентификации. И вот на "заполнялке азотом" я решил поиграться. Заодно лишний раз оптимизировал USB, выкинув ненужные флаги. Все индексы текстовых дескрипторов задаются в дескрипторе устройства и конфигурационном дескрипторе. Скажем: iManufacturer, iProduct, iSerialNumber и тот самый iInterface. Чтобы не запутаться, проще завести enum, его поля и использовать как индексы. Если мы не хотим отдавать дескрипторы, задаем вместо индекса нуль. Ну, а дальше компьютер запрашивает нужный индекс и получает текстовую строку, которую и можно использовать в правиле udev, чтобы вместо кучи /dev/ttyUSBx создать более понятные (например, /dev/nitrogen_flooding0 или /dev/canusb0).
Вот с правилами UDEV пришлось повозиться подольше: благо, есть udevadm test, так что не пришлось постоянно шнурок туда-сюда втыкать/вытыкать. Сложность вызвало то, что поле Interface лежит в одном "устройстве", а поля VID/PID — в "родительских". Как обычно, SO помог в решении этой проблемы (что бы мы без Stack Overflow делали вообще? Я, например, по латеху там кучу проблем решил, ну и сам немного людям помог; да и по C, линуксу, башу…).
Одним словом, чтобы различить устройства с одинаковым VID/PID, нам нужно это правило:
Code
1
2
ACTION=="add", DRIVERS=="usb", ENV{USB_IDS}="%s{idVendor}:%s{idProduct}"
ACTION=="add", ENV{USB_IDS}=="067b:2303", ATTRS{interface}=="?*", SYMLINK+="$attr{interface}%n"
Т.е. когда udev будет пробегаться по всем "родительским устройствам", на стадии добавления в систему USB он заведет переменную USB_IDS а когда пройдется по "дочернему" устройству, проверит, соответствует ли эта переменная нужному VID:PID. Если соответствует — проверит, есть ли поле iInterface (нам не нужно "настоящие" PL2303 там именовать, да и у них все равно нет этого поля), и если оно есть — создаст нужную ссылочку.
В простейшем же случае (в данном) наше устройство отличается от всех остальных полем "DRIVERS" (которое как раз является свойством "подустройства" с полем interface), поэтому можно упростить правило:
Code
1
DRIVERS=="pl2303", ACTION=="add", ATTRS{interface}=="?*", SYMLINK+="$attr{interface}%n"
Все, как только добавили устройство с нужным полем DRIVERS и существующим атрибутом interface, создастся нужная символическая ссылка.
Теперь достаточно для каждого USB-устройства только лишь менять название этого поля. И в системе теперь не придется перебирать из кучи /dev/ttyUSBx, чтобы найти свое устройство — на него будет удобный симлинк. Да и все демоны будут элементарно стартовать (не нужно будет перебирать устройства и запрашивать "ТЫ ХТО, Э?").
Кстати, COKPOWEHEU еще напомнил мне, что неизвестно, как себя поведет этот "%n" в правиле udev: ведь если ядро будет отдельно нумеровать каждый интерфейс составного устройства, получится совсем не то, что ожидалось (скажем, подключенное составное устройства вместо /dev/rs485_0, /dev/rs232_0, /dev/can0 и /dev/converter_setup0 создаст /dev/rs485_0, /dev/rs232_1, /dev/can2 и /dev/converter_setup3).
Метки c, stm32, usb, железяки, си
Размещено в Linux
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 0
Комментарии
 
Новые блоги и статьи
[golang] Алгоритм «Хак Госпера»
alhaos 17.05.2026
Алгоритм «Хак Госпера» Хак Госпера (Gosper's Hack) — алгоритм нахождения следующего по величине числа с тем же количеством установленных бит. Придуман Биллом Госпером в 1970-х, опубликован в. . .
Рисование бинарного древа до 6-го колена на js, svg.
russiannick 17.05.2026
<svg width="335" height="240" viewBox="0 0 335 240" fill="#e5e1bb"> <style> <!]> </ style> <g id="bush"> </ g> </ svg> function fn(){ let rost;/ / высота древа let xx=165,yy=210,w=256;
FSharp: interface of module
DevAlt 16.05.2026
Интерфейс модуля F# позволяет управлять доступностью членов, содержащихся в реализации модуля. По-умолчанию все члены модуля доступны: module Foo let x = 10 let boo () = printfn "boo" . . .
Хитросплетение родственных связей пантеона греческих богов.
russiannick 14.05.2026
Однооконник, позволяющий узреть и изучить отдельных героев древней Греции. <!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible". . .
[golang] Угол между стрелками часов
alhaos 12.05.2026
По заданным значениям часа и минуты необходимо определить значение меньшего угла между стрелками аналогового циферблата часов. import "math" func angleClock(hour int, minutes int) float64 { . . .
Debian 13: Установка Lazarus QT5
ВитГо 09.05.2026
Эта инструкция моя компиляция инструкций volvo https:/ / www. cyberforum. ru/ blogs/ 203668/ 10753. html и его же старой инструкции по установке Lazarus с gtk2. . .
Нейросеть на алгоритме "эстафета хвоста" как перспектива.
Hrethgir 06.05.2026
На десерт, когда запущу сервер. Статья тут https:/ / habr. com/ ru/ articles/ 1030914/ . Автор я сам, нейросеть только помогает в вопросах которые мне не известны - не знаю людей которые знали-бы. . .
Асинхронный приём данных из COM-порта
Argus19 01.05.2026
Асинхронный приём данных из COM-порта Купил на aliexpress термопринтер QR701. Он оказался странным. Поключил к Arduino Nano. Был очень удивлён. Наотрез отказывается печатать русские буквы. Чтобы. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru