Bootstrap

WinUsb实现USB免驱通讯技术总结

随着电脑更新换代、USB接口逐渐替代传统接口(串口等),为了更加方便与PC机进行通讯,引入USB通讯。

  1. 如何才能实现产品与PC又快又稳定通讯
  2. 如何解决串口通讯中接受不定时帧间隔问题
  3. 如何实现即插即用的USB免驱功能

USB免驱我们首先想到的是便是标准类别的USB设备(USB鼠标、键盘、游戏杆等)或者大容量存储(U盘、基于闪存的存储、媒体播放器等)不需要安装驱动程序,因为Windows会在设备第一次插入时自动处理,但HID采用中断类数据传输、传输数据量限制显然不适合大数据量快速通讯。

USB使用USB内部CDC类虚拟串口通讯速度要比我们普通的串口通讯速率要快,但需要安装驱动,有时现场安装环境不同可能出现安装驱动失败问题,造成用户体验度差。

那么有没有既能实现免驱、有能兼容虚拟串口提高通讯速率呢?

答案是肯定的!

WCID是WinUsb设备功能的扩展,由Microsoft在Windows8开发人员预览版期间提出,WinUSB自Windows XP SP2以来一直是Windows一部分的功能。

WinUsb设备是一种通用串行总线(USB)设备,其固件定义了某些Microsoft操作系统(OS)特征描述符,这些描述符将兼容ID报告为"WINUSB"。WinUsb设备的用途是让Windows将Winusb.sys作为设备的功能驱动程序载入,而无需自定义INF文件。对于WinUsb设备,你无须为设备分发INF文件,这大大简化了驱动程序安装过程。截至2012年5月,从Windows Vista开始的所有平台上都提供了自动 WinUSB WCID 驱动程序。在 Windows 8 或更高版本地系统上已经集成了该驱动程序,这意味着Windows 8 或更高版本地系统上不需要安装驱动程序,系统自动会匹配WinUSB驱动,而对于Vista、Windows7、XP系统,可以通过一些第三方软件(如Zadig)来安装或生成WCID版本的驱动程序,同样只需要安装一次WCID版本的驱动软件,以后所有WCID设备都可以使用该驱动,间接实现了免驱

WinUsb限制条件

WinUSB有许多限制条件,一般来说注意以下几点即可:

  1. WinUSB不支持Windows 2003 ( 32bit/64bit )
  2. WinUSB不支持Windows XP 64位(可以通过第三方驱动支持)
  3. USB设备版本必需是2.0或2.0以上,WinUSB不支持USB1.0和1.1

WinUsb的版本支持

  1. Windows 7 在基于 x86、基于 x64 和基于 Itanium 的系统上支持 WinUSB。
  2. 较新版本的 Windows 在基于 x86 和基于 x64 的系统上支持 WinUSB。
  3. WinUSB 支持从 Windows 8 开始支持同步传输

USB全速设备的插入检测

常规USB设备枚举

USB设备插入主机后、会有以下活动:

USB设备连接之后一般枚举过程

  1. §主机(下称H):你是什么设备?
  2. §设备(下称D):12 01 0100……Device Descriptor
  3. § H:你有几种功能?
  4. § D:09 02 09……Configuration Descriptor
  5. § H:每个功能有几个接口?
  6. § D:09 04 00……Interface Descriptor
  7. § H:每个接口使用哪几个端点?
  8. § D:06 05 82……Endpoint Descriptor
  9. § H:好了,我知道你是谁了,开始传输数据吧!
  10.   D:OK,Read Go

WinUsb设备枚举

  1. 当Windows检测到有USB设备插入,首先会向设备索取设备描述符长度,设备正确回复后Windows分配USB设备地址,并以之前收到的实际长度去获取完整的设备描述符。
  2. 获取USB设备信息,包含基本配置、设备接口、端点等信息
  3. Windows判断第一步获取的bcdUSB版本号如果大于等2.0,则还会索引0xEE处的OS字符串描述符,确认设备是否支持WCID,若回复内容为MSFT100则说明该设备支持WCID,后续才会继续获取兼容ID特征描述等
  4. 获取兼容ID特征描述符,回复兼容信息为WinUSB设备
  5. 获取兼容ID后,系统会根据兼容ID的情况请求属性描述符,对于WinUSB设备需要注册设备接口GUID
  6. 后续其他信息获取…

基于STM32F407ZGTX正点原子开发板抓包分析如下:

在线调试:

OS字符串描述符(0xEE获取”MSFT100”)

扩展属性描述符(注册设备接口GUID) 仅在设备第一次枚举被识别到(也可通过修改VID、PID)

扫盲:VID、PID

VID(Vender ID供应商识别码)和PID(Product ID产品识别码)

每一个USB设备都有VID和PID,其中,VID是由供应商向USB-IF(Implementers Forum 应用者论坛)申请。每一个供应商的VID是唯一,PID是由供应商自行决定。

主机通过VID和PID来识别不同的设备,根据他们(以及设备的版本号),可以给设备加载或安装相应的驱动程序。VID和PID的长度都是两个字节

使用Device Monitoring Studio应用层抓包软件抓包如下:

首先获取设备描述符

获取配置描述符

 

根据配置描述符获取接口描述符、输入、输出端点描述符

 

各个描述符的含义

设备描述符(Device Descriptor)

Eg:

Joystick_DeviceDescriptor[ ] =

{

0x12,   /* 整个Descriptor的长度:18字节 */

0x01,   /* Descriptor的类别:Device Descriptor(0x01) */

0x00, 0x02, /* 设备所遵循的USB协议的版本号:2.00 */

0x00,   /* 设备所实现的类:由每个接口描述符描述所实现的类*/

0x00,   /* 设备所实现的子类:由每个接口描述符描述 */

0x00,  /* 设备所遵循的协议类别:由每个接口描述符描述*/

0x40,   /* 端点0的最大数据包长度:64字节*/

0x83, 0x04,  /* IDVendor: 0x0483 (for ST) */

0x10, 0x57,  /* IDProduct: 0x5710 */

0x00, 0x02,  /* bcdDevice: 2.00*/

1,     /* 用于描述生产厂商的字符描述符的索引号 */

2,     /* 用于描述产品的字符描述符的索引号*/

3,     /* 用于描述产品系列号的字符描述符的索引号*/

0x01   /* 设备所支持的配置数目:1*/

}

配置描述符号:

 

Eg:

Joystick_ConfigurationDescriptor[ ] =

0x09, /* 描述符的长度:9字节 */

0x02, /* 描述符的类型: 0x02 配置描述符 */

JOYSTICK_SIZ_CONFIG_DESC, 0x00, /* 完整的描述符包括接口描述符、 端点描述符和类描述符的长度 */

0x01, /* 配置所支持的接口数目:1*/

0x01, /* 用SetConfiguration选择此配置时所指定的配置号*/

0x00, /* 用于描述此配置的字符描述符的索引号:0 */

0xE0, /* 供电配置:B7(1 保留), B6(自供电), B5(远程唤醒), B4-

B0(0 保留) */

0x32, /* 最大功耗,以2mA为单位计算:0x32表示 100mA */

接口描述符:

 

Eg:

Joystick_InterfaceDescriptor[ ] =

0x09, /* 描述符的长度:9字节 */

4, /* 描述符的类型:0x04接口描述符(Interface) */

0x00, /* 选择此接口的索引号,从0开始计算:0 */

0x00, /* 用于选择此设置的索引号:0 */

0x01, /* 实现此接口需要使用的端点数目:1 */

0x03, /* 此接口所遵循的类:HID Class  如果是WinUsb修改为0xFF*/

0x01, /* 此接口所遵循的子类:1=BOOT, 0=no boot */

0x02, /* 此接口所支持的协议:0自定义、1键盘、2鼠标 */

0, /* 用于描述此接口的字符描述符的索引号 */

端点描述符:

 

Eg:

Joystick_InterfaceDescriptor[ ] =

0x07, /* 描述符长度:7字节 */

5, /* 描述符类型:端点描述符*/

0x81, /* 端点的特性:B3-B0(端点号), B6-B4(0), B7(1=IN, 0=OUT)

0x81:Endpoint1/ IN */

0x03, /* 端点的类型:B1-B0(00=控制 01=同步 10=大容量 11=中断)

0x03:中断端点 */

0x04, 0x00 /* 此端点的最大有效数据长度:4 字节 */

0x20, /* 主机查询此端点数据的间隔时间:(1ms或125us单位):

0x20:32 ms */

各种传输特性比较

 

USB HID采用中断方式

FS最大速率62.5KB/s  最大一包64字节  

LS 800B/S            最大一包8字节

WinUsb采用Bulk传输

FS 最大速率800KB/s 最大一包64字节   传输受硬件影响

数据拆包接收发送规则:

 

STM32、GD32芯片数据接收数据采用分包接收,每包数据64字节。

数据发送库函数优化掉,不需要特别关心分包发送。

USB数据同步

计算机管理->通用串行总线设备->WinUsb

注意点:

  1. 上位机在扫描WinUsb设备名称时,会过滤‘-’字符串,导致识别失败,故WinUsb设备名称禁止出现‘-’
  2. 接口描述符中bIntergaceClasss字段必须给0xFF  否则上位机报错

参考:

WinUsb实现USB免驱通讯介绍_嵌入式小娄的博客-CSDN博客

STM32 WinUSB(WCID)免驱高速通信 20M/s(附详细测试)_bingwueyi的博客-CSDN博客

WinUSB 简介 - USB中文网

https://www.cnblogs.com/yanye0xff/p/16710614.html

GD32移植WinUsb 成功例程如下:

https://download.csdn.net/download/qq_35257512/87838361?spm=1001.2014.3001.5503

STM32移植WinUsb成功例程如下:

https://download.csdn.net/download/qq_35257512/87755345?spm=1001.2014.3001.5503
 

;