可以真正实现免驱的WinUSB设备

为什么要使用WinUSB设备?

  1. 如果您现在需要开发一款设备需要与PC通信,用USB接口是个不错的选择。每个USB设备在PC主机上都有对应的一个驱动程序,Windows操作系统为常用标准USB设备类型(如HID设备类、USB接口打印机、优盘等)提供了对应的驱动程序,但如果您开发的USB设备不是标准设备类,那么使用微软WinUSB将是个不错的选择。我们平常见得最多的就是USB_HID类型的USB,但是HID类型适合鼠标、键盘等传输速率比较小的设备,如果你需要传输大量数据并且传输速率要比USB_HID快,同时也能实现免驱的话,不妨试试WinUSB。
  2. Windows USB (WinUSB) 是 Microsoft 提供的 USB 设备的通用驱动程序。WinUSB由两部分组成,分别是winusb.sys和winusb.dll。Winusb.sys 是一种内核模式驱动程序,可在 USB 设备的内核模式设备堆栈的协议驱动程序之上作为筛选器驱动程序或功能驱动程序进行安装。Winusb.dll 是一种公开 WinUSB 功能的用户模式 DLL。当 Winusb.sys 作为设备的功能驱动程序安装后,应用程序可以使用这些功能与其进行通信。
  3. Microsoft 提供了 Winusb.inf,其中包含将Winusb.sys 作为 USB 设备的设备驱动程序安装所需的信息。如果你的系统是windows 7,那么你需要自己你需要提供自定义 INF。自定义 INF 指定设备特定的硬件 ID,同时包括内置 Winusb.inf 的部分。这些部分是实例化服务、复制内置二进制文件以及注册设备接口 GUID(应用程序查找设备和与设备通讯必须使用 GUID)所必需的。在枚举成功之后进行驱动更新的时候,选择包含自定义inf的文件夹即可(如下)。但是如果你的系统是windows 7以上系统,你就不必提供inf文件,因为 Microsoft已经替你准备好了,你只需要在更新驱动时选择“浏览我的电脑以获取驱动程序软件”—》选择“让我从计算机上的设备驱动程序列表中选择” —》从设备类别列表中,选择通用串行总线设备—》向导显示WinUsb设备,选择它以加载驱动程序即可。自定义inf文件实例(windows 7系统用):
; ================ Version section =================
 
[Version]
Signature="$Windows NT$"
Class=USB
ClassGuid={88bae032-5a81-49f0-bc3d-a4ff138216d6}
Provider = %ProviderName%
DriverVer = 12/04/2012, 0.2.0.0

; ========== Manufacturer/Models sections =========== 

[Manufacturer]
%ProviderName% = MyWinUSBDevice,NTx86,NTamd64

[MyWinUSBDevice.NTx86]
%DeviceDesc%=USB_Install, USB\VID_0483&PID_5750

[MyWinUSBDevice.NTamd64]
%DeviceDesc%=USB_Install, USB\VID_0483&PID_5750
; ================== Installation ==================
[ClassInstall]
AddReg=ClassAddReg

[ClassInstall32]
AddReg=ClassAddReg

[ClassAddReg]
HKR,,,,"%ClassName%"
HKR,,Icon,,-28

[USB_Install]
Include = WinUSB.inf 
Needs = WinUSB.NT 

[USB_Install.Services]
Include = WinUSB.inf
AddService = WinUSB, 0x00000002, WinUSB_ServiceInstall

[WinUSB_ServiceInstall]
DisplayName     = %WinUSB_SvcDesc%
ServiceType     = 1
StartType       = 3
ErrorControl    = 1
ServiceBinary   = %12%\WinUSB.sys

[USB_Install.Wdf]
KmdfService = WinUSB, WinUSB_Install

[WinUSB_Install]
KmdfLibraryVersion = 1.11

[USB_Install.HW]
AddReg = Dev_AddReg

[Dev_AddReg]
HKR,,DeviceInterfaceGUIDs,0x00010000,"{745a17a0-74d3-11d0-b6fe-00a0c90f57da}"

[USB_Install.CoInstallers]
AddReg = CoInstallers_AddReg
CopyFiles = CoInstallers_CopyFiles

[CoInstallers_AddReg]
HKR, , CoInstallers32, 0x00010000, "WinUSBCoInstaller2.dll","WdfCoInstaller01009.dll, WdfCoInstaller"

[CoInstallers_CopyFiles]
WinUSBCoInstaller2.dll
WdfCoInstaller01009.dll


[SourceDisksNames]
1 = %MediaDescription%
 
[SourceDisksFiles]
WinUSBCoInstaller2.dll = 1, x86
WdfCoInstaller01009.dll = 1, x86

 
[SourceDisksFiles.amd64]
WinUSBCoInstaller2.dll = 1, amd64
WdfCoInstaller01009.dll = 1, amd64
 
[DestinationDirs]
CoInstallers_CopyFiles = 11

; ==================== Strings =====================
[Strings]
ProviderName="YMSG Software"

DeviceDesc="MY WINUSB"
MediaDescription  = "USB MY WINUSB Disc"
WinUSB_SvcDesc = "WinUSB Driver Service"

USB设备的枚举过程

要想让设备被识别为WinUSB设备,首先得先让设备被识别成为USB设备(USB设备的枚举过程)如果在枚举过程中出错,我们就很难判断出错误在哪里,这里推荐大家使用bus hound(大家可以自己去网上下载)来进行抓包分析。这里是我自己抓包结果:

Bus Hound 6.00 capture on Windows Vista (x64). Complements of www.perisoft.net

  Device - Device ID (followed by the endpoint for USB devices)
            (31) STM32 WINUSB
            (32) STM32 WINUSB
            (33) STM32 WINUSB
  Length - Total transfer length
  Phase  - Phase Type
            CTL   USB control transfer       
            IN    Data in transfer           
            URB   USB request block          
  Data   - Hex dump of the data transferred
  Descr  - Description of the phase
  Cmd... - Position in the captured data


Device  Length    Phase  Data                                                Description       Cmd.Phase.Ofs(rep)
------  --------  -----  --------------------------------------------------  ----------------  ------------------
  33.0            CTL    80 06 00 01  00 00 12 00                            GET DESCRIPTOR           1.1.0        
  33.0        18  IN     12 01 00 02  00 00 00 40  83 04 50 57  00 02 01 02  .......@..PW....         1.2.0        
                         03 01                                               ..                       1.2.16       
  33.0            URB    88 00 08 00  00 00 00 00  98 53 19 84  f1 69 00 00  CONTROL TRANSFER         1.3.0        
                         00 00 00 00  45 00 47 00  b0 cc cb 7a  0e 96 ff ff                           1.3.16       
                         5b 00 5c 00  12 00 00 00  b0 53 51 6f  0e 96 ff ff                           1.3.32       
                         00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00                           1.3.48       
  33.0            CTL    80 06 00 01  00 00 12 00                            GET DESCRIPTOR           2.1.0        
  33.0        18  IN     12 01 00 02  00 00 00 40  83 04 50 57  00 02 01 02  .......@..PW....         2.2.0        
                         03 01                                               ..                       2.2.16       
  33.0            URB    88 00 08 00  00 00 00 00  98 53 19 84  f1 69 00 00  CONTROL TRANSFER         2.3.0        
                         00 00 00 00  00 00 00 00  b0 cc cb 7a  0e 96 ff ff                           2.3.16       
                         0b 00 00 00  12 00 00 00  68 3b 14 7c  0e 96 ff ff                           2.3.32       
                         00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00                           2.3.48       
  33.0            CTL    80 06 00 02  00 00 09 00                            GET DESCRIPTOR           3.1.0        
  33.0         9  IN     09 02 20 00  01 01 04 c0  32                        .. .....2                3.2.0        
  33.0            URB    88 00 08 00  00 00 00 00  98 53 19 84  f1 69 00 00  CONTROL TRANSFER         3.3.0        
                         00 00 00 00  00 00 00 00  b0 cc cb 7a  0e 96 ff ff                           3.3.16       
                         0b 00 00 00  09 00 00 00  10 71 4c 73  89 ce ff ff                           3.3.32       
                         00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00                           3.3.48       
  33.0            CTL    80 06 00 02  00 00 20 00                            GET DESCRIPTOR           4.1.0        
  33.0        32  IN     09 02 20 00  01 01 04 c0  32 09 04 00  00 02 ff 00  .. .....2.......         4.2.0        
                         00 00 07 05  01 02 40 00  00 07 05 81  02 40 00 00  ......@......@..         4.2.16       
  33.0            URB    88 00 08 00  00 00 00 00  98 53 19 84  f1 69 00 00  CONTROL TRANSFER         4.3.0        
                         00 00 00 00  00 00 00 00  b0 cc cb 7a  0e 96 ff ff                           4.3.16       
                         0b 00 00 00  20 00 00 00  90 b7 e4 82  0e 96 ff ff                           4.3.32       
                         00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00                           4.3.48       
  33.0            CTL    80 00 00 00  00 00 02 00                            GET STATUS               5.1.0        
  33.0         2  IN     01 00                                               ..                       5.2.0        
  33.0            URB    88 00 08 00  00 00 00 00  98 53 19 84  f1 69 00 00  CONTROL TRANSFER         5.3.0        
                         00 00 00 00  00 00 00 00  b0 cc cb 7a  0e 96 ff ff                           5.3.16       
                         0b 00 00 00  02 00 00 00  d0 6e 4c 73  89 ce ff ff                           5.3.32       
                         00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00                           5.3.48       
  33.0            CTL    00 09 01 00  00 00 00 00                            SET CONFIG               6.1.0        
  33.0            URB    70 00 00 00  00 00 00 00  98 53 19 84  f1 69 00 00  SELECT CONFIG            6.2.0        
                         00 00 00 00  00 00 00 00  90 b7 e4 82  0e 96 ff ff                           6.2.16       
                         30 cc df 7d  0e 96 ff ff  48 00 00 00  ff 00 00 00                           6.2.32       
                         e0 9b 30 7f  0e 96 ff ff  02 00 00 00  00 00 00 00                           6.2.48       
  33.0            CTL    80 06 00 02  00 00 09 00                            GET DESCRIPTOR           7.1.0        
  33.0         9  IN     09 02 20 00  01 01 04 c0  32                        .. .....2                7.2.0        
  33.0            URB    88 00 08 00  00 00 00 00  98 53 19 84  f1 69 00 00  CONTROL TRANSFER         7.3.0        
                         00 00 00 00  00 00 00 00  b0 cc cb 7a  0e 96 ff ff                           7.3.16       
                         0b 00 00 00  09 00 00 00  40 1b 2e 83  0e 96 ff ff                           7.3.32       
                         00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00                           7.3.48       
  33.0            CTL    80 06 00 02  00 00 20 00                            GET DESCRIPTOR           8.1.0        
  33.0        32  IN     09 02 20 00  01 01 04 c0  32 09 04 00  00 02 ff 00  .. .....2.......         8.2.0        
                         00 00 07 05  01 02 40 00  00 07 05 81  02 40 00 00  ......@......@..         8.2.16       
  33.0            URB    88 00 08 00  00 00 00 00  98 53 19 84  f1 69 00 00  CONTROL TRANSFER         8.3.0        
                         00 00 00 00  00 00 00 00  b0 cc cb 7a  0e 96 ff ff                           8.3.16       
                         0b 00 00 00  20 00 00 00  40 1b 2e 83  0e 96 ff ff                           8.3.32       
                         00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00                           8.3.48       

其中对于各种描述符的配置,大家可以参考这里

如何让一个USB设备被识别为WinUSB设备?

在成功识别为USB设备之后, 若要将 USB 设备标识为 WinUSB 设备,设备固件必须具有这些 Microsoft OS 描述符。

1.支持 OS 字符串描述符
为了让 USB 驱动程序堆栈了解设备支持扩展的特征描述符,设备必须定义存储在字符串索引 0xEE 处的 OS 字符串描述符。在枚举过程中,驱动程序堆栈查询字符串描述符。如果存在描述符,驱动程序堆栈会假定设备包含一个或多个OS 特征描述符和检索这些特征描述符所需要的数据。检索的字符串描述符具有 bMS_VendorCode 字段值。该值表示 USB 驱动程序堆栈必须用来检索扩展特征描述符的供应商代码。

#define bMS_VendorCode              ( 0x01 )
// "MSFT100" : index : 0xEE : langId : 0x0000
const U8 OS_StringDescritpor[ ] =
{ 0x12,  0x03,  'M',  0,  'S',  0,  'F',  0,  'T',  0,  '1',  0,  '0',  0,  '0',  0,  bMS_VendorCode,  0 };

2.设置兼容 ID 特征描述符
匹配内置 Winusb.inf 和加载 WinUSB 驱动程序模块所需要的扩展兼容 ID OS 特征描述符。扩展兼容 ID OS 特征描述符包含紧跟一个或多个功能部分的标题部分,具体取决于是否是复合设备。标题部分指定整个描述符的长度、功能部分的数量以及版本号。对于非复合设备,标题后紧跟一个仅与设备的接口关联的功能部分。该部分的 compatibleID 字段必须指定 “WINUSB” 作为字段值。复合设备有多个功能部分。每个功能部分的 compatibleID 字段必须指定 “WINUSB”。

// "WINUSB\0\0" : wIndex : 0x0004
const U8 WINUSB_ExtendedCompatId_Descritpor[ ] =
{
  0x28, 0x00, 0x00, 0x00,                         // dwLength
  0x00, 0x01,                                     // bcdVersion
  0x04, 0x00,                                     // wIndex
  0x01,                                           // bCount
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // Reserved[7]
  0x00,                                           // bFirstInterfaceNumber
  0x01,                                           // RESERVED ( 0x01 )
  'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00,       // compactiableID[8]
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // subCompactiableID[8]
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00              // Reserved[6]
};

3.注册设备接口 GUID
注册设备接口 GUID 所需要的扩展属性 OS 特征描述符。需要使用 GUID 从应用程序或服务查找设备、配置设备以及执行 I/O 操作。在以前版本的 Windows 中,设备接口 GUID 注册通过自定义 INF 完成。从 Windows 8 开始,你的设备应使用扩展属性 OS 特征描述符报告接口 GUID。

// L"DeviceInterfaceGUID" : wIndex = 0x0005
// L"{12345678-1234-1234-1234-123456789ABC}"(可以换自己的GUID)
const U8 WINUSB_ExtendedProperty_InterfaceGUID_Descritpor[ ] =
{
  0x8E, 0x00, 0x00, 0x00,     // dwTotalSize = Header + All sections
  0x00, 0x01,                 // bcdVersion
  0x05, 0x00,                 // wIndex
  0x01, 0x00,                 // wCount
  
  0x84, 0x00, 0x00, 0x00,     // dwSize -- this section
  
  0x01, 0x00, 0x00, 0x00,     // dwPropertyDataType
  
  0x28, 0x00,                 // wPropertyNameLength
  
  'D', 0x00, 'e', 0x00,       // bProperytName : WCHAR : L"DeviceInterfaceGUID"
  'v', 0x00, 'i', 0x00,       // bProperytName : WCHAR
  'c', 0x00, 'e', 0x00,       // bProperytName : WCHAR
  'I', 0x00, 'n', 0x00,       // bProperytName : WCHAR
  't', 0x00, 'e', 0x00,       // bProperytName : WCHAR
  'r', 0x00, 'f', 0x00,       // bProperytName : WCHAR
  'a', 0x00, 'c', 0x00,       // bProperytName : WCHAR
  'e', 0x00, 'G', 0x00,       // bProperytName : WCHAR
  'U', 0x00, 'I', 0x00,       // bProperytName : WCHAR
  'D', 0x00, 0x00, 0x00,      // bProperytName : WCHAR
  
  0x4E, 0x00, 0x00, 0x00,     // dwPropertyDataLength : 78 Bytes = 0x0000004E
  
  '{', 0x00, '1', 0x00,       // bPropertyData : WCHAR : L"{12345678-1234-1234-1234-123456789ABC}"
  '2', 0x00, '3', 0x00,       // bPropertyData
  '4', 0x00, '5', 0x00,       // bPropertyData
  '6', 0x00, '7', 0x00,       // bPropertyData
  '8', 0x00, '-', 0x00,       // bPropertyData
  '1', 0x00, '2', 0x00,       // bPropertyData
  '3', 0x00, '4', 0x00,       // bPropertyData
  '-', 0x00, '1', 0x00,       // bPropertyData
  '3', 0x00, '4', 0x00,       // bPropertyData
  '4', 0x00, '-', 0x00,       // bPropertyData
  '1', 0x00, '2', 0x00,       // bPropertyData
  '3', 0x00, '4', 0x00,       // bPropertyData
  '-', 0x00, '1', 0x00,       // bPropertyData
  '2', 0x00, '3', 0x00,       // bPropertyData
  '4', 0x00, '5', 0x00,       // bPropertyData
  '6', 0x00, '7', 0x00,       // bPropertyData
  '8', 0x00, '9', 0x00,       // bPropertyData
  'A', 0x00, 'B', 0x00,       // bPropertyData
  'C', 0x00, '}', 0x00,       // bPropertyData
  0x00, 0x00                  // bPropertyData
};

WinUSB设备枚举成功后如何挂载驱动

                       WinUSB设备驱动挂载流程
                       
一、在windows 10系统上:
1.将WinUSB设备插入主机系统。
2.打开设备管理器并找到WinUSB设备。
3.选择并按住(或右键单击)WinUSB设备,然后从上下文菜单中选择“更新驱动程序软件... ”。
4.在向导中,选择“浏览我的电脑以获取驱动程序软件”。
5.选择“让我从计算机上的设备驱动程序列表中选择” 。
6.从设备类别列表中,选择通用串行总线设备。
7.向导显示WinUsb设备。选择它以加载驱动程序。

二、在windows 7系统上(找到Windows 7 Driver文件夹位置):
1.将WinUSB设备插入主机系统。
2.打开设备管理器并找到WinUSB设备。
3.选择并按住(或右键单击)WinUSB设备,然后从上下文菜单中选择“更新驱动程序软件... ”。
4.在向导中,选择“浏览我的电脑以获取驱动程序软件”。
5.选择文件夹Windows 7 Driver。
6.点击下一步。
7.选择“始终安装此驱动软件程序“。
8.加载驱动成功。

如何确定WinUSB设备驱动挂载成功

1.在”通用串行总线设备“下面可以看到枚举成功的”STM32 WINUSB“:
在
2.在”常规“里可以看到如下结果:
在这里插入图片描述
3.在”驱动程序“里可以看到如下结果:在这里插入图片描述
4.在”详细信息“里的”设备描述“可以看到如下结果:在这里插入图片描述
推荐网站:
1.https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/winusb-installation
2.https://blog.csdn.net/weixin_34081595/article/details/85552321

说到最后

这是我作为实习生去公司后自己独自一人搞了两个月(目前还在搞),从不熟悉usb协议到最后WinUSB枚举成功,其中的难度对我来说还是很大的,因为网上WinUSB的资料确实不是很多(也可能我没有找到),只能自己慢慢摸索,每次碰壁之后我都会回去看看usb最基础的协议,总能给我启发。但是成功之后的喜悦也是无可比拟的。最后也希望这篇文章能对大家有所帮助,如果有什么问题也希望大家指出来,共同交流。

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值