Linux的USB连接/断开事件

您好,我正在一个embedded式Linux设备与usb端口使用g_ether驱动程序的USBnetworking

当usb插头连接时,dmesg的输出是:

g_ether小工具:全速configuration#2:RNDIS

拔下USB电缆时,不会将消息写入dmesg。

使用C如何侦听连接/断开事件?

embedded式Linux操作系统没有任何附加function。 没有dbus守护进程或hotplug助手脚本。 我甚至不确定这些是否有用。

如果你想在你的单一进程中做所有的事情,你必须使用libudev来从udevd或直接从内核获取事件。

看到在应用程序中使用libudev可能会出现问题(缺少文档?),另一种方法是使用udevadm程序,该程序可以:

  • 报告由udevdudevadm monitor --udev --property )处理后的设备事件,
  • 直接从内核报告事件( udevadm monitor --kernel --property )和
  • dump udevd当前设备的数据库(但不是内核的!)( udevadm info --query all --export-db

udevadm是udev软件包的一部分,但是如果仅用它来报告内核事件,则不需要udevd 。 你可以通过让你的进程生成并解析它的标准输出来使用它(但是你必须通过stdbuf -o L启动它)。

无论哪种方式,这可能会是很多工作。 我已经在我的NCD编程语言中实现了很多,包括USB设备的监控。 你可能想看看NCD; 它对于很多配置任务很有用,并能很好地处理hotplugging。 例如,这个NCD程序将把USB设备事件打印到标准输出:

 process main { sys.watch_usb() watcher; println(watcher.event_type, " ", watcher.devname, " ", watcher.vendor_id, ":", watcher.model_id); watcher->nextevent(); } 

这将使NCD打印出类似的内容(对于已经插入的任何USB设备,最初added事件):

 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运行; 但为什么这是一个问题呢? (有些工作可以去除这个依赖关系)

您可以使用libudev或解析udevadm输出作为@Ambroz Bizjak建议。 虽然,我建议不要添加额外的进程( stdbuf )和语言( NCD ),只是为了解析udevadm的输出。

普通libudev和解析输出之间的一个步骤是修改udevadm源代码。 该解决方案减少了所需的资源,并完全跳过了解析过程。 查看udev软件包时,可以在udev目录中找到udevd和udevadm的源代码。

在那里,您有udevadm.c的主例程和udevadm-monitor.c udevadm monitor的源代码。 收到的每个事件都将通过print_device()打印。 这是你插入你的代码的地方。

如果你的内存很紧张,你可以去掉不需要的代码来controlinfosettletest-builtin testtesttrigger 。 在我的系统上(Ubuntu 12.04),这使udevadm的大小减少了大约75%。

不幸的是,在连接/断开连接上没有产生udev事件,所以几乎不可能监视这些事件。
你可以监视内核消息(这似乎是疯狂的想法)。 可能更好的方法是修改内核。

更新:我不明白为什么这个答案得到负面评价。
也许有些人将USB主机部分(在设备插入/拔出时产生UDEV事件)和USB设备/小工具部分(不会产生这种事件)
所以,如果你的linux电脑作为一个小工具(USB设备连接到一些USB主机),没有好的方法来捕捉插拔事件。

证明: Greg Kroah-Hartman的消息