目录:
回顾
步骤 一 :实现USB驱动框架
步骤二:添加描述符-打印设备描述符即Device描述符
步骤三:添加描述符-打印配置描述符即Configuration描述符
步骤四:添加描述符-打印接口联合描述符即IAD/IF描述符
步骤五 :添加描述符-打印接口描述符
步骤六 :添加描述符-打印UVC设备自定义描述符
描述符
回顾USB设备驱动内容,一个USB设备,包含如下一系列描述符
USB设备标准描述符
设备描述符
配置描述符1
接口描述符1 //指逻辑上的设备,如USB声卡可以分为录音和播放两个逻辑设备
端点描述符1 //代表数据通道
...
端点描述符n
接口描述符n
配置描述符n
接口描述符1
端点描述符1
...
端点描述符n
接口描述符n
小结:
访问设备时:访问某个接口—接口表示逻辑设备
传输数据时:读写某个端点—端点是数据通道
而我们 UVC设备描述符如下:
上图中的白色部分就是USB设备的标准描述符,而灰色部分则是UVC设备自己定义的描述符。
本文即分析上述这些UVC描述符,依次分析打印上述的
Device描述符
Configuration描述符
IAD/IF描述符
VideoControl描述符
本章代码将分析 USB摄像头驱动的描述符,根据这些描述符,我们可以知道这一款USB摄像头可以支持哪几种格式的视频数据,某一种格式下它又支持哪几种分辨率,还有该摄像头是否支持设置某些属性,如 是否可以调整亮度等等。
结构体之间的关系:
步骤 一 :实现USB驱动框架
1 分配并简单设置 struct usb_driver myuvc_driver
1.1 简单实现 .probe /.disconnect
1.2 填充 id_table
说明:将 id_table 填充为 "Generic USB Video Class" 即通用USB Video类
2 注册 myuvc_driver :usb_register(&myuvc_driver);
该驱动 prob()会被调用两次,因为 id_table 中填充了两个设备
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/videodev2.h>
#include <linux/vmalloc.h>
#include <linux/wait.h>
#include <asm/atomic.h>
#include <asm/unaligned.h>
#include <media/v4l2-common.h>
static int myuvc_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
static int cnt = 0;
printk("myuvc_probe : cnt = %d\n", cnt++);
return 0;
}
static void myuvc_disconnect(struct usb_interface *intf)
{
static int cnt = 0;
printk("myuvc_disconnect : cnt = %d\n", cnt++);
}
/*
#define USB_INTERFACE_INFO(cl, sc, pr) \
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO, \
.bInterfaceClass = (cl), \
.bInterfaceSubClass = (sc), \
.bInterfaceProtocol = (pr)
即 bInterfaceClass = USB_CLASS_VIDEO
bInterfaceSubClass = 1 ---> 代表 VideoControl Interface
2 ---> 代表 VideoStreaming Interface
bInterfaceProtocol = 0 ---> 代表
*/
static struct usb_device_id myuvc_ids[] = {
/* Generic USB Video Class */
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, /* VideoControl Interface */
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 2, 0) }, /* VideoStreaming Interface 属于 VideoControl Interface 可以不写*/
{}
};
/* 1. 分配usb_driver */
/* 2. 设置 */
static struct usb_driver myuvc_driver = {
.name = "myuvc",
.probe = myuvc_probe,
.disconnect = myuvc_disconnect,
.id_table = myuvc_ids,
};
static int myuvc_init(void)
{
/* 3. 注册 */
usb_register(&myuvc_driver);
return 0;
}
static void myuvc_exit(void)
{
usb_deregister(&myuvc_driver);
}
module_init(myuvc_init);
module_exit(myuvc_exit);
MODULE_LICENSE("GPL");
步骤二:添加描述符-打印设备描述符即Device描述符
lsusb -v -d 设备厂家ID:
会打印出usb摄像头的一系列设备描述符。通过这些描述符,可以更新清晰的了解USB设备
通过查看 lsusb.c: main()中的实现,分别打印了 设备描述符、配置描述符、接口描述符、端点描述符。
lsusb.c:
main
dumpdev
dump_device //打印设备描述符
dump_config //打印配置描述符
for (i = 0 ; i < config->bNumInterfaces ; i++)
dump_interface(dev, &config->interface[i]); //打印接口描述符
for (i = 0; i < interface->num_altsetting; i++)
dump_altsetting(dev, &interface->altsetting[i]); //打印设置
1 添加设备描述符
1.1 获得USB设备结构体 struct usb_device
1.2 获得USB设备描述符结构体 struct usb_device_descriptor,并关联到 USB设备结构体usb_device
1.3 打印USB设备结构体相关信息
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/videodev2.h>
#include <linux/vmalloc.h>
#include <linux/wait.h>
#include <asm/atomic.h>
#include <asm/unaligned.h>
#include <media/v4l2-common.h>
static int myuvc_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
static int cnt = 0;
struct usb_device *dev = interface_to_usbdev(intf);
struct usb_device_descriptor *descriptor = &dev->descriptor;
printk("myuvc_probe : cnt = %d\n", cnt++);
/* 打印设备描述符 */
printk("Device Descriptor:\n"
" bLength %5u\n"
" bDescriptorType %5u\n"
" bcdUSB %2x.%02x\n"
" bDeviceClass %5u \n"
" bDeviceSubClass %5u \n"
" bDeviceProtocol %5u \n"
" bMaxPacketSize0 %5u\n"
" idVendor 0x%04x \n"
" idProduct 0x%04x \n"
" bcdDevice %2x.%02x\n"
" iManufacturer %5u\n"
" iProduct %5u\n"
" iSerial %5u\n"
" bNumConfigurations %5u\n",
descriptor->bLength, descriptor->bDescriptorType,
descriptor->bcdUSB >> 8, descriptor->bcdUSB & 0xff,
descriptor->bDeviceClass,
descriptor->bDeviceSubClass,
descriptor->bDeviceProtocol,
descriptor->bMaxPacketSize0,
descriptor->idVendor, descriptor->idProduct,
descriptor->bcdDevice >> 8, descriptor->bcdDevice & 0xff,
descriptor->iManufacturer,
descriptor->iProduct,
descriptor->iSerialNumber,
descriptor->bNumConfigurations);
return 0;
}
static void myuvc_disconnect(struct usb_interface *intf)
{
static int cnt = 0;
printk("myuvc_disconnect : cnt = %d\n", cnt++);
}
static struct usb_device_id myuvc_ids[] = {
/* Generic USB Video Class */
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, /* VideoControl Interface */
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 2, 0) }, /* VideoStreaming Interface */
{}
};
/* 1. 分配usb_driver */
/* 2. 设置 */
static struct usb_driver myuvc_driver = {
.name = "myuvc",
.probe = myuvc_probe,
.disconnect = myuvc_disconnect,
.id_table = myuvc_ids,
};
static int myuvc_init(void)
{
/* 3. 注册 */
usb_register(&myuvc_driver);
return 0;
}
static void myuvc_exit(void)
{
usb_deregister(&myuvc_driver);
}
module_init(myuvc_init);
module_exit(myuvc_exit);
MODULE_LICENSE("GPL");
步骤三:添加描述符-打印配置描述符即Configuration描述符
说明:
struct usb_device {
...
struct usb_host_config *config;//配置数组,代表一个usb设备所对应的多个配置
struct usb_host_config *actconfig;// 代表当前配置
...
}
1 添加配置描述符
1.1 分配设备配置结构体 struct usb_host_config *hostconfig
说明:代表设备的当前配置,并用 &dev->config[i] 初始化
1.2 分配设备配置描述符结构体 struct usb_config_descriptor *config
说明:代表usb设备配置所对应的配置描述符,此处代表当前usb配置所对应的配置描述符。
1.3 轮询usb设备的所有配置,并且依次打印每一个配置中的配置描述符。
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/videodev2.h>
#include <linux/vmalloc.h>
#include <linux/wait.h>
#include <asm/atomic.h>
#include <asm/unaligned.h>
#include <media/v4l2-common.h>
static int myuvc_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
static int cnt = 0;
struct usb_device *dev = interface_to_usbdev(intf);
struct usb_device_descriptor *descriptor = &dev->descriptor;
struct usb_host_config *hostconfig;
struct usb_config_descriptor *config;
int i;
printk("myuvc_probe : cnt = %d\n", cnt++);
/* 打印设备描述符 */
printk("Device Descriptor:\n"
" bLength %5u\n"
" bDescriptorType %5u\n"
" bcdUSB %2x.%02x\n"
" bDeviceClass %5u \n"
" bDeviceSubClass %5u \n"
" bDeviceProtocol %5u \n"
" bMaxPacketSize0 %5u\n"
" idVendor 0x%04x \n"
" idProduct 0x%04x \n"
" bcdDevice %2x.%02x\n"
" iManufacturer %5u\n"
" iProduct %5u\n"
" iSerial %5u\n"
" bNumConfigurations %5u\n",
descriptor->bLength, descriptor->bDescriptorType,
descriptor->bcdUSB >> 8, descriptor->bcdUSB & 0xff,
descriptor->bDeviceClass,
descriptor->bDeviceSubClass,
descriptor->bDeviceProtocol,
descriptor->bMaxPacketSize0,
descriptor->idVendor, descriptor->idProduct,
descriptor->bcdDevice >> 8, descriptor->bcdDevice & 0xff,
descriptor->iManufacturer,
descriptor->iProduct,
descriptor->iSerialNumber,
descriptor->bNumConfigurations);
/* 打印配置描述符 */
//设备描述符中指明了该设备具有多少个配置。
for (i = 0; i < descriptor->bNumConfigurations; i++)
{
hostconfig = &dev->config[i];
config = &hostconfig->desc;
printk(" Configuration Descriptor %d:\n"
" bLength %5u\n"
" bDescriptorType %5u\n"
" wTotalLength %5u\n"
" bNumInterfaces %5u\n"
" bConfigurationValue %5u\n"
" iConfiguration %5u\n"
" bmAttributes 0x%02x\n",
i,
config->bLength, config->bDescriptorType,
le16_to_cpu(config->wTotalLength),
config->bNumInterfaces, config->bConfigurationValue,
config->iConfiguration,
config->bmAttributes);
}
return 0;
}
static void myuvc_disconnect(struct usb_interface *intf)
{
static int cnt = 0;
printk("myuvc_disconnect : cnt = %d\n", cnt++);
}
static struct usb_device_id myuvc_ids[] = {
/* Generic USB Video Class */
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, /* VideoControl Interface */
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 2, 0) }, /* VideoStreaming Interface */
{}
};
/* 1. 分配usb_driver */
/* 2. 设置 */
static struct usb_driver myuvc_driver = {
.name = "myuvc",
.probe = myuvc_probe,
.disconnect = myuvc_disconnect,
.id_table = myuvc_ids,
};
static int myuvc_init(void)
{
/* 3. 注册 */
usb_register(&myuvc_driver);
return 0;
}
static void myuvc_exit(void)
{
usb_deregister(&myuvc_driver);
}
module_init(myuvc_init);
module_exit(myuvc_exit);
MODULE_LICENSE("GPL");
步骤四:添加描述符-打印接口联合描述符即IAD/IF描述符
关于 IAD/IF ,在 UVC 1.5 Class specification.pdf 文档中有如下描述:
Interface Association Descriptor:接口关联描述符
A device must use an Interface Association Descriptor to describe a Video Interface Collection for each device function that requires a VideoControl Interface and one or more VideoStreaming interfaces.
对于我们USB摄像头来说,它包含有一个 VideoControl Interface(VC) ,一个或者多个
VideoStreaming interfaces(VS),而VC 和 VS之间的关联信息就在 Interface Association Descriptor 中描述。
1 定义接口关联描述符
struct usb_interface_assoc_descriptor *assoc_desc;
2 初始化接口关联描述符
assoc_desc = hostconfig->intf_assoc[0];
将会打印出 bInterfaceCount = 2 ,因为 id_table 中实现了2个接口
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/videodev2.h>
#include <linux/vmalloc.h>
#include <linux/wait.h>
#include <asm/atomic.h>
#include <asm/unaligned.h>
#include <media/v4l2-common.h>
static int myuvc_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
static int cnt = 0;
struct usb_device *dev = interface_to_usbdev(intf);
struct usb_device_descriptor *descriptor = &dev->descriptor;
struct usb_host_config *hostconfig;
struct usb_config_descriptor *config;
struct usb_interface_assoc_descriptor *assoc_desc;
int i;
printk("myuvc_probe : cnt = %d\n", cnt++);
/* 打印设备描述符 */
printk("Device Descriptor:\n"
" bLength %5u\n"
" bDescriptorType %5u\n"
" bcdUSB %2x.%02x\n"
" bDeviceClass %5u \n"
" bDeviceSubClass %5u \n"
" bDeviceProtocol %5u \n"
" bMaxPacketSize0 %5u\n"
" idVendor 0x%04x \n"
" idProduct 0x%04x \n"
" bcdDevice %2x.%02x\n"
" iManufacturer %5u\n"
" iProduct %5u\n"
" iSerial %5u\n"
" bNumConfigurations %5u\n",
descriptor->bLength, descriptor->bDescriptorType,
descriptor->bcdUSB >> 8, descriptor->bcdUSB & 0xff,
descriptor->bDeviceClass,
descriptor->bDeviceSubClass,
descriptor->bDeviceProtocol,
descriptor->bMaxPacketSize0,
descriptor->idVendor, descriptor->idProduct,
descriptor->bcdDevice >> 8, descriptor->bcdDevice & 0xff,
descriptor->iManufacturer,
descriptor->iProduct,
descriptor->iSerialNumber,
descriptor->bNumConfigurations);
/* 打印配置描述符 */
for (i = 0; i < descriptor->bNumConfigurations; i++)
{
hostconfig = &dev->config[i];
config = &hostconfig->desc;
printk(" Configuration Descriptor %d:\n"
" bLength %5u\n"
" bDescriptorType %5u\n"
" wTotalLength %5u\n"
" bNumInterfaces %5u\n"
" bConfigurationValue %5u\n"
" iConfiguration %5u\n"
" bmAttributes 0x%02x\n",
i,
config->bLength, config->bDescriptorType,
le16_to_cpu(config->wTotalLength),
config->bNumInterfaces, config->bConfigurationValue,
config->iConfiguration,
config->bmAttributes);
//初始化接口关联描述符
assoc_desc = hostconfig->intf_assoc[0];
/* 打印接口关联描述符 */
printk(" Interface Association:\n"
" bLength %5u\n"
" bDescriptorType %5u\n"
" bFirstInterface %5u\n"
" bInterfaceCount %5u\n"
" bFunctionClass %5u\n"
" bFunctionSubClass %5u\n"
" bFunctionProtocol %5u\n"
" iFunction %5u\n",
assoc_desc->bLength,
assoc_desc->bDescriptorType,
assoc_desc->bFirstInterface,
assoc_desc->bInterfaceCount,
assoc_desc->bFunctionClass,
assoc_desc->bFunctionSubClass,
assoc_desc->bFunctionProtocol,
assoc_desc->iFunction);
}
return 0;
}
static void myuvc_disconnect(struct usb_interface *intf)
{
static int cnt = 0;
printk("myuvc_disconnect : cnt = %d\n", cnt++);
}
static struct usb_device_id myuvc_ids[] = {
/* Generic USB Video Class */
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, /* VideoControl Interface */
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 2, 0) }, /* VideoStreaming Interface */
{}
};
/* 1. 分配usb_driver */
/* 2. 设置 */
static struct usb_driver myuvc_driver = {
.name = "myuvc",
.probe = myuvc_probe,
.disconnect = myuvc_disconnect,
.id_table = myuvc_ids,
};
static int myuvc_init(void)
{
/* 3. 注册 */
usb_register(&myuvc_driver);
return 0;
}
static void myuvc_exit(void)
{
usb_deregister(&myuvc_driver);
}
module_init(myuvc_init);
module_exit(myuvc_exit);
MODULE_LICENSE("GPL");
步骤五 :添加描述符-打印接口描述符
1 定义一个接口描述符指针
struct usb_interface_descriptor *interface;
2 打印 接口描述符中的若干个设置项
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/videodev2.h>
#include <linux/vmalloc.h>
#include <linux/wait.h>
#include <asm/atomic.h>
#include <asm/unaligned.h>
#include <media/v4l2-common.h>
static int myuvc_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
static int cnt = 0;
struct usb_device *dev = interface_to_usbdev(intf);
struct usb_device_descriptor *descriptor = &dev->descriptor;
struct usb_host_config *hostconfig;
struct usb_config_descriptor *config;
struct usb_interface_assoc_descriptor *assoc_desc;
struct usb_interface_descriptor *interface;
int i, j;
printk("myuvc_probe : cnt = %d\n", cnt++);
/* 打印设备描述符 */
printk("Device Descriptor:\n"
" bLength %5u\n"
" bDescriptorType %5u\n"
" bcdUSB %2x.%02x\n"
" bDeviceClass %5u \n"
" bDeviceSubClass %5u \n"
" bDeviceProtocol %5u \n"
" bMaxPacketSize0 %5u\n"
" idVendor 0x%04x \n"
" idProduct 0x%04x \n"
" bcdDevice %2x.%02x\n"
" iManufacturer %5u\n"
" iProduct %5u\n"
" iSerial %5u\n"
" bNumConfigurations %5u\n",
descriptor->bLength, descriptor->bDescriptorType,
descriptor->bcdUSB >> 8, descriptor->bcdUSB & 0xff,
descriptor->bDeviceClass,
descriptor->bDeviceSubClass,
descriptor->bDeviceProtocol,
descriptor->bMaxPacketSize0,
descriptor->idVendor, descriptor->idProduct,
descriptor->bcdDevice >> 8, descriptor->bcdDevice & 0xff,
descriptor->iManufacturer,
descriptor->iProduct,
descriptor->iSerialNumber,
descriptor->bNumConfigurations);
/* 打印配置描述符 */
for (i = 0; i < descriptor->bNumConfigurations; i++)
{
hostconfig = &dev->config[i];
config = &hostconfig->desc;
printk(" Configuration Descriptor %d:\n"
" bLength %5u\n"
" bDescriptorType %5u\n"
" wTotalLength %5u\n"
" bNumInterfaces %5u\n"
" bConfigurationValue %5u\n"
" iConfiguration %5u\n"
" bmAttributes 0x%02x\n",
i,
config->bLength, config->bDescriptorType,
le16_to_cpu(config->wTotalLength),
config->bNumInterfaces, config->bConfigurationValue,
config->iConfiguration,
config->bmAttributes);
/* 打印接口联合描述符 */
assoc_desc = hostconfig->intf_assoc[0];
printk(" Interface Association:\n"
" bLength %5u\n"
" bDescriptorType %5u\n"
" bFirstInterface %5u\n"
" bInterfaceCount %5u\n"
" bFunctionClass %5u\n"
" bFunctionSubClass %5u\n"
" bFunctionProtocol %5u\n"
" iFunction %5u\n",
assoc_desc->bLength,
assoc_desc->bDescriptorType,
assoc_desc->bFirstInterface,
assoc_desc->bInterfaceCount,
assoc_desc->bFunctionClass,
assoc_desc->bFunctionSubClass,
assoc_desc->bFunctionProtocol,
assoc_desc->iFunction);
/* 打印接口描述符里面的若干个设置项 */
for (j = 0; j < intf->num_altsetting; j++)
{
interface = &intf->altsetting[j].desc;
printk(" Interface Descriptor altsetting %d:\n"
" bLength %5u\n"
" bDescriptorType %5u\n"
" bInterfaceNumber %5u\n"
" bAlternateSetting %5u\n"
" bNumEndpoints %5u\n"
" bInterfaceClass %5u\n"
" bInterfaceSubClass %5u\n"
" bInterfaceProtocol %5u\n"
" iInterface %5u\n",
j,
interface->bLength, interface->bDescriptorType, interface->bInterfaceNumber,
interface->bAlternateSetting, interface->bNumEndpoints, interface->bInterfaceClass,
interface->bInterfaceSubClass, interface->bInterfaceProtocol,
interface->iInterface);
}
}
return 0;
}
static void myuvc_disconnect(struct usb_interface *intf)
{
static int cnt = 0;
printk("myuvc_disconnect : cnt = %d\n", cnt++);
}
static struct usb_device_id myuvc_ids[] = {
/* Generic USB Video Class */
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, /* VideoControl Interface */
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 2, 0) }, /* VideoStreaming Interface */
{}
};
/* 1. 分配usb_driver */
/* 2. 设置 */
static struct usb_driver myuvc_driver = {
.name = "myuvc",
.probe = myuvc_probe,
.disconnect = myuvc_disconnect,
.id_table = myuvc_ids,
};
static int myuvc_init(void)
{
/* 3. 注册 */
usb_register(&myuvc_driver);
return 0;
}
static void myuvc_exit(void)
{
usb_deregister(&myuvc_driver);
}
module_init(myuvc_init);
module_exit(myuvc_exit);
MODULE_LICENSE("GPL");
步骤六 :添加描述符-打印UVC设备自定义描述符
我们 UVC设备自定义描述符全部都从存储于
struct usb_interface->cur_altsetting->extra 中。
工作:
1 取出 buffer : intf->cur_altsetting->extra
2 取出 buflen : intf->cur_altsetting->extralen;
3 打印 UVC自定义的描述符
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/videodev2.h>
#include <linux/vmalloc.h>
#include <linux/wait.h>
#include <asm/atomic.h>
#include <asm/unaligned.h>
#include <media/v4l2-common.h>
static int myuvc_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
static int cnt = 0;
struct usb_device *dev = interface_to_usbdev(intf);
struct usb_device_descriptor *descriptor = &dev->descriptor;
struct usb_host_config *hostconfig;
struct usb_config_descriptor *config;
struct usb_interface_assoc_descriptor *assoc_desc;
struct usb_interface_descriptor *interface;
int i, j, k, l;
unsigned char *buffer;
int buflen;
int desc_len;
int desc_cnt;
printk("myuvc_probe : cnt = %d\n", cnt++);
/* 打印设备描述符 */
printk("Device Descriptor:\n"
" bLength %5u\n"
" bDescriptorType %5u\n"
" bcdUSB %2x.%02x\n"
" bDeviceClass %5u \n"
" bDeviceSubClass %5u \n"
" bDeviceProtocol %5u \n"
" bMaxPacketSize0 %5u\n"
" idVendor 0x%04x \n"
" idProduct 0x%04x \n"
" bcdDevice %2x.%02x\n"
" iManufacturer %5u\n"
" iProduct %5u\n"
" iSerial %5u\n"
" bNumConfigurations %5u\n",
descriptor->bLength, descriptor->bDescriptorType,
descriptor->bcdUSB >> 8, descriptor->bcdUSB & 0xff,
descriptor->bDeviceClass,
descriptor->bDeviceSubClass,
descriptor->bDeviceProtocol,
descriptor->bMaxPacketSize0,
descriptor->idVendor, descriptor->idProduct,
descriptor->bcdDevice >> 8, descriptor->bcdDevice & 0xff,
descriptor->iManufacturer,
descriptor->iProduct,
descriptor->iSerialNumber,
descriptor->bNumConfigurations);
for (i = 0; i < descriptor->bNumConfigurations; i++)
{
hostconfig = &dev->config[i];
config = &hostconfig->desc;
printk(" Configuration Descriptor %d:\n"
" bLength %5u\n"
" bDescriptorType %5u\n"
" wTotalLength %5u\n"
" bNumInterfaces %5u\n"
" bConfigurationValue %5u\n"
" iConfiguration %5u\n"
" bmAttributes 0x%02x\n",
i,
config->bLength, config->bDescriptorType,
le16_to_cpu(config->wTotalLength),
config->bNumInterfaces, config->bConfigurationValue,
config->iConfiguration,
config->bmAttributes);
assoc_desc = hostconfig->intf_assoc[0];
printk(" Interface Association:\n"
" bLength %5u\n"
" bDescriptorType %5u\n"
" bFirstInterface %5u\n"
" bInterfaceCount %5u\n"
" bFunctionClass %5u\n"
" bFunctionSubClass %5u\n"
" bFunctionProtocol %5u\n"
" iFunction %5u\n",
assoc_desc->bLength,
assoc_desc->bDescriptorType,
assoc_desc->bFirstInterface,
assoc_desc->bInterfaceCount,
assoc_desc->bFunctionClass,
assoc_desc->bFunctionSubClass,
assoc_desc->bFunctionProtocol,
assoc_desc->iFunction);
for (j = 0; j < intf->num_altsetting; j++)
{
interface = &intf->altsetting[j].desc;
printk(" Interface Descriptor altsetting %d:\n"
" bLength %5u\n"
" bDescriptorType %5u\n"
" bInterfaceNumber %5u\n"
" bAlternateSetting %5u\n"
" bNumEndpoints %5u\n"
" bInterfaceClass %5u\n"
" bInterfaceSubClass %5u\n"
" bInterfaceProtocol %5u\n"
" iInterface %5u\n",
j,
interface->bLength, interface->bDescriptorType, interface->bInterfaceNumber,
interface->bAlternateSetting, interface->bNumEndpoints, interface->bInterfaceClass,
interface->bInterfaceSubClass, interface->bInterfaceProtocol,
interface->iInterface);
}
//打印 UVC自定义的描述符
buffer = intf->cur_altsetting->extra;
buflen = intf->cur_altsetting->extralen;
printk("extra buffer of interface %d:\n", cnt-1);
k = 0;
desc_cnt = 0;
while (k < buflen)
{
desc_len = buffer[k];
printk("extra desc %d: ", desc_cnt);
for (l = 0; l < desc_len; l++, k++)
{
printk("%02x ", buffer[k]);
}
desc_cnt++;
printk("\n");
}
}
return 0;
}
static void myuvc_disconnect(struct usb_interface *intf)
{
static int cnt = 0;
printk("myuvc_disconnect : cnt = %d\n", cnt++);
}
static struct usb_device_id myuvc_ids[] = {
/* Generic USB Video Class */
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, /* VideoControl Interface */
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 2, 0) }, /* VideoStreaming Interface */
{}
};
/* 1. 分配usb_driver */
/* 2. 设置 */
static struct usb_driver myuvc_driver = {
.name = "myuvc",
.probe = myuvc_probe,
.disconnect = myuvc_disconnect,
.id_table = myuvc_ids,
};
static int myuvc_init(void)
{
/* 3. 注册 */
usb_register(&myuvc_driver);
return 0;
}
static void myuvc_exit(void)
{
usb_deregister(&myuvc_driver);
}
module_init(myuvc_init);
module_exit(myuvc_exit);
MODULE_LICENSE("GPL");
编译运行后,分别打印了两个接口的 自定义描述符,即VC接口的描述符 和 VS接口的描述符。如下:
VideoControl Interface 的自定义描述符:
extra buffer of interface 0:
extra desc 0: 0d 24 01 00 01 4d 00 80 c3 c9 01 01 01
extra desc 1: 12 24 02 01 01 02 00 00 00 00 00 00 00 00 03 0e 00 00
extra desc 2: 09 24 03 02 01 01 00 04 00
extra desc 3: 0b 24 05 03 01 00 00 02 7f 14 00
extra desc 4: 1a 24 06 04 ad cc b1 c2 f6 ab b8 48 8e 37 32 d4 f3 a3 fe ec 08 01 03 01 3f 00
VideoStreaming Interface的自定义描述符:
extra buffer of interface 1:
extra desc 0: 0e 24 01 01 df 00 81 00 02 02 01 01 01 00
extra desc 1: 1b 24 04 01 05 59 55 59 32 00 00 10 00 80 00 00 aa 00 38 9b 71 10 01 00 00 00 00
extra desc 2: 1e 24 05 01 00 80 02 e0 01 00 00 ca 08 00 00 ca 08 00 60 09 00 15 16 05 00 01 15 16 05 00
extra desc 3: 1e 24 05 02 00 60 01 20 01 00 80 e6 02 00 80 e6 02 00 18 03 00 15 16 05 00 01 15 16 05 00
extra desc 4: 1e 24 05 03 00 40 01 f0 00 00 80 32 02 00 80 32 02 00 58 02 00 15 16 05 00 01 15 16 05 00
extra desc 5: 1e 24 05 04 00 b0 00 90 00 00 a0 b9 00 00 a0 b9 00 00 c6 00 00 15 16 05 00 01 15 16 05 00
extra desc 6: 1e 24 05 05 00 a0 00 78 00 00 a0 8c 00 00 a0 8c 00 00 96 00 00 15 16 05 00 01 15 16 05 00
extra desc 7: 1a 24 03 00 05 80 02 e0 01 60 01 20 01 40 01 f0 00 b0 00 90 00 a0 00 78 00 00
extra desc 8: 06 24 0d 01 01 04
结合UVC规范分析这两个接口的描述符
改表格为 UVC描述符格式参考表,即即每行描述符第0位为长度,第一位为 接口描述类,搜索文档可知为0x24 第二位为子类。
设备描述符子类参照表
即
VC_DESCRIPTOR_UNDEFINED 0x00
VC_HEADER 0x01
VC_INPUT_TERMINAL 0x02
VC_OUTPUT_TERMINAL 0x03
VC_SELECTOR_UNIT 0x04
VC_PROCESSING_UNIT 0x05
VC_EXTENSION_UNIT 0x06
VC_ENCODING_UNIT 0x07
分析 VideoControl Interface 的自定义描述符:
则上面打印的 VideoControl Interface 的自定义描述符 的
第0位...
第1位数据 描述类都是 24
第2位数据 子类分别是
{
extra desc 0 --> 01 : VC_HEADER
extra desc 1 --> 02 : VC_INPUT_TERMINAL
extra desc 2 --> 03 : VC_OUTPUT_TERMINAL
extra desc 3 --> 05 : VC_PROCESSING_UNIT
extra desc 4 --> 06 : VC_EXTENSION_UNIT
}
第3位数据 ID 分别是
{
extra desc 0 --> VC_HEADER 的 ID 是 00
extra desc 1 --> VC_INPUT_TERMINAL 的 ID 是 01
extra desc 2 --> VC_OUTPUT_TERMINAL 的 ID 是 02
extra desc 3 --> VC_PROCESSING_UNIT 的 ID 是 03
extra desc 4 --> VC_EXTENSION_UNIT 的 ID 是 04
}
回顾前面学习的 USB摄像头硬件结构
结构图VC中的各个 Units Terminals 是怎么联系到一起的呢?结合上面的打印信息分析如下:
IT(01)
PU(03)
EU(04)
OT(02)
我们在 UVC 1.5 Class specification.pdf 文档中搜索 Processing Unit Descriptor 即PU,看一下 该 Unit 的源是什么,如下:
可知 Processing Unit Descriptor 即PU 的源是 描述符第4为位数据
第4位数据
Processing Unit Descriptor 描述符的第四位数据是 bSourceID 即源ID,为01
其余的 Unit 以及 Terminals的 描述符的 源ID 不一定是 描述符的第四位数据,具体要查手册,总之经过一系类查找,得处如下 各个 各个 Units Terminals的源关系如下:
IT(01) ===> PU(03) ===> EU(04) ===> OT(02)
概览信息如下:
extra buffer of interface 0:
extra desc 0: 0d 24 01 00 01 4d 00 80 c3 c9 01 01 01
VC_HEADER
extra desc 1: 12 24 02 01 01 02 00 00 00 00 00 00 00 00 03 0e 00 00
VC_INPUT_TERMINAL ID
extra desc 2: 09 24 03 02 01 01 00 04 00
VC_OUTPUT_TERMINAL ID wTerminalType bAssocTerminal bSourceID
extra desc 3: 0b 24 05 03 01 00 00 02 7f 14 00
VC_PROCESSING_UNIT ID bSourceID wMaxMultiplier bControlSize bmControls
extra desc 4: 1a 24 06 04 ad cc b1 c2 f6 ab b8 48 8e 37 32 d4 f3 a3 fe ec 08 01 03 01 3f 00
VC_EXTENSION_UNIT ID GUID bNumControls bNrInPins baSourceID
分析 VideoStreaming Interface的自定义描述符
描述符的
第0位数据...
第1位数据表示长度
第2位数据表示它的子类
VideoStreaming Interface 所定义的子类有如下种类
VS_INPUT_HEADER 0x01
VS_STILL_IMAGE_FRAME 0x03
VS_FORMAT_UNCOMPRESSED 0x04
VS_FRAME_UNCOMPRESSED 0x05
VS_COLORFORMAT 0x0D
对照UVC规范手册 汇总信息如下
extra buffer of interface 1:
extra desc 0: 0e 24 01 01 df 00 81 00 02 02 01 01 01 00
VS_INPUT_HEADER bNumFormats
extra desc 1: 1b 24 04 01 05 59 55 59 32 00 00 10 00 80 00 00 aa 00 38 9b 71 10 01 00 00 00 00
VS_FORMAT_UNCOMPRESSED bFormatIndex bNumFrameDescriptors GUID bBitsPerPixel
extra desc 2: 1e 24 05 01 00 80 02 e0 01 00 00 ca 08 00 00 ca 08 00 60 09 00 15 16 05 00 01 15 16 05 00
VS_FRAME_UNCOMPRESSED bFrameIndex bmCapabilities wWidth wHeight
640x480
extra desc 3: 1e 24 05 02 00 60 01 20 01 00 80 e6 02 00 80 e6 02 00 18 03 00 15 16 05 00 01 15 16 05 00
VS_FRAME_UNCOMPRESSED
extra desc 4: 1e 24 05 03 00 40 01 f0 00 00 80 32 02 00 80 32 02 00 58 02 00 15 16 05 00 01 15 16 05 00
extra desc 5: 1e 24 05 04 00 b0 00 90 00 00 a0 b9 00 00 a0 b9 00 00 c6 00 00 15 16 05 00 01 15 16 05 00
extra desc 6: 1e 24 05 05 00 a0 00 78 00 00 a0 8c 00 00 a0 8c 00 00 96 00 00 15 16 05 00 01 15 16 05 00
extra desc 7: 1a 24 03 00 05 80 02 e0 01 60 01 20 01 40 01 f0 00 b0 00 90 00 a0 00 78 00 00
VS_STILL_IMAGE_FRAME
extra desc 8: 06 24 0d 01 01 04
描述符
lsusb -v -d 0x1e4e:
Bus 001 Device 007: ID 1e4e:0102
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 239 Miscellaneous Device
bDeviceSubClass 2 ?
bDeviceProtocol 1 Interface Association
bMaxPacketSize0 64
idVendor 0x1e4e
idProduct 0x0102
bcdDevice 0.02
iManufacturer 1
iProduct 2
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 539
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 100mA
Interface Association:
bLength 8
bDescriptorType 11
bFirstInterface 0
bInterfaceCount 2
bFunctionClass 14 Video
bFunctionSubClass 3 Video Interface Collection
bFunctionProtocol 0
iFunction 2
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 1 Video Control
bInterfaceProtocol 0
iInterface 2
VideoControl Interface Descriptor:
bLength 13
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdUVC 1.00
wTotalLength 77
dwClockFrequency 30.000000MHz
bInCollection 1
baInterfaceNr( 0) 1
VideoControl Interface Descriptor:
bLength 18
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 1
wTerminalType 0x0201 Camera Sensor
bAssocTerminal 0
iTerminal 0
wObjectiveFocalLengthMin 0
wObjectiveFocalLengthMax 0
wOcularFocalLength 0
bControlSize 3
bmControls 0x0000000e
Auto-Exposure Mode
Auto-Exposure Priority
Exposure Time (Absolute)
VideoControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (OUTPUT_TERMINAL)
bTerminalID 2
wTerminalType 0x0101 USB Streaming
bAssocTerminal 0
bSourceID 4
iTerminal 0
VideoControl Interface Descriptor:
bLength 11
bDescriptorType 36
bDescriptorSubtype 5 (PROCESSING_UNIT)
Warning: Descriptor too short
bUnitID 3
bSourceID 1
wMaxMultiplier 0
bControlSize 2
bmControls 0x0000147f
Brightness
Contrast
Hue
Saturation
Sharpness
Gamma
White Balance Temperature
Power Line Frequency
White Balance Temperature, Auto
iProcessing 0
bmVideoStandards 0x1a
NTSC - 525/60
SECAM - 625/50
NTSC - 625/50
VideoControl Interface Descriptor:
bLength 26
bDescriptorType 36
bDescriptorSubtype 6 (EXTENSION_UNIT)
bUnitID 4
guidExtensionCode {adccb1c2-f6ab-b848-8e37-32d4f3a3feec}
bNumControl 8
bNrPins 1
baSourceID( 0) 3
bControlSize 1
bmControls( 0) 0x3f
iExtension 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 4
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 0
iInterface 0
VideoStreaming Interface Descriptor:
bLength 14
bDescriptorType 36
bDescriptorSubtype 1 (INPUT_HEADER)
bNumFormats 1
wTotalLength 223
bEndPointAddress 129
bmInfo 0
bTerminalLink 2
bStillCaptureMethod 2
bTriggerSupport 1
bTriggerUsage 1
bControlSize 1
bmaControls( 0) 27
VideoStreaming Interface Descriptor:
bLength 27
bDescriptorType 36
bDescriptorSubtype 4 (FORMAT_UNCOMPRESSED)
bFormatIndex 1
bNumFrameDescriptors 5
guidFormat {59555932-0000-1000-8000-00aa00389b71}
bBitsPerPixel 16
bDefaultFrameIndex 1
bAspectRatioX 0
bAspectRatioY 0
bmInterlaceFlags 0x00
Interlaced stream or variable: No
Fields per frame: 1 fields
Field 1 first: No
Field pattern: Field 1 only
bCopyProtect 0
VideoStreaming Interface Descriptor:
bLength 30
bDescriptorType 36
bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
bFrameIndex 1
bmCapabilities 0x00
Still image unsupported
wWidth 640
wHeight 480
dwMinBitRate 147456000
dwMaxBitRate 147456000
dwMaxVideoFrameBufferSize 614400
dwDefaultFrameInterval 333333
bFrameIntervalType 1
dwFrameInterval( 0) 333333
VideoStreaming Interface Descriptor:
bLength 30
bDescriptorType 36
bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
bFrameIndex 2
bmCapabilities 0x00
Still image unsupported
wWidth 352
wHeight 288
dwMinBitRate 48660480
dwMaxBitRate 48660480
dwMaxVideoFrameBufferSize 202752
dwDefaultFrameInterval 333333
bFrameIntervalType 1
dwFrameInterval( 0) 333333
VideoStreaming Interface Descriptor:
bLength 30
bDescriptorType 36
bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
bFrameIndex 3
bmCapabilities 0x00
Still image unsupported
wWidth 320
wHeight 240
dwMinBitRate 36864000
dwMaxBitRate 36864000
dwMaxVideoFrameBufferSize 153600
dwDefaultFrameInterval 333333
bFrameIntervalType 1
dwFrameInterval( 0) 333333
VideoStreaming Interface Descriptor:
bLength 30
bDescriptorType 36
bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
bFrameIndex 4
bmCapabilities 0x00
Still image unsupported
wWidth 176
wHeight 144
dwMinBitRate 12165120
dwMaxBitRate 12165120
dwMaxVideoFrameBufferSize 50688
dwDefaultFrameInterval 333333
bFrameIntervalType 1
dwFrameInterval( 0) 333333
VideoStreaming Interface Descriptor:
bLength 30
bDescriptorType 36
bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
bFrameIndex 5
bmCapabilities 0x00
Still image unsupported
wWidth 160
wHeight 120
dwMinBitRate 9216000
dwMaxBitRate 9216000
dwMaxVideoFrameBufferSize 38400
dwDefaultFrameInterval 333333
bFrameIntervalType 1
dwFrameInterval( 0) 333333
VideoStreaming Interface Descriptor:
bLength 26
bDescriptorType 36
bDescriptorSubtype 3 (STILL_IMAGE_FRAME)
bEndpointAddress 0
bNumImageSizePatterns 5
wWidth( 0) 640
wHeight( 0) 480
wWidth( 1) 352
wHeight( 1) 288
wWidth( 2) 320
wHeight( 2) 240
wWidth( 3) 176
wHeight( 3) 144
wWidth( 4) 160
wHeight( 4) 120
bNumCompressionPatterns 5
VideoStreaming Interface Descriptor:
bLength 6
bDescriptorType 36
bDescriptorSubtype 13 (COLORFORMAT)
bColorPrimaries 1 (BT.709,sRGB)
bTransferCharacteristics 1 (BT.709)
bMatrixCoefficients 4 (SMPTE 170M (BT.601))
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 1
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x00a0 1x 160 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 2
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x00d0 1x 208 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 3
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0300 1x 768 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 4
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x030c 1x 780 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 5
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x032c 1x 812 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 6
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x03d0 1x 976 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 7
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x03fc 1x 1020 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 8
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 9
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0a58 2x 600 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 10
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0b00 2x 768 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 11
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x1334 3x 820 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 12
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x13fc 3x 1020 bytes
bInterval 1