Событие подключения/отключения linux usb
Здравствуйте, я работаю над встроенным Linux-устройством с портом usb, который использует драйвер g_ether для сетей usb.
Когда подключен USB-разъем, выход dmesg:
g_ether gadget: полная конфигурация конфигурации # 2: RNDIS
Когда кабель USB отсоединен, ни одно сообщение не записывается в dmesg.
Использование C, как я могу прослушивать события connect/disconnect?
Встроенная ОС Linux не имеет никаких дополнительных функций. Демона dbus или помощника hotplug нет script. Я даже не уверен, что это было бы полезно.
Ответы
Ответ 1
Если вам нужно все в одном процессе, вам придется использовать libudev для получения событий из udevd
или непосредственно из ядра.
Видя, что может быть проблемой использование libudev в вашем приложении (отсутствие документации?), Альтернативой является использование программы udevadm, которая может:
- сообщать о событиях устройства после обработки
udevd
(udevadm monitor --udev --property
),
- сообщать о событиях отклонения непосредственно из ядра (
udevadm monitor --kernel --property
) и
- выгрузить базу данных udevd текущих устройств (но не ядра!) (
udevadm info --query all --export-db
)
udevadm
является частью пакета udev, но не должен нуждаться в udevd
, если вы используете его только для сообщения о событиях ядра. Вы можете использовать его, если ваш процесс порождает его и анализирует его стандартный вывод (но вам придется запускать его через stdbuf -o L
).
В любом случае, вероятно, будет много работы. Я уже реализовал многое из этого на своем языке программирования NCD, включая мониторинг USB-устройств. Возможно, вы захотите взглянуть на НИЗ; это полезно для многих задач конфигурации и хорошо справляется с горячим подключением. Например, эта программа NCD будет печатать события устройства USB на стандартный вывод:
process main {
sys.watch_usb() watcher;
println(watcher.event_type, " ", watcher.devname, " ", watcher.vendor_id, ":", watcher.model_id);
watcher->nextevent();
}
Это заставит NCD напечатать что-то подобное (с начальным событием added
для любого USB-устройства, которое уже было подключено):
added /dev/bus/usb/002/045 0409:0059
added /dev/bus/usb/002/046 046d:c313
added /dev/bus/usb/002/047 046d:c03e
added /dev/bus/usb/002/048 0557:2008
removed /dev/bus/usb/002/048 0557:2008
Вы также можете использовать NCD только для этого и анализировать этот стандартный вывод - с ним гораздо проще работать, чем напрямую связываться с udevadm.
Обратите внимание, что сам NCD использует udevadm
, и для этого требуется, чтобы udevd работал; но почему это проблема в любом случае? (при некоторой работе эта зависимость может быть удалена)
Ответ 2
Вы можете использовать libudev
или выполнить синтаксический анализ udevadm
в качестве предложения @Ambroz Bizjak. Хотя, я советую не добавлять дополнительный процесс (stdbuf
) и язык (NCD
), просто для разбора выходного файла udevadm.
Шаг между простым libudev и синтаксическим выражением изменяет источники udevadm. Это решение уменьшает необходимые ресурсы и вообще пропускает процесс анализа. Когда вы посмотрите на пакет udev, вы найдете источники для udevd и udevadm в каталоге udev
.
Там, у вас есть основная процедура в udevadm.c
и источник udevadm monitor
в udevadm-monitor.c
. Каждое полученное событие будет напечатано через print_device()
. Здесь вы вставляете свой код.
Если вы сильно зажаты в памяти, вы можете удалить ненужный код для control
, info
, settle
, test-builtin
, test
и trigger
. В моей системе (Ubuntu 12.04) это уменьшает размер udevadm примерно на 75%.
Ответ 3
К сожалению, при подключении/отключении на стороне гаджета не происходит событие udev, поэтому отслеживать эти события практически невозможно.
Вы можете отслеживать сообщения ядра (dmesg). Это кажется глупой идеей. Или посмотрите некоторые файлы в sysfs. Возможно, лучшим способом является исправление ядра.
обновление: Я не понимаю, почему этот ответ получил отрицательный рейтинг.
Возможно, некоторые люди смешивают часть USB-хоста (которая генерирует события UDEV при подключении/отключении устройства) и часть USB-устройства/гаджета (которая не генерирует такие события)
Если ваш Linux-компьютер работает как гаджет (USB-устройство, которое подключено к какому-либо USB-хосту), то нет хорошего способа отловить события включения/отключения.
Доказательство: сообщение Грега Кроа-Хартмана
другая копия, если предыдущая ссылка не работает