zoukankan      html  css  js  c++  java
  • 2.7 usb摄像头之usb摄像头描述符打印

    学习目标:参考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
    ", cnt++);
     19 
     20     /* 打印设备描述符 */
     21     printk("Device Descriptor:
    "
     22            "  bLength             %5u
    "
     23            "  bDescriptorType     %5u
    "
     24            "  bcdUSB              %2x.%02x
    "
     25            "  bDeviceClass        %5u 
    "
     26            "  bDeviceSubClass     %5u 
    "
     27            "  bDeviceProtocol     %5u 
    "
     28            "  bMaxPacketSize0     %5u
    "
     29            "  idVendor           0x%04x 
    "
     30            "  idProduct          0x%04x 
    "
     31            "  bcdDevice           %2x.%02x
    "
     32            "  iManufacturer       %5u
    "
     33            "  iProduct            %5u
    "
     34            "  iSerial             %5u
    "
     35            "  bNumConfigurations  %5u
    ",
     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:
    "
     54                "    bLength             %5u
    "
     55                "    bDescriptorType     %5u
    "
     56                "    wTotalLength        %5u
    "
     57                "    bNumInterfaces      %5u
    "
     58                "    bConfigurationValue %5u
    "
     59                "    iConfiguration      %5u
    "
     60                "    bmAttributes         0x%02x
    ",
     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:
    "
     70                "      bLength             %5u
    "
     71                "      bDescriptorType     %5u
    "
     72                "      bFirstInterface     %5u
    "
     73                "      bInterfaceCount     %5u
    "
     74                "      bFunctionClass      %5u
    "
     75                "      bFunctionSubClass   %5u
    "
     76                "      bFunctionProtocol   %5u
    "
     77                "      iFunction           %5u
    ",
     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:
    "
     91                        "      bLength             %5u
    "
     92                        "      bDescriptorType     %5u
    "
     93                        "      bInterfaceNumber    %5u
    "
     94                        "      bAlternateSetting   %5u
    "
     95                        "      bNumEndpoints       %5u
    "
     96                        "      bInterfaceClass     %5u
    "
     97                        "      bInterfaceSubClass  %5u
    "
     98                        "      bInterfaceProtocol  %5u
    "
     99                        "      iInterface          %5u
    ",
    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:
    ", 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("
    ");
    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  
     
     
  • 相关阅读:
    Java程序员面试宝典
    毕设进度19
    毕设进度18
    毕设进度17
    毕设进度16
    毕设进度15
    毕设进度14
    毕设进度13
    css笔记
    14.10源
  • 原文地址:https://www.cnblogs.com/lxl-lennie/p/10329121.html
Copyright © 2011-2022 走看看