linux usb连接/断开事件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7115731/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
linux usb connect/disconnect event
提问by eat_a_lemon
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. There is no dbus daemon or hotplug helper script. I am not even sure if these would of been helpful.
嵌入式 linux 操作系统没有任何附加功能。没有 dbus 守护程序或热插拔帮助程序脚本。我什至不确定这些是否会有所帮助。
采纳答案by Ambroz Bizjak
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.
如果您希望在单个进程中包含所有内容,则必须使用 libudevudevd
从内核获取事件或直接从内核获取事件。
Seeing that it might be a problem to use libudev in your application (lack of documentation?), an alternative is to use the udevadmprogram, which can:
看到在您的应用程序中使用 libudev 可能有问题(缺乏文档?),另一种方法是使用udevadm程序,它可以:
- report device events after being processed by
udevd
(udevadm monitor --udev --property
), - report devive events directly from the kernel (
udevadm monitor --kernel --property
), and - dump udevd's database of current devices (but not the kernel's!) (
udevadm info --query all --export-db
)
- 由
udevd
(udevadm monitor --udev --property
)处理后上报设备事件, - 直接从内核报告 devive 事件 (
udevadm monitor --kernel --property
),以及 - 转储 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. 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
).
udevadm
是 udev 包的一部分,但udevd
如果您仅使用它来报告内核事件,则不需要。您可以通过让您的进程生成它并解析其标准输出来使用它(但您必须通过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. You might want to take a look at 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 设备的监控。你可能想看看 NCD;它对许多配置任务很有用,并且可以很好地处理热插拔。例如,这个 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 打印出类似的内容(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
You can also use NCD just for this, and parse thisstandard output - which is much easier to work with than messing with udevadm directly.
您也可以为此使用 NCD,并解析此标准输出 - 这比直接使用 udevadm 更容易使用。
Note that NCD itself uses udevadm
, and it doesrequire udevd to be running; but why is that a problem anyway? (with some work this dependency could be removed)
请注意,NCD 本身使用udevadm
,并且它确实需要运行 udevd;但为什么这是一个问题呢?(通过一些工作,可以删除此依赖项)
回答by Olaf Dietsche
You can use libudev
or parse udevadm
output as @Ambroz Bizjak suggested. Although, I advise against adding an additional process (stdbuf
) and language (NCD
), just to parse udevadm's output.
您可以按照@Ambroz Bizjak 的建议使用libudev
或解析udevadm
输出。虽然,我建议不要添加额外的进程 ( stdbuf
) 和语言 ( NCD
),只是为了解析 udevadm 的输出。
A step between plain libudev and parsing output is modifying the udevadm sources. 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.
普通 libudev 和解析输出之间的一个步骤是修改 udevadm 源。该解决方案减少了所需的资源并完全跳过了解析过程。当您查看 udev 包时,您会在udev
目录中找到 udevd 和 udevadm 的源代码。
There, you have the main routine in udevadm.c
and the source for udevadm monitor
in udevadm-monitor.c
. Every event received will be printed through print_device()
. This is where you insert your code.
在那里,你必须在主程序udevadm.c
和源udevadm monitor
中udevadm-monitor.c
。收到的每个事件都将通过print_device()
. 这是您插入代码的地方。
If you're tight on memory, you can strip off unneeded code for control
, info
, settle
, test-builtin
, test
and trigger
. On my system (Ubuntu 12.04), this reduces the size of udevadm by about 75%.
如果你的内存是紧的,你可以脱掉了不必要的代码control
,info
,settle
,test-builtin
,test
和trigger
。在我的系统 (Ubuntu 12.04) 上,这将 udevadm 的大小减少了大约 75%。
回答by edo1
Unfortunately, there is no udev event produced on connect/disconnect on gadget side, so it is almost to impossible to monitor these events.
You could monitor kernel messages (dmesg). It seems to be stupid idea. Or watch some files in sysfs. Possible better way is kernel patching.
不幸的是,在小工具端的连接/断开连接上没有产生 udev 事件,因此几乎不可能监视这些事件。
您可以监视内核消息 (dmesg)。这似乎是个愚蠢的想法。或者查看 sysfs 中的一些文件。可能更好的方法是内核补丁。
update:I do not understand why this answer got negative rating.
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)
If your linux computer works as a gadget (USB device which is connected to some USB host) there is no good way to catch plug/unplug events.
更新:我不明白为什么这个答案得到负面评价。
也许有些人将 USB 主机部分(在设备插入/拔出时产生 UDEV 事件)和 USB 设备/小工具部分(不产生此类事件)混合使用
如果您的 linux 计算机用作小工具(连接到某些 USB 的 USB 设备)主机)没有捕获插入/拔出事件的好方法。
Proof: message by Greg Kroah-Hartman
another copy if previous link is down