简体   繁体   English

linux usb连接/断开事件

[英]linux usb connect/disconnect event

Hello I am working on an embedded linux device with a usb port that uses the g_ether driver for usb networking.您好,我正在开发带有 USB 端口的嵌入式 Linux 设备,该设备使用 g_ether 驱动程序进行 USB 网络连接。

When the usb plug is connected the dmesg output is:连接 USB 插头后,dmesg 输出为:

g_ether gadget: full speed config #2: RNDIS g_ether 小工具:全速配置 #2:RNDIS

When the usb cable is unplugged no message is written to dmesg.拔下 USB 电缆时,不会向 dmesg 写入任何消息。

Using C how can I listen for the connect/disconnect events?使用 C 如何监听连接/断开事件?

The embedded linux OS does not have any extras.嵌入式 linux 操作系统没有任何附加功能。 There is no dbus daemon or hotplug helper script.没有 dbus 守护程序或热插拔帮助程序脚本。 I am not even sure if these would of been helpful.我什至不确定这些是否会有所帮助。

If you want everything in your single process, you'll have to use libudev to either get events from udevd or directly from the kernel.如果您希望在单个进程中包含所有内容,则必须使用 libudev 从udevd或直接从内核获取事件。

Seeing that it might be a problem to use libudev in your application (lack of documentation?), an alternative is to use the udevadm program, which can:看到在您的应用程序中使用 libudev 可能有问题(缺乏文档?),另一种方法是使用udevadm程序,它可以:

  • report device events after being processed by udevd ( udevadm monitor --udev --property ), udevd处理后报告设备事件( udevadm monitor --udev --property ),
  • report devive events directly from the kernel ( udevadm monitor --kernel --property ), and直接从内核报告 devive 事件( udevadm monitor --kernel --property ),以及
  • dump udevd's database of current devices (but not the kernel's!) ( udevadm info --query all --export-db )转储 udevd 的当前设备数据库(但不是内核的!)( udevadm info --query all --export-db

udevadm is part of the udev package, but shouldn't need udevd if you only use it to report kernel events. udevadm是 udev 包的一部分,但如果您只使用它来报告内核事件,则不需要udevd You can use it by having your process spawn it and parse its standard output (but you'll have to launch it via stdbuf -o L ).您可以通过让您的进程生成它并解析其标准输出来使用它(但您必须通过stdbuf -o L启动它)。

Either way, it'll probably be a lot of work.无论哪种方式,都可能需要大量工作。 I've already implemented a lot of this in my NCD programming language , including monitoring of USB devices.我已经在我的NCD 编程语言中实现了很多这样的功能,包括对 USB 设备的监控。 You might want to take a look at NCD;你可能想看看 NCD; it's useful for a lot of configuration tasks, and handles hotplugging well.它对许多配置任务很有用,并且可以很好地处理热插拔。 For example, this NCD program will print USB device events to standard output:例如,这个 NCD 程序会将 USB 设备事件打印到标准输出:

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

This will make NCD print something like that (with an initial added event for any USB device that was already plugged in):这将使 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

You can also use NCD just for this, and parse this standard output - which is much easier to work with than messing with udevadm directly.您也可以为此使用 NCD,并解析标准输出 - 这比直接使用 udevadm 更容易使用。

Note that NCD itself uses udevadm , and it does require udevd to be running;请注意,NCD 本身使用udevadm ,它确实需要 udevd 运行; but why is that a problem anyway?但为什么这是一个问题呢? (with some work this dependency could be removed) (通过一些工作,可以删除此依赖项)

You can use libudev or parse udevadm output as @Ambroz Bizjak suggested.您可以按照@Ambroz Bizjak 的建议使用libudev或解析udevadm输出。 Although, I advise against adding an additional process ( stdbuf ) and language ( NCD ), just to parse udevadm's output.虽然,我建议不要添加额外的进程 ( stdbuf ) 和语言 ( NCD ),只是为了解析 udevadm 的输出。

A step between plain libudev and parsing output is modifying the udevadm sources.普通 libudev 和解析输出之间的一个步骤是修改 udevadm 源。 This solution reduces the needed resources and skips the parsing process altogether.该解决方案减少了所需的资源并完全跳过了解析过程。 When you look at the udev package, you will find the sources for udevd and udevadm in the udev directory.当您查看 udev 包时,您会在udev目录中找到 udevd 和 udevadm 的源代码。

There, you have the main routine in udevadm.c and the source for udevadm monitor in udevadm-monitor.c .在那里,您在udevadm.c有主要例程,在udevadm-monitor.c udevadm monitor的源代码。 Every event received will be printed through print_device() .收到的每个事件都将通过print_device()打印。 This is where you insert your code.这是您插入代码的地方。

If you're tight on memory, you can strip off unneeded code for control , info , settle , test-builtin , test and trigger .如果您的内存紧张,您可以去除controlinfosettletest-builtintesttrigger不需要的代码。 On my system (Ubuntu 12.04), this reduces the size of udevadm by about 75%.在我的系统 (Ubuntu 12.04) 上,这将 udevadm 的大小减少了大约 75%。

Unfortunately, there is no udev event produced on connect/disconnect on gadget side, so it is almost impossible to monitor these events.不幸的是,在小工具端的连接/断开连接上没有产生 udev 事件,因此几乎不可能监视这些事件。
You could monitor kernel messages (dmesg).您可以监视内核消息 (dmesg)。 It seems to be a stupid idea.这似乎是一个愚蠢的想法。 Or watch some files in sysfs.或者查看 sysfs 中的一些文件。 Maybe the better way is kernel patching.也许更好的方法是内核补丁。

update: I do not understand why this answer have got many negative votes.更新:我不明白为什么这个答案得到了很多反对票。
Maybe some people mix USB host part (which produces UDEV events on device plug/unplug) and USB device/gadget part (which doesn't produce such events)也许有些人将 USB 主机部分(在设备插入/拔出时产生 UDEV 事件)和 USB 设备/小工具部分(不产生此类事件)混合使用
If your linux host works as a gadget (USB device which is connected to some USB host) there is no good way to catch plug/unplug events.如果您的 linux 主机用作小工具(连接到某个 USB 主机的 USB 设备),则没有捕获插入/拔出事件的好方法。

Proof: message by Greg Kroah-Hartman证明: Greg Kroah-Hartman 的消息
another copy if previous link is down 如果上一个链接已关闭,则再复制一份

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM