Linux 如何使用 libudev 获取 USB 设备 VID 及 PID
这篇文章主要介绍了 Linux 如何使用 libudev 获取 USB 设备 VID 及 PID,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
在本文将使用 libudev 库来访问 hidraw 的设备。通过 libudev 库,我们可以查询设备的厂家 ID(Vendor ID, VID),产品 ID(Product ID, PID),序列号和设备字符串等而不需要打开设备。进一步,libudev 可以告诉我们在/dev 目录下设备节点的具体位置路径,为应用程序提供一种具有足够鲁棒性而又和系统厂家独立的访问设备的方式。使用 libudev 库,需要包含 libudev.h 头文件,并且在编译时加上-ludev 告诉编译器去链接 udev 库。
libudev 将返回所有匹配这个过滤字符串的 udev_device 对象。
这个列子的步骤如下:
1、 初始化库,获取一个 struct udev 句柄
2、枚举设备
3、对找到的匹配设备输出它的节点名称,找到实际 USB 设备的起始节点,打印出 USB 设备的 IDs 和序列号等,最后解引用设备对象
4、解引用枚举对象
5、解引用 udev 对象
具体代码如下:
#include <libudev.h>
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <unistd.h>
int main (void)
{
struct udev *udev;
struct udev_enumerate *enumerate;
struct udev_list_entry *devices, *dev_list_entry;
struct udev_device *dev;
/* Create the udev object */
udev = udev_new();
if
(!udev) {
printf
(
"Can't create udev\n"
);
exit
(1);
}
/* Create a list of the devices
in
the
'hidraw'
subsystem. */
enumerate = udev_enumerate_new(udev);
udev_enumerate_add_match_subsystem(enumerate,
"hidraw"
);
udev_enumerate_scan_devices(enumerate);
devices = udev_enumerate_get_list_entry(enumerate);
/* For each item enumerated, print out its information.
udev_list_entry_foreach is a macro
which
expands to
a loop. The loop will be executed
for
each member
in
devices, setting dev_list_entry to a list entry
which
contains the device's path
in
/sys
. */
udev_list_entry_foreach(dev_list_entry, devices) {
const char *path;
/* Get the filename of the
/sys
entry
for
the device
and create a udev_device object (dev) representing it */
path = udev_list_entry_get_name(dev_list_entry);
dev = udev_device_new_from_syspath(udev, path);
/* usb_device_get_devnode() returns the path to the device node
itself
in
/dev
. */
printf
(
"Device Node Path: %s\n"
, udev_device_get_devnode(dev));
/* The device pointed to by dev contains information about
the hidraw device. In order to get information about the
USB device, get the parent device with the
subsystem
/devtype
pair of
"usb"
/
"usb_device"
. This will
be several levels up the tree, but the
function
will
find
it.*/
dev = udev_device_get_parent_with_subsystem_devtype(
dev,
"usb"
,
"usb_device"
);
if
(!dev) {
printf
(
"Unable to find parent usb device."
);
exit
(1);
}
/* From here, we can call get_sysattr_value()
for
each
file
in
the device's
/sys
entry. The strings passed into these
functions (idProduct, idVendor, serial, etc.) correspond
directly to the files
in
the directory
which
represents
the USB device. Note that USB strings are Unicode, UCS2
encoded, but the strings returned from
udev_device_get_sysattr_value() are UTF-8 encoded. */
printf
(
" VID/PID: %s %s\n"
,
udev_device_get_sysattr_value(dev,
"idVendor"
),
udev_device_get_sysattr_value(dev,
"idProduct"
));
printf
(
" %s\n %s\n"
,
udev_device_get_sysattr_value(dev,
"manufacturer"
),
udev_device_get_sysattr_value(dev,
"product"
));
printf
(
" serial: %s\n"
,
udev_device_get_sysattr_value(dev,
"serial"
));
udev_device_unref(dev);
}
/* Free the enumerator object */
udev_enumerate_unref(enumerate);
udev_unref(udev);
return
0;
}
编译程序:
gcc -Wall -g -o udev_example udev_example.c -ludev
以上就是本文的全部内容,希望对大家的学习有所帮助
技术参考:http://www.cncsto.com/article/102
版权声明: 本文为 InfoQ 作者【夜猫西街】的原创文章。
原文链接:【http://xie.infoq.cn/article/04adf4dc7fd28b78236fbd4bb】。
本文遵守【CC BY-NC-SA】协议,转载请保留原文出处及本版权声明。
评论