【问题标题】:linux usb connect/disconnect eventlinux usb连接/断开事件
【发布时间】:2011-10-30 06:03:56
【问题描述】:

您好,我正在开发一个带有 USB 端口的嵌入式 linux 设备,该设备使用 g_ether 驱动程序进行 USB 网络连接。

连接usb插头后dmesg输出为:

g_ether 小工具:全速配置 #2:RNDIS

拔下 USB 电缆后,不会向 dmesg 写入任何消息。

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

嵌入式 linux 操作系统没有任何额外功能。没有 dbus 守护程序或 hotplug 帮助程序脚本。我什至不确定这些是否会有所帮助。

【问题讨论】:

  • 不幸的是我没有。没有udev就无法在用户态监听这种类型的事件吗?
  • 我相信这是获取内核事件的最佳方式。另一种选择是 linux-hotplug 中的旧 USB。

标签: c linux networking usb driver


【解决方案1】:

如果您想在单个进程中处理所有内容,则必须使用 libudev 从 udevd 或直接从内核获取事件。

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

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

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

不管怎样,这可能需要大量的工作。我已经在我的NCD programming language 中实现了很多这样的功能,包括监控 USB 设备。您可能想看看 NCD;它对许多配置任务很有用,并且可以很好地处理热插拔。例如,这个 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,并解析 this 标准输出 - 这比直接使用 udevadm 更容易使用。

请注意,NCD 本身使用udevadm,并且它确实需要运行 udevd;但为什么这是一个问题呢? (通过一些工作可以删除这种依赖关系)

【讨论】:

    【解决方案2】:

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

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

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

    如果您的内存不足,您可以删除 controlinfosettletest-builtintesttrigger 的不需要的代码。在我的系统(Ubuntu 12.04)上,这将 udevadm 的大小减少了大约 75%。

    【讨论】:

      【解决方案3】:

      不幸的是,在小工具端的连接/断开连接时没有产生 udev 事件,因此几乎不可能监控这些事件。
      您可以监视内核消息 (dmesg)。这似乎是一个愚蠢的想法。或者查看 sysfs 中的一些文件。也许更好的方法是内核补丁。

      更新:我不明白为什么这个答案有很多反对票。
      也许有些人混合了 USB 主机部分(在设备插入/拔出时产生 UDEV 事件)和 USB 设备/小工具部分(不产生此类事件)
      如果您的 linux 主机作为小工具(连接到某个 USB 主机的 USB 设备)工作,则没有很好的方法来捕获插入/拔出事件。

      证明:message by Greg Kroah-Hartman
      another copy if previous link is down

      【讨论】:

      • 来源?你能解释一下你的理由以及从哪里开始实施吗?
      • 我编辑了我的答案以获得更详细的解释。如果您决定查看内核消息,您可以查看如何在 dmesg 源中执行 /proc/kmsg,或者您可以使用一些 syslog 守护程序 PLUS 日志文件监控程序,如 swatch。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-17
      • 1970-01-01
      • 2013-08-01
      • 2021-10-14
      相关资源
      最近更新 更多