学习目标:参考lsusb源码,打印USB摄像头的设备描述符、配置描述符、接口联合描述符、端点描述符;

一、lsusb命令和源码

使用命令lsusb可以看看设备的id,并执行 # lsusb -v -d 0x1b3b:2977 命令查看usb摄像头的描述符。

二、源码

打印以下描述符:

程序主要正在probe执行printk函数进行打印:

  1 static int myuvc_probe(struct usb_interface *intf,
  2              const struct usb_device_id *id)
  3 {
  4     static int cnt = 0;
  5     struct usb_device *dev = interface_to_usbdev(intf);
  6     struct usb_device_descriptor *descriptor = &dev->descriptor;
  7     struct usb_host_config *hostconfig;
  8     struct usb_config_descriptor *config;
  9     struct usb_interface_assoc_descriptor *assoc_desc;
 10     struct usb_interface_descriptor    *interface;
 11     struct usb_endpoint_descriptor  *endpoint;
 12     int i, j, k, l, m;
 13     unsigned char *buffer;
 14     int buflen;
 15     int desc_len;
 16     int desc_cnt;
 17
 18     printk("myuvc_probe : cnt = %d\n", cnt++);
 19
 20     /* 打印设备描述符 */
 21     printk("Device Descriptor:\n"
 22            "  bLength             %5u\n"
 23            "  bDescriptorType     %5u\n"
 24            "  bcdUSB              %2x.%02x\n"
 25            "  bDeviceClass        %5u \n"
 26            "  bDeviceSubClass     %5u \n"
 27            "  bDeviceProtocol     %5u \n"
 28            "  bMaxPacketSize0     %5u\n"
 29            "  idVendor           0x%04x \n"
 30            "  idProduct          0x%04x \n"
 31            "  bcdDevice           %2x.%02x\n"
 32            "  iManufacturer       %5u\n"
 33            "  iProduct            %5u\n"
 34            "  iSerial             %5u\n"
 35            "  bNumConfigurations  %5u\n",
 36            descriptor->bLength, descriptor->bDescriptorType,
 37            descriptor->bcdUSB >> 8, descriptor->bcdUSB & 0xff,
 38            descriptor->bDeviceClass,
 39            descriptor->bDeviceSubClass,
 40            descriptor->bDeviceProtocol,
 41            descriptor->bMaxPacketSize0,
 42            descriptor->idVendor,  descriptor->idProduct,
 43            descriptor->bcdDevice >> 8, descriptor->bcdDevice & 0xff,
 44            descriptor->iManufacturer,
 45            descriptor->iProduct,
 46            descriptor->iSerialNumber,
 47            descriptor->bNumConfigurations);
 48
 49     for (i = 0; i < descriptor->bNumConfigurations; i++)
 50     {
 51         hostconfig = &dev->config[i]; //第i个配置
 52         config     = &hostconfig->desc;
 53         printk("  Configuration Descriptor %d:\n"
 54                "    bLength             %5u\n"
 55                "    bDescriptorType     %5u\n"
 56                "    wTotalLength        %5u\n"
 57                "    bNumInterfaces      %5u\n"
 58                "    bConfigurationValue %5u\n"
 59                "    iConfiguration      %5u\n"
 60                "    bmAttributes         0x%02x\n",
 61                i,
 62                config->bLength, config->bDescriptorType,
 63                le16_to_cpu(config->wTotalLength),
 64                config->bNumInterfaces, config->bConfigurationValue,
 65                config->iConfiguration,
 66                config->bmAttributes);
 67
 68         assoc_desc = hostconfig->intf_assoc[0]; //IAD
 69         printk("    Interface Association:\n"
 70                "      bLength             %5u\n"
 71                "      bDescriptorType     %5u\n"
 72                "      bFirstInterface     %5u\n"
 73                "      bInterfaceCount     %5u\n"
 74                "      bFunctionClass      %5u\n"
 75                "      bFunctionSubClass   %5u\n"
 76                "      bFunctionProtocol   %5u\n"
 77                "      iFunction           %5u\n",
 78             assoc_desc->bLength,
 79             assoc_desc->bDescriptorType,
 80             assoc_desc->bFirstInterface,
 81             assoc_desc->bInterfaceCount,
 82             assoc_desc->bFunctionClass,
 83             assoc_desc->bFunctionSubClass,
 84             assoc_desc->bFunctionProtocol,
 85             assoc_desc->iFunction);
 86
 87             for (j = 0; j < intf->num_altsetting; j++)
 88             {
 89                 interface = &intf->altsetting[j].desc; //第j个设置的描述符  接口描述符
 90                 printk("    Interface Descriptor altsetting %d:\n"
 91                        "      bLength             %5u\n"
 92                        "      bDescriptorType     %5u\n"
 93                        "      bInterfaceNumber    %5u\n"
 94                        "      bAlternateSetting   %5u\n"
 95                        "      bNumEndpoints       %5u\n"
 96                        "      bInterfaceClass     %5u\n"
 97                        "      bInterfaceSubClass  %5u\n"
 98                        "      bInterfaceProtocol  %5u\n"
 99                        "      iInterface          %5u\n",
100                        j,
101                        interface->bLength, interface->bDescriptorType, interface->bInterfaceNumber,
102                        interface->bAlternateSetting, interface->bNumEndpoints, interface->bInterfaceClass,
103                        interface->bInterfaceSubClass, interface->bInterfaceProtocol,
104                        interface->iInterface);
105                 /* 打印端点描述符 */
106                 for (m = 0; m < interface->bNumEndpoints; m++)
107                 {
108                     endpoint = &intf->altsetting[j].endpoint[m].desc;
109                     dump_endpoint(endpoint);
110                 }
111
112             }
113        /*自定义描述符*/
114             buffer = intf->cur_altsetting->extra;
115             buflen = intf->cur_altsetting->extralen;
116             printk("extra buffer of interface %d:\n", cnt-1);
117             k = 0;
118             desc_cnt = 0;
119             while (k < buflen)
120             {
121                 desc_len = buffer[k];
122                 printk("extra desc %d: ", desc_cnt);
123                 for (l = 0; l < desc_len; l++, k++)
124                 {
125                     printk("%02x ", buffer[k]);
126                 }
127                 desc_cnt++;
128                 printk("\n");
129             }
130         //模拟lsusb打印内核usb摄像头信息
131             interface = &intf->cur_altsetting->desc;
132             if ((buffer[1] == USB_DT_CS_INTERFACE) && (interface->bInterfaceSubClass == 1))
133             {
134                 parse_videocontrol_interface(intf, buffer, buflen);
135             }
136             if ((buffer[1] == USB_DT_CS_INTERFACE) && (interface->bInterfaceSubClass == 2))
137             {
138                 parse_videostreaming_interface(intf, buffer, buflen);
139             }
140
141     }
142
143
144     return 0;
145 }

分析:

1. VideoControl Interface的自定义描述符:

[318044.582155] extra buffer of interface 0:
[318044.582156] extra desc 0: 0d 24 01 00 01 4d 00 80 c3 c9 01 01 01
[318044.582161] extra desc 1: 12 24 02 01 01 02 00 00 00 00 00 00 00 00 03 0e 00 00
[318044.582166] extra desc 2: 09 24 03 02 01 01 00 04 00
[318044.582170] extra desc 3: 0b 24 05 03 01 00 00 02 7f 14 00
[318044.582174] 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 

解析:

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         --->UVC 1.5 Class specification 69页
bControlSize =2表示,后面2个字节,支持哪些功能,该位设为1表示为支持此功能;
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
从而可知数据流向:IT(01)  ===>  PU(03)  ===>  EU(04)  ===>  OT(02)

1)第1字节为长度;

2)第2个字节表示为自定义的;

3)第3个字节为VC定义的子类:Video Class-Specific VC Interface Descriptor Subtypes 172页
  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

4)第4个字节为bSourceID,来源

5)后面字节要根据手册分析;

2. VideoStreaming Interface的自定义描述符:

[318044.582312] extra buffer of interface 1:
[318044.582313] extra desc 0: 0e 24 01 01 df 00 81 00 02 02 01 01 01 00
[318044.582317] 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
[318044.582325] 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
[318044.582333] 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
[318044.582342] 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
[318044.582350] 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
[318044.582358] 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
[318044.582367] 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
[318044.582374] extra desc 8: 06 24 0d 01 01 04 

分析:

第3个字节:数据来源
VS_INPUT_HEADER 0x01
  VS_STILL_IMAGE_FRAME 0x03        // 表示支持静态图片,拍照功能
  VS_FORMAT_UNCOMPRESSED 0x04  // 表示格式
  VS_FRAME_UNCOMPRESSED 0x05  frame //表示一种格式下可支持多种分辨率
  VS_COLORFORMAT 0x0D  

转载于:https://www.cnblogs.com/lxl-lennie/p/10329121.html

2.7 usb摄像头之usb摄像头描述符打印相关推荐

  1. uvc摄像头代码解析之描述符

    1.uvc驱动模块入口 module_init(uvc_init); //1.模块入口 2.初始化函数 static int __init uvc_init(void) // 2.初始化函数 {int ...

  2. USB设备多个配置描述符的获取过程

    多配置USB设备枚举过程和多字符串描述符的枚举是相同的,过程如下: 1. 总线复位: 2. 获取设备描述符: 3. 总线复位: 4. 设置地址: 5. 获取设备描述符: 6. 获取配置描述符1: 7. ...

  3. usb驱动开发7——接口描述符

    此系列是http://blog.csdn.net/fudan_abc/博文的整理,同时加入了自己的理解.很敬佩fudan_abc的文章,仔细学习和分析受益很多.注:fundan_abc所分析linux ...

  4. USB开发基础:USB命令(请求)和USB描述符

    一.USB命令 在USB规范里,对命令一词提供的单词为"Request",但这里为了更好的理解主机与设备之间的主从关系,将它定义成"命令". 所有的USB设备都 ...

  5. USB基础---设备、配置、接口、端点和字符串描述符

    USB设备用描述符报告他们的属性,一个描述符是一个已定义格式的数据结构体.每个描述符以一个表示描述符长度的字节和一个表示描述符类型的字节开始. USB描述符信息存储在USB设备中,在枚举过程中,USB ...

  6. USB描述符解析和USB_CCID描述符设置

    USB描述符解析 USB描述符信息会被存储在USB设备中,在设备枚举过程中,USB主机会向USB设备发送GetDescriptor请求,USB设备在收到这个请求之后,会将USB描述符信息返回给USB主 ...

  7. USB设备开发---- usb描述符概述

    说到USB设备,不得不提到各种描述符(descriptors), 一般来说,描述符有如下几种: 1:设备描述符(Device Descriptors) 2:配置描述符(Configuration De ...

  8. USB鼠标-字符串描述符(七)

    USB 鼠标详解阅读顺序 1.枚举 2.设备描述符 3.设置地址 4.配置描述符 5.接口描述符 6.HID 描述符 7.端点描述符 8.字符串描述符 9.HID 报告描述符 10.HID 报告的返回 ...

  9. 二,usb描述符-设备 配置 接口 端点

    一,基础概念 在USB设备的逻辑组织中,包含设备.配置.接口和端点4个层次. 每个USB设备都提供了不同级别的配置信息,可以包含一个或多个配置,不同的配置使设备表现出不同的功能组合(在探测/连接期间需 ...

最新文章

  1. Windows配置jdk环境变量JAVA_HOME与path
  2. 模糊数学笔记:四、模糊矩阵与模糊关系
  3. Lesson 02:变量、数据类型
  4. linux内核如何修改lowmem,技术内幕:Android对Linux内核的增强 Low Memory Killer
  5. vue 白边 项目_GUIDE.md · kaiking_g/g6-vue-demo - Gitee.com
  6. 开放下载!《AliOS Things快速开发指南》
  7. 机器学习入门KNN近邻算法(一)
  8. 仿写简单的vue虚拟dom
  9. 我和学姐聊了下他在阿里这9年的成长,受益颇多!
  10. 用JAVA制作小游戏——推箱子(一)
  11. 将python程序打包为exe及一些问题
  12. uniapp使用cmd引入uview报错,文件查找失败:‘uview-ui‘
  13. 通过selenium突破极验验证实现登录
  14. 独家专访 | “共同基金之父”纽伯格的公司(NeubergerBerman)要在中国做什么?
  15. llvm Pass简单实例
  16. 乐高JAVA编程_用乐高认真玩进行Design Sprint
  17. 层次高的人,都拥有成长型思维
  18. 注意力机制学习 BAM
  19. 如何用手机给视频变速
  20. 深入理解String.intern

热门文章

  1. malloc calloc realloc的对比
  2. Android获取挂载U盘的属性
  3. Android用观察者模式代替广播通知刷新界面
  4. View及ViewGroup的事件分发及传递(一)
  5. c++ opencv 通过网络连接工业相机_OpenCV项目实战之零件缺陷检测(上)
  6. Glide DiskCache 原理分析
  7. uniapp启动页,底部虚拟按钮向上闪一下的问题
  8. DWM1000 长距离模块讨论
  9. HTTP [TCP Retransmission] Continuation or non-HTTP traffic[Packet size limited during capture]
  10. Android自定义Seekbar拖动条式样