我们可以使用libusb_device对象,在不使用libusb_open打开USB设备的情况下获取USB设备的基本信息。其中包括USB Descriptor、USB Configuration、USB Bus ID、USB Device ID和USB Port ID,USB连接速度等。
1. 获取USB Bus ID
函数定义如下:
uint8_t libusb_get_bus_number (libusb_device *dev)
dev:为通过libusb_get_device_list或者libusb_hotplug_callback_fn获取的libusb_device对象,后续不再赘述
返回值:为 bus id
2. 获取USB Device ID
函数定义如下:
uint8_t libusb_get_device_address (libusb_device *dev)
返回值:为device id
3. 获取USB Port ID
函数定义如下:
int libusb_get_port_numbers (
libusb_device *dev,
uint8_t *port_numbers,
int port_numbers_len)
port_numbers:为待返回的port层级ID组成的数组
port_numbers_len:为port_numbers数组长度,当前USB3.0支持最大长度为7
返回值:为填入的ID个数(层级数)。如果传入的port_numbers数组过小,会返回LIBUSB_ERROR_OVERFLOW错误
4. 获取USB连接速度
函数定义如下:
int libusb_get_device_speed (libusb_device *dev)
返回libusb_speed表示的速度值,LIBUSB_SPEED_UNKNOWN表示系统无法侦测连接速度
5. 获取USB Descriptor信息
USB Descriptor信息中包括此设备的PID和VID,Device Class、USB协议版本以及最重要的Configuration数量
函数定义如下:
int libusb_get_device_descriptor (
libusb_device *dev,
struct libusb_device_descriptor *desc)
desc:为获取的Device Descriptor信息
返回值:为LIBUSB_SUCESS表示成功,否则返回LIBUSB_ERROR code
其中:
desc->bcdUSB:表示USB版本,0x0110表示USB 1.1,0x0200表示USB 2.0等
desc->bDeviceClass:表示Device Class,由libusb_class_code定义
desc->idVendor:表示Device的VID
desc->idProduct:表示Device的PID
desc->bNumConfigurations:表示Device的Configuration数量
其它的内容,比如:desc->iManufacturer, desc->iProduct和desc->iSerialNumber,分别是厂商名称、产品名称和序列号的description字符串序号。如果不为0,则可以进一步通过libusb_get_string_descriptor_ascii函数获取实际的字符串。
libusb_get_string_descriptor_ascii函数定义如下:
int libusb_get_string_descriptor_ascii (
libusb_device_handle *dev_handle,
uint8_t desc_index,
unsigned char *data,
int length)
其中:
dev_handle:为USB Device的句柄,所以此接口需要打开USB设备
desc_index: 就是description字符串序号,即iManufacturer, iProduct,iSerialNumber等
data:为待返回字符串的char数组指针
length:为data数组的长度
返回值:为填入的字符个数
6. 获取USB Configuration信息
libusb或者说Linux的USB架构中,USB设备一般包含一个或多个USB Configuration。一个USB Configuration对应一个特定配置。每个配置中同样包含一个或多个接口(Interface),每个接口对应USB设备的一种功能,比如:视频、音频、HID等。最后每个接口可以包含一个或多个端口(Endpoint), USB的传输就是通过这些端口进行的。详细说明可以参考https://blog.youkuaiyun.com/tilblackout/article/details/134046115
获取USB Configuration信息的函数定义如下:
int libusb_get_config_descriptor (
libusb_device *dev,
uint8_t config_index,
struct libusb_config_descriptor **config)
config_index:为configuration的序号,范围为0 - bNumConfiguration-1(bNumConfiguration由libusb_get_device_descriptor 获得)
config:为返回的configuration信息对象
返回值:为LIBUSB_SUCCESS表示成功,LIBUSB_ERROR_NOT_FOUND表示此configuration未找到,还有其它LIBUSB_ERROR code
获取的libusb_config_descriptor信息对象必须通过libusb_free_config_descriptor进行free。
函数libusb_free_config_descriptor的定义如下:
void libusb_free_config_descriptor (struct libusb_config_descriptor *config)
获取的libusb_config_descriptor 对象中有用的信息为:
config->MaxPower:表示此设备需消耗的最大电量,对于HighSpeed设备(可通过libusb_get_device_speed获知),值为2mA的倍数;对于Super Speed设备,值为8 mA的倍数
config->bNumInterfaces: 表示此Configuration中包含的Interface数量
config->interface: 为配置中接口对象libusb_interface的数组,长度由bNumInterfaces决定。
config->interface数组中主要是libusb_interface对象,libusb_interface接口对象只包含了其可配置项对象libusb_interface_descriptor的信息,主要有:
interface->num_altsetting: 表示可配置项个数
interface->altsetting: 可配置项对象数组,其长度由num_altsetting决定
接口(Interface)信息的主要内容就存储在可配置信息libusb_interface_descriptor中,主要包括:
altsetting->bInterfaceNumber:表示此Interface的序号
altsetting->bAlternateSetting: 表示此Interface可配置项的序号
altsetting->bNumEndpoints: 表示此Interface包含端口(Endpoint)的个数
altsetting->endpoint: 表示Interface中端口对象libusb_endpoint_descriptor的数组,长度由bNumEndpoints决定
端口(Endpoint)信息的主要内容存储在端口对象libusb_endpoint_descriptor中,主要包括:
endpoint->bEndpointAddress:表示访问此端口的地址,后续读写操作需要用到,最高位决定此端口是"读"还是"写"端口
endpoint->bmAttributes:表示此端口的属性。
Bits 0:1表示传输类型(控制(Control)、同步(Isochronous)、块(Bulk)、中断(Interrupt));
Bit 2:3表示同步传输类型(无、异步、自适应、同步)
Bit 4:5表示同步传输用途(数据(Data)、反馈(Feedback)、隐式反馈(Implict Feedback))
endpoint->wMaxPacketSize:表示端口一次传输的最大Size
endpoint->bInterval:表示端口传输的间隔时间
关于endpoint定义的详细内容,可参考https://blog.youkuaiyun.com/u013256018/article/details/62087333
遍历Configuration信息的例程如下:
static void print_endpoint(const struct libusb_endpoint_descriptor *endpoint)
{
printf(" Endpoint:\n");
printf(" bEndpointAddress: %02xh\n", endpoint->bEndpointAddress);
printf(" bmAttributes: %02xh\n", endpoint->bmAttributes);
printf(" wMaxPacketSize: %u\n", endpoint->wMaxPacketSize);
printf(" bInterval: %u\n", endpoint->bInterval);
printf(" bRefresh: %u\n", endpoint->bRefresh);
printf(" bSynchAddress: %u\n", endpoint->bSynchAddress);
}
static void print_altsetting(const struct libusb_interface_descriptor *interface)
{
uint8_t i;
printf(" Interface:\n");
printf(" bInterfaceNumber: %u\n", interface->bInterfaceNumber);
printf(" bAlternateSetting: %u\n", interface->bAlternateSetting);
printf(" bNumEndpoints: %u\n", interface->bNumEndpoints);
printf(" bInterfaceClass: %u\n", interface->bInterfaceClass);
printf(" bInterfaceSubClass: %u\n", interface->bInterfaceSubClass);
printf(" bInterfaceProtocol: %u\n", interface->bInterfaceProtocol);
printf(" iInterface: %u\n", interface->iInterface);
for (i = 0; i < interface->bNumEndpoints; i++)
print_endpoint(&interface->endpoint[i]);
}
static void print_interface(const struct libusb_interface *interface)
{
int i;
for (i = 0; i < interface->num_altsetting; i++)
print_altsetting(&interface->altsetting[i]);
}
static void print_configuration(struct libusb_config_descriptor *config)
{
uint8_t i;
printf(" Configuration:\n");
printf(" wTotalLength: %u\n", config->wTotalLength);
printf(" bNumInterfaces: %u\n", config->bNumInterfaces);
printf(" bConfigurationValue: %u\n", config->bConfigurationValue);
printf(" iConfiguration: %u\n", config->iConfiguration);
printf(" bmAttributes: %02xh\n", config->bmAttributes);
printf(" MaxPower: %u\n", config->MaxPower);
for (i = 0; i < config->bNumInterfaces; i++)
print_interface(&config->interface[i]);
}
libusb获取USB设备基本信息详解
5857

被折叠的 条评论
为什么被折叠?



