Событие подключения/отключения 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-хосту), то нет хорошего способа отловить события включения/отключения.

Доказательство: сообщение Грега Кроа-Хартмана
другая копия, если предыдущая ссылка не работает