У меня несколько одинаковых USB-устройств.Каждое устройство перечисляет несколько портов ttyACM в каталоге / dev.Каждый порт имеет свое уникальное назначение, один для обработки некоторых команд, другой для диагностики и т. Д. Я хочу, чтобы псевдонимы для конкретного устройства создавались символические ссылки с возможностью различать, к какому устройству принадлежит этот порт.
Например:
DEVICE_UNIQUENUM_PURPOSE
/dev/MODULE_0_DIAG
/dev/MODULE_0_CMD
/dev/MODULE_1_DIAG
/dev/MODULE_1_CMD
Для этого я начал работать с udev для написания правил для моего устройства.Я узнал, что udev не может перечислять символические ссылки для одного и того же устройства так, как я хочу.Поэтому я решил написать скрипт bash, который сделает всю работу.Вот правила:
ACTION=="add", KERNEL=="ttyACM[0-9]*", SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{idVendor}=="1e2d", ATTRS{idProduct}=="0063", PROGRAM="/bin/bash /home/user/script.sh %k", SYMLINK+="%c"
ACTION=="remove", SUBSYSTEM=="usb", DRIVER=="usb", ATTRS{idVendor}=="1e2d", ATTRS{idProduct}=="0063", PROGRAM="/bin/bash /home/user/script.sh"
В основном сценарий начинается с проверки того, какое действие имело место «добавить» или «удалить», и на основании этого предпринимает следующие шаги.Сложность в том, что правило add добавляет сценарий сразу несколько раз, поскольку одновременно обрабатывается несколько устройств tty.Поэтому для синхронизации моего сценария я реализовал простой мьютекс, основанный на создании каталога в каком-то месте.Если каталог присутствует, другие сценарии будут ждать, пока они не смогут его создать.Двигаясь вперед, добавьте операцию:
- Создает временную базу данных, если ее нет
- На основе информации, передаваемой udev, она определяет, что это за тип устройства и какой уникальный номер ему следует дать.
- Записывает запись в базу данных для данного конкретного tty
Операция удаления:
- На основе серийного номера, переданного от udev, следует удалить все записи для соответствия ttyустройства.
Теперь проблема.По какой-то причине действие «удалить» не запускает мой скрипт должным образом.Для действия «добавить» все работает без нареканий.При подключении устройства записи записываются в файл базы данных правильно для каждого tty.Когда я отключаю скрипт устройства, большую часть времени он даже не запускается.Иногда так и будет.Ранее у меня было почти то же правило для действия «удалить», что и для «добавить»:
ACTION=="remove", KERNEL=="ttyACM[0-9]*", SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{idVendor}=="1e2d", ATTRS{idProduct}=="0063", PROGRAM="/bin/bash /home/user/script.sh %k"
Этот сценарий иногда запускается для одного tty, иногда для большего.Совершенно недетерминировано.Я понятия не имею, почему это ведет себя так.
Когда я использую утилиту "udevadm test" для имитации действия "удалить" для устройства, тогда он работает идеально каждый раз.Но для реального выхода это не так.Я также проверил с помощью «udevadm monitor», какие события происходят, и действия «удалить» присутствуют для устройства, поэтому все выглядит правильно.
Еще одна вещь, которую я попытался, состояла в том, чтобы изменить команду «PROGRAM» на команду «RUN», но этоне помогло.
После этого я решил сделать самый простой тест.Я написал это правило:
ACTION=="remove", SUBSYSTEM=="usb", DRIVER=="usb", ATTRS{idVendor}=="1244", ATTRS{idProduct}=="206d", RUN+="/bin/touch /home/user/udev/%k"
Предполагается, что для создания файла с именем «KERNEL» param устройства.Этого тоже не происходит!Но для действия «добавить» это работает!
Это сводит меня с ума.Я что-то пропустил?Я знаю, что udev указывает, что через «PROGRAM / RUN» нужно запускать только короткие задачи, но если это не короткая задача, то что?Также все работает для действия «добавить».У меня просто нет идей.Может быть, это недостаток Udev?