Linux的/dev/xxx设备节点是自动创建。一般情况下,开发者只能拿到设备号等少数信息。而像一些USB设备,即便是同一个设备,插拔以后可能,生成的/dev/xxx节点名可能也不相同。所以应用编程有时候需要知道,设备节点的具体信息。比如是哪个厂家的USB设备,USB设备的PID和VID是多少,插在了hub的哪个端口上等等.这时候就需要使用libudev获取设备节点的详细信息。

通过libudev获取的USB信息,比较常用的就是PID和VID,

ID_VENDOR_ID 对应的就是USB设备的VID

ID_MODEL_ID 对应的就是USB设备的PID

#include <libudev.h>
#include <stdio.h>
#include <string.h>

/*
 * libudev api说明
 * https://mirrors.edge.kernel.org/pub/linux/utils/kernel/hotplug/libudev/ch01.html
 */


/**
 * 打印/dev/xxx设备节点的properties值
 * @devnode: 设备节点文件/dev/xxx,如:/dev/ttyUSB0
 */
int print_devnode_properties(const char *devnode)
{
	int ret = 0;
	struct udev *udev;
	struct udev_device *device;
	struct udev_enumerate *enumerate;
	struct udev_list_entry *first_entry;
	struct udev_list_entry *list_entry;
	const char *syspath;

	udev = udev_new();
	enumerate = udev_enumerate_new(udev);

	/*
	 * 通过枚举器添加匹配条件,如果有多条匹配条件
	 */
	udev_enumerate_add_match_property(enumerate, "DEVNAME", devnode);

	/*
	 * 根据枚举器设置的条件扫描所有的设备.
	 * 注意: 如果有多条匹配条件,符合其中一条就会被扫描到,
	 *       匹配条件越多,扫描越宽松
	 */
	udev_enumerate_scan_devices(enumerate);

	list_entry = udev_enumerate_get_list_entry(enumerate);

	if (!list_entry) {
		ret = -1;
		goto ERROR1;
	}

	syspath = udev_list_entry_get_name(list_entry);
	device = udev_device_new_from_syspath(udev, syspath);

	if (!device) {
		ret = -1;
		goto ERROR1;
	} 

	first_entry = udev_device_get_properties_list_entry(device);

	if (!first_entry) {
		ret = -1;
		goto ERROR2;
	}

	udev_list_entry_foreach(list_entry, first_entry) {
		printf("%s = %s\n", udev_list_entry_get_name(list_entry), udev_list_entry_get_value(list_entry));
	}

ERROR2:	
	udev_device_unref(device);
ERROR1:
	udev_enumerate_unref(enumerate);
	udev_unref(udev);
	return ret;
}


void test_print_devnode_properties(void)
{
	print_devnode_properties("/dev/ttyUSB0");
	print_devnode_properties("/dev/sda1");
	/*
	 * 异常情况测试
	 */
	print_devnode_properties("/dev/");
}

/dev/ttyUSB0的打印信息:

DEVLINKS = /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0 /dev/serial/by-path/platform-13500000.otg-usb-0:1.1:1.0-port0
DEVNAME = /dev/ttyUSB0
DEVPATH = /devices/platform/ahb2/13500000.otg/usb1/1-1/1-1.1/1-1.1:1.0/ttyUSB0/tty/ttyUSB0
ID_BUS = usb
ID_MODEL = USB_Serial
ID_MODEL_ENC = USB\x20Serial
ID_MODEL_FROM_DATABASE = HL-340 USB-Serial adapter
ID_MODEL_ID = 7523
ID_PATH = platform-13500000.otg-usb-0:1.1:1.0
ID_PATH_TAG = platform-13500000_otg-usb-0_1_1_1_0
ID_REVISION = 0264
ID_SERIAL = 1a86_USB_Serial
ID_TYPE = generic
ID_USB_CLASS_FROM_DATABASE = Vendor Specific Class
ID_USB_DRIVER = ch341
ID_USB_INTERFACES = :ff0102:
ID_USB_INTERFACE_NUM = 00
ID_VENDOR = 1a86
ID_VENDOR_ENC = 1a86
ID_VENDOR_FROM_DATABASE = QinHeng Electronics
ID_VENDOR_ID = 1a86
MAJOR = 188
MINOR = 0
SUBSYSTEM = tty
USEC_INITIALIZED = 4234570131

/dev/sda1的打印信息:

DEVLINKS = /dev/disk/by-id/usb-Mass_Storage_Device_121220160204-0:0-part1 /dev/disk/by-label/HHP /dev/disk/by-partuuid/e7c35f5b-01 /dev/disk/by-path/platform-13500000.otg-usb-0:1.2:1.0-scsi-0:0:0:0-part1 /dev/disk/by-uuid/AECB-FA14
DEVNAME = /dev/sda1
DEVPATH = /devices/platform/ahb2/13500000.otg/usb1/1-1/1-1.2/1-1.2:1.0/host7/target7:0:0/7:0:0:0/block/sda/sda1
DEVTYPE = partition
ID_BUS = usb
ID_FS_LABEL = HHP
ID_FS_LABEL_ENC = HHP
ID_FS_TYPE = vfat
ID_FS_USAGE = filesystem
ID_FS_UUID = AECB-FA14
ID_FS_UUID_ENC = AECB-FA14
ID_FS_VERSION = FAT32
ID_INSTANCE = 0:0
ID_MODEL = Storage_Device
ID_MODEL_ENC = Storage\x20Device\x20\x20
ID_MODEL_ID = 1212
ID_PART_ENTRY_DISK = 8:0
ID_PART_ENTRY_NUMBER = 1
ID_PART_ENTRY_OFFSET = 2048
ID_PART_ENTRY_SCHEME = dos
ID_PART_ENTRY_SIZE = 30879744
ID_PART_ENTRY_TYPE = 0xc
ID_PART_ENTRY_UUID = e7c35f5b-01
ID_PART_TABLE_TYPE = dos
ID_PART_TABLE_UUID = e7c35f5b
ID_PATH = platform-13500000.otg-usb-0:1.2:1.0-scsi-0:0:0:0
ID_PATH_TAG = platform-13500000_otg-usb-0_1_2_1_0-scsi-0_0_0_0
ID_REVISION = 1.00
ID_SERIAL = Mass_Storage_Device_121220160204-0:0
ID_SERIAL_SHORT = 121220160204
ID_TYPE = disk
ID_USB_DRIVER = usb-storage
ID_USB_INTERFACES = :080650:
ID_USB_INTERFACE_NUM = 00
ID_VENDOR = Mass
ID_VENDOR_ENC = Mass\x20\x20\x20\x20
ID_VENDOR_ID = 14cd
MAJOR = 8
MINOR = 1
SUBSYSTEM = block
USEC_INITIALIZED = 4238784457

 

Logo

更多推荐