WinUSB
+ -

使用微软系统描述符2.0制作免驱动自定义USB设备

2022-06-16 17 0
原文转自:http://blog.xtoolbox.org/ms_os_20_descriptor_create_driverless_custom_usb_device/

本文作者XTOOLBOX,本站得到了作者本人的转载授权。

前言

在《使用微软系统描述符1.0制作免驱动自定义USB设备》一文中,介绍了如何使用1.0版本的系统描述符来制作免驱动设备,这里将介绍如何使用2.0版本的系统描述符来制作免驱动设备。无论是1.0还是2.0,都是为了让系统给设备安装WinUSB驱动,并且给接口指定GUID。2.0版本的系统描述符处理流程更加精简一些。2.0不再需要OS字符串描述符,而是使用了USB标准的BOS描述符来获取设备的vendor code。然后再通过一个叫做描述符集的描述符一次性返回所有接口所有配置的compat ID和属性。

BOS描述符

Binary Object Store二进制对象数据描述符,需要设备的bcdUSB大于等于0x0210,在此描述符中上报设备支持的类型。BOS描述符的头是在USB标准中指定。下面描述符中bDeviceCapabilityType为5,在标准中5是保留值,在这里由微软定义为Platform Capability BOS Descriptor,里面包含了uuid,操作系统版本,vendor code信息:

WEAK __ALIGN_BEGIN const uint8_t WINUSB20_WCIDBOS [33] __ALIGN_END = {
  ///////////////////////////////////////
  /// WCID20 BOS descriptor
  ///////////////////////////////////////
  0x05,                                             /* bLength */
  USB_DESC_TYPE_BOS,                                /* bDescriptorType */
  0x21, 0x00,                                       /* wTotalLength */
  0x01,                                             /* bNumDeviceCaps */

  ///////////////////////////////////////
  /// WCID20 device capability descriptor
  ///////////////////////////////////////
  0x1c,                                             /* bLength */
  0x10,                                             /* bDescriptorType */
  0x05,                                             /* bDevCapabilityType */
  0x00,                                             /* bReserved */
  0xdf, 0x60, 0xdd, 0xd8, 0x89, 0x45, 0xc7, 0x4c,   /* bPlatformCapabilityUUID_16 */
  0x9c, 0xd2, 0x65, 0x9d, 0x9e, 0x64, 0x8a, 0x9f,   /* bPlatformCapabilityUUID_16 */
  0x00, 0x00, 0x03, 0x06,                           /* dwWindowsVersion */
  LO_BYTE(WINUSB20_WCID_DESC_SET_SIZE), HI_BYTE(WINUSB20_WCID_DESC_SET_SIZE),/* wDescriptorSetTotalLength */
  WCID_VENDOR_CODE,                                 /* bVendorCode */
  0x00,                                             /* bAltEnumCode */
};

这个描述符的格式固定,在倒数第二个字节指定了vendor code。这个vendor code在后面的请求中会用到。

下图是请求BOS描述符的过程:
154157226999

OS2.0描述符集

Windows系统从BOS描述符中得到设备支持的功能后,通过vendor code请求OS2.0描述符集,这个描述符集会一次性将所有配置的所有接口信息都上报给操作系统。如果只有一个配置的时候,可以省略掉配置子集头。如果只有一个接口,可以省略掉功能子集头。

单配置单接口的OS2.0描述符集如下:

WEAK __ALIGN_BEGIN const uint8_t WINUSB20_WCIDDescriptorSet [162] __ALIGN_END = {
  ///////////////////////////////////////
  /// WCID20 descriptor set descriptor
  ///////////////////////////////////////
  0x0a, 0x00,                                       /* wLength */
  0x00, 0x00,                                       /* wDescriptorType */
  0x00, 0x00, 0x03, 0x06,                           /* dwWindowsVersion */
  0xa2, 0x00,                                       /* wDescriptorSetTotalLength */

  ///////////////////////////////////////
  /// WCID20 compatible ID descriptor
  ///////////////////////////////////////
  0x14, 0x00,                                       /* wLength */
  0x03, 0x00,                                       /* wDescriptorType */
  /* WINUSB */
  'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00,         /* cCID_8 */
  /*  */
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* cSubCID_8 */

  ///////////////////////////////////////
  /// WCID20 registry property descriptor
  ///////////////////////////////////////
  0x84, 0x00,                                       /* wLength */
  0x04, 0x00,                                       /* wDescriptorType */
  0x07, 0x00,                                       /* wPropertyDataType */
  0x2a, 0x00,                                       /* wPropertyNameLength */
  /* DeviceInterfaceGUIDs */
  'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00,       /* wcPropertyName_21 */
  'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00,       /* wcPropertyName_21 */
  't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00,       /* wcPropertyName_21 */
  'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00,       /* wcPropertyName_21 */
  'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00,       /* wcPropertyName_21 */
  0x00, 0x00,                                       /* wcPropertyName_21 */
  0x50, 0x00,                                       /* wPropertyDataLength */
  /* {1D4B2365-4749-48EA-B38A-7C6FDDDD7E26} */
  '{', 0x00, '1', 0x00, 'D', 0x00, '4', 0x00,       /* wcPropertyData_40 */
  'B', 0x00, '2', 0x00, '3', 0x00, '6', 0x00,       /* wcPropertyData_40 */
  '5', 0x00, '-', 0x00, '4', 0x00, '7', 0x00,       /* wcPropertyData_40 */
  '4', 0x00, '9', 0x00, '-', 0x00, '4', 0x00,       /* wcPropertyData_40 */
  '8', 0x00, 'E', 0x00, 'A', 0x00, '-', 0x00,       /* wcPropertyData_40 */
  'B', 0x00, '3', 0x00, '8', 0x00, 'A', 0x00,       /* wcPropertyData_40 */
  '-', 0x00, '7', 0x00, 'C', 0x00, '6', 0x00,       /* wcPropertyData_40 */
  'F', 0x00, 'D', 0x00, 'D', 0x00, 'D', 0x00,       /* wcPropertyData_40 */
  'D', 0x00, '7', 0x00, 'E', 0x00, '2', 0x00,       /* wcPropertyData_40 */
  '6', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00,     /* wcPropertyData_40 */
};

在上面的描述符中,省略掉了配置子集头和功能子集头,在里面直接写入了Compatible ID和注册表属性。如果有多个接口,需要通过功能子集头指定后面的内容属于哪一个接口。

单配置多接口的OS2.0描述符集可以通过在线的描述符生成工具TeenyDT进行查看,选择WinUSB20,点击【==> TeenyUSB .c】生成C语言格式描述符。

下图是请求OS2.0描述符集的过程:
154224982440

从上图可以看到,描述符集并没有像其它描述符那样先取头获得总长度,再取完整的描述符,这是因为在BOS描述符中包含描述符集的长度信息。

使用OS2.0描述符的一些注意事项

当使用OS2.0描述符时,会将bcdUSB设置为0x0210,即USB版本2.1。在此版本下,高速设备的Bulk端点最大包长必须为512,否则会报报告描述符错误。
154239370078

关于bcdUSB = 0x210
这个值说明USB设备的版本号是2.1,实际上并没有任何关于USB 2.1的文档。在《USB 2.0 Link Power Management Addendum》这个文档的第3节中,提到如果要支持BOS描述符,需要将bcdUSB设置为0x201或更高。

在USB3.0的规范文档的9.2.6.6章节中,提到如果要支持BOS描述符,需要bcdUSB大于等于0x210。3.0设备工作在高速模式时会前向兼容2.0,因此这个地方的bcdUSB大于等于0x210对于2.0设备也是有效的。

两个文档中一个是大于等于0x201,一个是大于等于0x210,为了方便兼容,这里就取了较大的那个值0x210,实际上bcdUSB设置为0x201也是可以识别的。

无论这里的bcdUSB取0x210还是0x201,都只是为了说明这个设备支持BOS描述符,用的还是2.0的规范。

参考文档

关于Windows系统上免驱动设备更详细的内容请阅读《使用微软系统描述符1.0制作免驱动自定义USB设备》和《使用微软系统描述符2.0制作免驱动自定义USB设备》

0 篇笔记 写笔记

USB3.2超高速 BOS描述符
USB3.2规范新增加了一个灵活且可扩展的框架,用于描述设备级功能特性。BOS(Binary Device Object Store)是与配置描述符类似的一个根描述符。使用该描述符,可以访问一系列相关描述符的基本描述符。和配置描述符一样,主机通过读取BOS描述符的wTotalLength字段中获......
USB WCID设备中特殊字符描述符
WCID全称”Windows Compatible ID,中文名为“Windows兼容ID”。 WCID设备是一种向Windows系统提供额外信息的USB设备,以便于自动安装驱动程序,并在某些情况下允许立即访问。USB设备驱动的匹配安装一般是以VID/PID进行驱动匹配的,但WCID设备却是根据C......
使用WinUSB读写USB设备
Windows为WinUSB设备提供了API,主要通过以下几个步骤访问设备。通过扩展描述符中的GUID查看接口的路径用接口的路径作为参数,调用CreateFile打开接口使用WinUsb_Initialize得到WinUSB句柄通过WinUsb_WritePipe和WinUsb_ReadPipe对......
使用微软系统描述符1.0制作免驱动自定义USB设备
本文作者XTOOLBOX,本站得到了作者本人的转载授权。本文介绍如何使用微软的操作系统描述符来实现自定义USB设备在Windows系统上的免驱动使用。前言在Linux上开发USB设备是不需要特别的驱动的,Linux内核的USB驱动会将USB设备的基本操作都暴露到应用层,由应用层来完成实际的业......
使用微软系统描述符2.0制作免驱动自定义USB设备
本文作者XTOOLBOX,本站得到了作者本人的转载授权。前言在《使用微软系统描述符1.0制作免驱动自定义USB设备》一文中,介绍了如何使用1.0版本的系统描述符来制作免驱动设备,这里将介绍如何使用2.0版本的系统描述符来制作免驱动设备。无论是1.0还是2.0,都是为了让系统给设备安装WinUS......
简单几步,让自定义USB设备也能免驱动运行
本文作者XTOOLBOX,本站得到了作者本人的转载授权。更完整的说明见《使用微软系统描述符1.0制作免驱动自定义USB设备》和《使用微软系统描述符2.0制作免驱动自定义USB设备》做过USB设备开发的人,对USB中的自定义HID设备一定不陌生。很多时候为了通过USB接口与上位机进行通讯,都会......
作者信息
USB中文网
B站搜索 站长漫谈 看视频。
pnpon内核开网,USB中文网,
busrom硬核技术网站长
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!