嵌入式系统与单片机|技术阅读
登录|注册

您现在的位置是:嵌入式系统与单片机 > 技术阅读 > USB系列之-WINUSB枚举过程实例分享

USB系列之-WINUSB枚举过程实例分享

前言

  本文分享WINUSB枚举过程和描述符实例。

WINUSB枚举过程

描述符实例

设备描述符

static const uint8_t s_dev_desc[] = {    0x12,    0x01,    0x00,    0x02,    0x00,    0x00,    0x00,    0x40,    0x95,    0x19,    0x01,    0x01,    0x00,    0x01,    0x01,    0x02,    0x00,    0x01,};

索引EE的字符串描述符

12 03 4d 00 53 00 46 00 54 00 31 00 30 00 30 00 41 00

MSFT100A

配置描述符

static const uint8_t s_cfg_desc[] = {    0x09,  /* bLength */    0x02,  /* bDescriptorType 0x02 */    0x20, 0x00, /* wTotalLength */    0x01,       /* bNumInterfaces */    0x01,       /* bConfigurationValue */    0x00,       /* iConfiguration */    0x80,       /* bmAttributes */    0x64,       /* bMaxPower 200mA */
    /* 接口0 */    0x09,                                 /* bLength */    0x04,                                 /* bDescriptorType 0x04*/    0x00,                                 /* bInterfaceNumber */    0x00,                                 /* bAlternateSetting */    0x02,                                 /* bNumEndpoints */    0xff,                                 /* bInterfaceClass */    0xff,                                 /* bInterfaceSubClass */    0x00,                                 /* bInterfaceProtocol */    0x00,                                 /* iInterface */
    /* 端点 */    0x07,                                 /* bLength */    0x05,                                 /* bDescriptorType 0x05*/    0x81,                                 /* bEndpointAddress */    0x02,                                 /* bmAttributes */    0x40, 0x00,                           /* wMaxPacketSize */    0x01,                                 /* bInterval */
    /* 端点 */    0x07,                                 /* bLength */    0x05,                                 /* bDescriptorType 0x05*/    0x02,                                 /* bEndpointAddress */    0x02,                                 /* bmAttributes */    0x40, 0x00,                           /* wMaxPacketSize */    0x01,                                 /* bInterval */};

兼容ID描述符

{  /* Header Sector 16字节头 */  0x28,0,0,0,    /* dwLength: 40    */  0,1,           /* bcdVersion: 1.0 */   4,0,           /* wIndex: 0x04  */  1,             /* bCount: 1     */  0,0,0,0,0,0,0, /* RESERVED: 7 bytes */  /* Function Section 24bytes */  0,             /* bFirstInterfaceNumber: 0 */  1,             /* RESERVED: 1bytes  */   (uint8_t)'W',(uint8_t)'I',(uint8_t)'N',(uint8_t)'U',(uint8_t)'S',(uint8_t)'B',0,0,   /*  compatibleID  */  0,   0,   0,   0,   0,   0, 0, 0,  /* subCompatibleID */   0,   0,   0,   0,   0,   0         /*  RESERVED 6 bytes */};

扩展属性OS特征描述符

static const uint8_t s_extended_properties_os_feature_desc[] = #if 0{    /* 头 10字节  */    0x8E, 0, 0, 0,  /* 长度 length 142 = 132 + 10 byte */    0x00, 0x01,     /* BCD version 1.0 */     0x05, 0x00,     /* Extended Property Descriptor Index(5) */    0x01, 0x00,     /* number of section (1) */    /* 0x84(132) = 50(property section) + 82(property data ) */    /* property section */    0x84, 0x00, 0x00, 0x00,   /* size of property section */    0x1, 0, 0, 0,             /* property data type (1) (REG_SZ) 多个接口0x01写0x07 (REG_MULTI_SZ) */    0x28, 0,                  /* property name length (40) */    'D', 0,    'e', 0,    'v', 0,    'i', 0,    'c', 0,    'e', 0,    'I', 0,    'n', 0,    't', 0,    'e', 0,    'r', 0,    'f', 0,    'a', 0,    'c', 0,    'e', 0,    'G', 0,    'U', 0,    'I', 0,    'D', 0,     0, 0,    /* 82 = 0x4E(78) + 4 */    0x4E, 0, 0, 0,          /* property data length */    '{', 0,    '1', 0,    '3', 0,    'E', 0,    'B', 0,    '3', 0,    '6', 0,    '0', 0,    'B', 0,    '-', 0,    'B', 0,    'C', 0,    '1', 0,    'E', 0,    '-', 0,    '4', 0,    '6', 0,    'C', 0,    'B', 0,    '-', 0,    'A', 0,    'C', 0,    '8', 0,    'B', 0,    '-', 0,    'E', 0,    'F', 0,    '3', 0,    'D', 0,    'A', 0,    '4', 0,    '7', 0,    'B', 0,    '4', 0,    '0', 0,    '6', 0,    '2', 0,    '}', 0,    0, 0,};
#else /* 以下是多个section示例 */{    /* 头 10字节  */    0xE0, 0, 0, 0, /* length 214+10=224(0xE0) byte */     0x00, 0x01,    /* BCD version 1.0 */    0x05, 0x00,    /* Extended Property Descriptor Index(5) */    0x01, 0x00,    /* number of section (1) */    /* 0xD6(214) = 50+2(property section) + 162(property data ) */    /*property section */    0xD6, 0x00, 0x00, 0x00, /* 214 size of property section */    0x7, 0, 0, 0, /*  property data type (1) 多个接口0x01写0x07 (REG_MULTI_SZ) */    0x2a, 0,      /* property name length (42) 注意:比单个接口多2字节 's', 0, */    'D', 0,    'e', 0,    'v', 0,    'i', 0,    'c', 0,    'e', 0,    'I', 0,    'n', 0,    't', 0,    'e', 0,    'r', 0,    'f', 0,    'a', 0,    'c', 0,    'e', 0,    'G', 0,    'U', 0,    'I', 0,    'D', 0,    's', 0, /* 比单个接口这里多了个s */    0, 0,   /* 0x9E(158) = 0x4E(78)x2+2    * 162= 0x9E(158)+4    */    0x9E, 0, 0, 0,  /*  property data length */    '{', 0,    '1', 0,    '3', 0,    'E', 0,    'B', 0,    '3', 0,    '6', 0,    '0', 0,    'B', 0,    '-', 0,    'B', 0,    'C', 0,    '1', 0,    'E', 0,    '-', 0,    '4', 0,    '6', 0,    'C', 0,    'B', 0,    '-', 0,    'A', 0,    'C', 0,    '8', 0,    'B', 0,    '-', 0,    'E', 0,    'F', 0,    '3', 0,    'D', 0,    'A', 0,    '4', 0,    '7', 0,    'B', 0,    '4', 0,    '0', 0,    '6', 0,    '2', 0,    '}', 0,    0, 0, /* 一个结束符间隔 */    '{', 0,    '1', 0,    '3', 0,    'E', 0,    'B', 0,    '3', 0,    '6', 0,    '0', 0,    'B', 0,    '-', 0,    'B', 0,    'C', 0,    '1', 0,    'E', 0,    '-', 0,    '4', 0,    '6', 0,    'C', 0,    'B', 0,    '-', 0,    'A', 0,    'C', 0,    '8', 0,    'B', 0,    '-', 0,    'E', 0,    'F', 0,    '3', 0,    'D', 0,    'A', 0,    '4', 0,    '7', 0,    'B', 0,    '4', 0,    '0', 0,    '6', 0,    '3', 0,    '}', 0,    0, 0,    0, 0, /* 最后以两个结束符结束 */};
#endif

枚举过程如下

(1)获取设备描述符

(2)设置地址

(3)获取设备描述符

(4)获取配置描述符

(5)获取索引0xEEMS OS字符串描述符

(6)获取设备相关的扩展兼容ID OS特征描述符:先获取头确认总长

(7)获取设备相关的扩展兼容ID OS特征描述符:根据前面获取的总长获取全部内容

(8)获取索引0x00的字符串描述符

(9)获取索引2的字符串描述符

(10)获取接口相关的扩展属性OS特征描述符:先获取头确认总长

(11)获取接口相关的扩展属性OS特征描述符:根据前面获取的总长获取全部内容

(12)获取设备描述符

(13)获取配置描述符,先获取9字节的配置描述符头确认总长

(14)根据前面获取的总长,获取完整的配置描述符

(15)获取设备状态

(16)设置配置1

(17)获取索引0的字符串描述符

(18)获取索引1的字符串描述符

(19)获取索引2的字符串描述符

(20)获取索引0的字符串描述符

(21)获取索引1的字符串描述符

(22)获取索引2的字符串描述符

完整的抓包数据见附件

总结

枚举过程比较简单,注意三个WINUSB特有的请求,参考前一篇文章。