USB协议
USB的标准
目前USB的标准有USB1.0、USB1.1、USB2.0、USB3.0、USB3.1。
- USB1.0:低速,1.5Mbps
- USB1.1: 全速,12Mbps
- USB2.0: 高速,480Mbps,USB 2.0中的“增强主机控制器接口”定义了一个与USB 1.1相兼容的架构。它可以用USB 2.0的驱动程序驱动USB 1.1设备。也就是说,所有支持USB 1.1的设备都可以直接在USB 2.0的接口上使用而不必担心兼容性问题
- USB3.0: 超速,5Gbps,也有叫3.1 Gen1的,而USB3.1被称为3.1 Gen2
- USB3.1: 超速+,10Gbps
USB的接口规范
USB的接口规范有Type A,Type B,Type C
转存失败重新上传取消
另外,还有Mini接口
转存失败重新上传取消
和Micro接口
转存失败重新上传取消
如果是USB3.0以上的版本,常见的Micro接口信号线不够,所以会看到这样的Micro口
转存失败重新上传取消
USB协议和USB接口规范并不是一一对应的,比如Type-C广泛应用于USB3.0,但是也是可以用在USB2.0的。
USB的电气特性
识别设备的速度模式 对于设备(Device)而言,按照速度来划分,工作在低速模式下的设备称之为低速设备;工作在全速模式下的设备称之为全速设备;同理,工作在高速模式下的设备称之为高速设备。 对于主机(Host)而言,只有全速主机和高速主机两种。
识别低速和全速设备 主机的D+和D-都接有15K下拉电阻;全速USB设备的数据线D+接有1.5K的上拉电阻,一旦接入主机,主机的D+被拉高;低速USB设备的数据线D-接有1.5K的上拉电阻,一旦接入主机,主机的D-会被拉高。因此,主机就可以根据检测到自己的D+为高还是D-为高,从而判断接入的设备是一个全速还是低速设备。硬件结构图如下:
转存失败重新上传取消
转存失败重新上传取消
识别高速设备 刚开始时,高速设备以全速模式连接到主机,D+有上拉电阻。主机检测到全速设备连接上之后,对设备进行复位,USB设备收到复位信号,主动发起高速模式的握手协议进行速度识别。接下来,就取决于主机端了,如果主机的USB控制器支持高速模式传输,则主机会与该高速设备交互完成高速模式握手协议,之后,两者都工作在高速模式下;如果主机不支持高速模式传输(如果主机上没有EHCI类型的控制器,像比较老旧的电脑,并且是XP系统的),那么握手协议就会失败,设备端也不会切换到高速模式,之后两者都工作在全速模式下。 如果是一个全速设备接到高速主机,设备端没法发起高速握手协议,所以,最终设备和主机都会工作在全速模式下。主机具有多种控制器类型,能工作在全速/高速模式下。 全速和高速控制器,都是DP上拉,低速才是DM上拉(配置寄存器的时候,需要注意的地方)。
USB设备的识别
一套完整的USB设备有USB主机,USB HUB(可选的),USB从机,主机为电脑。USB主机通过D+上有没有上拉电阻判断是否为高速设备或全速设备,而D-上有上拉电则阻判断为低速设备。
当USB主机检测到D+或D-上从低电平转为高电平,USB主机会开始读取USB从机的描述符信息,这个过程称为枚举过程。USB主机通过枚举过程得知USB从机是什么类型的设备,如何进行通信等。枚举是一个非常重要的过程,枚举成功了基本上USB通信就算完成一大半。
USB的描述符
描述符是一组和USB主设备约定好格式和意义的数据(USB驱动可以约定这些含义)。下图是USB2.0规范中规定的8种描述符。描述符随具体的设备不同而不同。
转存失败重新上传取消
USB Device
参考 :
-
《windows驱动开发技术详解》--- 第17章 USB设备驱动
-
USB Device应用笔记(基于STM32F103) https://blog.csdn.net/mr_bean_1031/article/details/75944777
常见USB设备类
USB视频类(UVC),音频类(Audio),通信设备类(CDC),设备固件升级类(DFU),人机接口类(HID),大容量存储设备类(Mass Storage)。
USB设备中有一大类就是HID设备,即Human Interface Devices,人机接口设备。这类设备包括鼠标、键盘等,主要用于人与计算机进行交互。它是USB协议最早支持的一种设备类。HID设备可以作为低速、 全速、高速设备用。由于HID设备要求用户输入能得到及时响应,故其传输方式通常采用中断方式。 在USB协议中,HID设备的定义放置在接口描述符中,USB的设备描述符和配置描述符中不包含HID设备的信息。因此,对于某些特定的HID设备,可以定义多个接口,只有其中一个接口为HID设备类即可。
-
HID设备简述
-
1.1HID设备的特点
- 交换的数据储存在称为报表(Report ) 的结构内, 设备的固件必须支持HlD 报表的格式。 主机通过控制和中断传输中的传送和请求报表来传送和接收数据。报表的格式非常灵活。
- 每一笔事务可以携带小量或中量的数据。低速设备每一笔事务最大是8B ,全速设备每一笔事务最大是64B, 高速设备每一笔事务最大是1024B 。 一个报表可以使用多笔事务。
- 设备可以在未预期的时间传送信息给主机,例如键盘的按键或是鼠标的移动。所以主机会定时轮询设备,以取得最新的数据。
- HID 设备的最大传输速度有限制。主机可以保证低速的中断端点每10ms 内最多 1笔事务,每一秒最多是 800B 。保证全速端点每 lms 一笔事务,每一秒最多是64000B 。保证高速端点每 125 us 三笔事务,每一秒最多是 24.576MB 。
- HID 设备没有保证的传输速率。如果设备是设置在 10ms 的时距,事务之间的时间可能等于或小于 10ms 。除非设备是设置在全速时在每个帧传输数据,或是在高速时在每个微帧传输数据。这是最快的轮询速率,所以端点可以保证有正确的带宽可供使用
-
USB通信流程
USB的连接模式是Host和Devcie的连接模式,它不同于早期的串口和并口,所有的请求必须是Host向Device发出,这就使Host瑞设计相对复杂,而Device端设计相对简单。Host 端会在主板的南桥设计好,而Devic的厂商众多,厂商只需要遵循USB协议,重点精力可以放在设备的研发上,而与PC的通信不用过多考虑。
USB四种传输类型
用于描述端点(Endpoint)或通道(Pipe)的特性
-
中断传输事务(Interrupt Transfer)
- 在USB设备中,有种处理机制类似于PCI中断的机制,这就是中断事务。中断事务数据量很小,一般用于通知Host某个事件的来临。例如USB鼠标,鼠标移动或者鼠标单机等操作都会通过中断管道来想Host传送事件。在中断事务中,也分为三个阶段,即令牌阶段、数据传送阶段、握手阶段。
-
控制传输事务(Control Transfer)
- 控制传输是负责想USB设置一些控制信息,传递这种事务的管道是控制管道。在每个USB设备中都会有控制管道。控制传输分为三个阶段,即令牌阶段、数据传送阶段、握手阶段。
-
同步传输事务(Isochronous Transfer)
- 这种事务能保证传输的同步性。例如在USB摄像头传输视频数据的时候会采用这种事务,这种事务能保证每秒有固定的传输量,与Bulk传输不同,它允许有一定的误码率,这样符合视频会议等传输需求的,因为视频会议首先包保证实时性,在一定条件下,允许有一定的误码率。同步传输事务只有两个阶段,即令牌阶段、数据传送阶段,因为不关心数据的正确性,故没有握手阶段。
-
批量传输事务(Bulk Transfer)
- 这种事务传输主要是大块的数据,传递这种事务的管道叫做Bulk管道。这种事务传输的时候分为三个部分。第一部分是Host端发出一个Buik的令牌请求,如果令牌是IN请求则是从Device到Host的请求,如果是OUT令牌,则是从Host端到Device端的请求。
同步传输与中断传输是周期性的,控制传输和批量传输是突发的
中断传输的端点,每个帧(1ms)最多只能传输一次;而批量传输则可以在一个帧内安排多次传输。
事务(Transaction)分类:SETUP, OUT, IN
转存失败重新上传取消
描述符(Descriptor)分类
- 设备描述符(Device Descriptor)
- 配置描述符(Configuration Descriptor)
- 接口描述符(Interface Descriptor)
- 端点描述符(Endpoint Descriptor)
- 字符描述符(String Descriptor)
- 报告描述符(Report Descriptor)
转存失败重新上传取消
windows中的USB
在Windows上开发USB驱动相对来说比较简单,主要是因为微软已经提供了完备的USB总线驱动,程序员编写的设备驱动只需调用总线驱动即可。在Windows上还有一-些工具软件可以帮助开发者查看USB的各类信息,包括设备描述符、配置描述符等。当然,这些描述符在驱动中也会用到。
转存失败重新上传取消
1.1 USB设备请求:USB的请求是通过控制管道传输的,请求是8个字节,按照如表17-1所示的排列发送。
偏移量 | 变量 | 大小 | 数值 | 描述 |
---|---|---|---|---|
0 | bmRequestType | 1字节 | 位图 | 第七位:数据方向位 0=主机到设备 1=设备到主机。第6-5位:类型 0=标准 1=类 2=厂商自定义 3=保留 |
第4-0位:接受者 0=对设备的请求 1=对接口的请求 2=对管道(端点)的请求 4=其他 | ||||
1 | bRequest | 1字节 | 数值 | 请求类别 |
2 | wValue | 2字节 | 数值 | 不同请求含义不同 |
4 | wIndex | 2字节 | 数值 | 不同请求含义不同 |
6 | wLength | 2字节 | 数值 | 表示需要有多少数据返回 |
其中,bRequest代表不同的USB请求,他们分别是一下集中请求,定义在DDk的usb100.h文件中
1
//
2
// USB 1.1: 9.4 Standard Device Requests, Table 9-4. Standard Request Codes
3
// USB 2.0: 9.4 Standard Device Requests, Table 9-4. Standard Request Codes
4
//
5
#define USB_REQUEST_GET_STATUS 0x00
6
#define USB_REQUEST_CLEAR_FEATURE 0x01
7
#define USB_REQUEST_SET_FEATURE 0x03
8
#define USB_REQUEST_SET_ADDRESS 0x05
9
#define USB_REQUEST_GET_DESCRIPTOR 0x06
10
#define USB_REQUEST_SET_DESCRIPTOR 0x07
11
#define USB_REQUEST_GET_CONFIGURATION 0x08
12
#define USB_REQUEST_SET_CONFIGURATION 0x09
13
#define USB_REQUEST_GET_INTERFACE 0x0A
14
#define USB_REQUEST_SET_INTERFACE 0x0B
15
#define USB_REQUEST_SYNC_FRAME 0x0C
16
17
#define USB_REQUEST_GET_FIRMWARE_STATUS 0x1A
18
#define USB_REQUEST_SET_FIRMWARE_STATUS 0x1B
1.2 设备描述符
转存失败重新上传取消
1.2 配置描述符
转存失败重新上传取消
1.2 接口描述符
转存失败重新上传取消
1.2 端点描述符
转存失败重新上传取消
设备枚举为winusb设备
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设备都可以使用该驱动,间接实现了免驱。
在WCID之前,只有标准类别的USB设备,如HID(USB键盘、鼠标、游戏杆等)或大容量存储(U盘、基于闪存的存储、媒体播放器等)不需要安装驱动程序,因为Windows会在设备第一次插入时自动处理。而其他设备通常需要自己手动提供和安装驱动程序,在WIN8以后厂家自己提供的驱动程序还可能受到微软的驱动程序签名限制,造成不必要的麻烦。
1.2 、WinUSB有许多限制条件
- WinUSB 不支持 Windows 2003 ( 32bit/64bit )
- WinUSB 不支持 Windows XP 64 位(官方不支持 64 位 Windows XP)
- WinUSB 不能用于向USB 设备发送实际的复位命令。这是 WinUSB 的限制。
- WinUSB 不支持同步传输。
- WinUSB 不能用于设置与第一个不同的设备配置 。这是 KMDF USB I/O Target 的限制。
- WinUSB 不支持多个并发应用程序
- WinUSB 不支持USB 1.0 或 USB 1.1
如果 USB 设备描述符的 bcdUSB 字段等于 0x0100
或 0x0110
,集线器驱动程序将跳过对 MS OS 描述符的查询并移动到“序列号字符串描述符查询”状态
1.3 、什么是 WCID?
- WCID 设备(其中 WCID 代表“Windows 兼容 ID”)是一种 USB 设备,可为 Windows 系统提供额外信息,以便于自动安装驱动程序,并在某些情况下允许立即访问。
- WCID 允许 Windows 应用程序几乎只要插入设备就可以使用它,这与通常的情况相反,即既不是 HID 也不是海量存储的 USB 设备需要最终用户执行手动驱动程序安装。因此,WCID 可以将 HID 和大容量存储的“即插即用”功能带到任何 USB 设备(具有 WCID 感知固件)。
- WCID 是 WinUSB Device 功能的扩展,由 Microsoft 在 Windows 8 Developer Preview 期间提出。但是,它使用自 Windows XP SP2 以来已成为 Windows 一部分的功能(Microsoft OS 描述符或 MOD)。
- 自 2012 年 5 月起,从 Windows Vista 开始的所有平台都提供了自动 WinUSB WCID 驱动程序。在 Windows 8 上,它是系统自带的(即无需在线获取驱动程序),而对于 Vista 和 Windows 7,它将通过 Windows 更新从 Internet 获得。
1.4 、WinUSB 架构和模块
如何使用 WinUSB 与 USB 设备 (USBDevice) 通信
-
Windows USB (WinUSB) 是 Microsoft 提供的 USB 设备的通用驱动程序。
-
WinUSB 体系结构由内核模式驱动程序 (Winusb.sys) 和用户模式动态链接库 (Winusb.dll) 组成。
- Winusb.sys 是一种内核模式驱动程序,可在 USB 设备的内核模式设备堆栈的协议驱动程序之上作为筛选器驱动程序或功能驱动程序进行安装。
- Winusb.dll 是一种公开 WinUSB 功能的用户模式 DLL。当 Winusb.sys 作为设备的功能驱动程序安装后,应用程序可以使用这些功能与其进行通信。
-
对于不要求自定义功能驱动程序的设备,Winusb.sys 可以在该设备的内核模式堆栈中作为功能驱动程序进行安装。随后,用户模式流程通过使用一组设备 I/O 控制请求或调用 WinUSB 功能 ( WinUsb_Xxx 函数 )来与 Winusb.sys 进行通信。
1
例程 说明
2
WinUsb_Initialize 为文件句柄指定的设备创建 WinUSB句柄。
3
WinUsb_Free 释放 WinUsb_Initialize 分配的所有资源。
4
WinUsb_ControlTransfer 通过默认控制端点传输控制数据。
5
WinUsb_ReadPipe 从指定管道读取数据。
6
WinUsb_WritePipe 将数据写入管道。
7
WinUsb_GetOverlappedResult 检索对指定文件的重叠操作的结果。
8
WinUsb_ResetPipe 重置数据切换并清除管道上的停顿情况。
9
WinUsb_AbortPipe 中止管道的所有挂起传输。
10
WinUsb_FlushPipe 丢弃缓存在管道中的任何数据。
11
WinUsb_QueryPipe 检索有关与接口关联的管道的信息。
12
WinUsb_QueryDeviceInformation 检索有关与 WinUSB 句柄关联的物理设备的信息。
13
WinUsb_GetDescriptor 获取请求的描述符。
14
WinUsb_GetAssociatedInterface 检索关联接口的句柄。
15
WinUsb_QueryInterfaceSettings 检索特定接口句柄 的指定备用接口设置的接口描述符。
16
WinUsb_GetCurrentAlternateSetting获取接口的当前备用接口设置。
17
WinUsb_SetCurrentAlternateSetting 设置一个备用设置界面。
18
WinUsb_GetPowerPolicy 获取设备的电源策略。
19
WinUsb_SetPowerPolicy 设置设备的电源策略。
20
WinUsb_GetPipePolicy 获取特定管道(端点)的策略。
21
WinUsb_SetPipePolicy为特定管道(端点)设置策略。
1.5、什么是 WinUSB 设备
- WinUSB 设备是一种通用串行总线 (USB) 设备,其 固件 定义了某些 Microsoft 操作系统 (OS) 特征描述符,这些描述符将兼容 ID 报告为 "WINUSB"。
- WinUSB 设备的用途是让 Windows 将 Winusb.sys 作为设备的功能驱动程序载入,而无需自定义 INF 文件。对于 WinUSB 设备,你无须为设备分发 INF 文件,对最终用户而言,这大大简化了驱动程序安装过程。相反,如果你需要提供自定义 INF,则不应将设备定义为 WinUSB 设备和在 INF 中指定设备的硬件 ID。
- Microsoft 提供了 Winusb.inf,其中包含将 Winusb.sys 作为 USB 设备的设备驱动程序安装所需的信息。
- 在 Windows 8 之前,要将 Winusb.sys 作为功能驱动程序加载,你需要提供自定义 INF。自定义 INF 指定设备特定的硬件 ID,同时包括内置 Winusb.inf 的部分。这些部分是实例化服务、复制内置二进制文件以及注册设备接口 GUID(应用程序查找设备和与设备通讯必须使用 GUID)所必需的。有关编写自定义 INF 的信息,请参阅 WinUSB (Winusb.sys) 安装。
- 在 Windows 8 中,内置 Winusb.inf 文件经过更新后可让 Windows 自动将 INF 与 WinUSB 设备匹配。
1.6、如何配置 WinUSB 设备
- USB 设备在固件中存储设备、设备接口和端点的标准描述符。
- 哪些 Windows 版本支持 Microsoft OS 描述符?
1
描述符 Windows 版本
2
OS 字符串描述符 Windows XP SP1 及更高版本
3
扩展兼容 ID OS 功能描述符 Windows XP SP2 及更高版本
4
扩展属性 OS 功能描述符 Windows XP SP2 及更高版本
5
Genre OS 功能描述符 可能受未来的 Windows 版本支持
- 若要将 USB 设备标识为 WinUSB 设备,设备固件必须具有这些 Microsoft OS 描述符。
1)支持 OS 字符串描述符
为了让 USB 驱动程序堆栈了解设备支持扩展的特征描述符,设备必须定义存储在字符串索引 0xEE 处的 OS 字符串描述符。在枚举过程中,驱动程序堆栈查询字符串描述符。如果存在描述符,驱动程序堆栈会假定设备包含一个或多个OS 特征描述符和检索这些特征描述符所需要的数据。
检索的字符串描述符具有 bMS_VendorCode 字段值。该值表示 USB 驱动程序堆栈必须用来检索扩展特征描述符的供应商代码。
1
#define bMS_VendorCode ( 0x01 )
2
// “MSFT100”:索引:0xEE:langId:0x0000
3
const U8 OS_StringDescritpor[ ] =
4
{ 0x12 , 0x03 , ' M ' , 0 , ' S ' , 0 , ' F ' , 0 , ' T ' , 0 , ' 1 ' , 0 , ' 0 ' , 0 , ' 0 ' , 0 , bMS_VendorCode , 0 };
为什么必须将 OS 字符串描述符存储在索引 0xEE 上?
一台支持 Microsoft OS 描述符的设备必须包含一个 OS 字符串描述符,存储在字符串索引 0xEE 位置。该 OS 字符串描述符是一个标准的 USB 字符串描述符,具有以下功能: . 其存在表明该设备包含一个或多个 OS 功能描述符。 . 它包含检索相关的 OS 功能描述符所需的数据。 . 它包含一个签名字段,该字段可将 OS 字符串描述符和其他 IHV 可能选择存储在 0xEE 的字符串别开来。 . 它包含一个允许未来修改 Microsoft OS 描述符的版本号。
2)设置兼容 ID 特征描述符
匹配内置 Winusb.inf 和加载 WinUSB 驱动程序模块所需要的扩展兼容 ID OS 特征描述符。
扩展兼容 ID OS 特征描述符包含紧跟一个或多个功能部分的标题部分,具体取决于是否是复合设备。标题部分指定整个描述符的长度、功能部分的数量以及版本号。
对于非复合设备,标题后紧跟一个仅与设备的接口关联的功能部分。该部分的 compatibleID 字段必须指定 "WINUSB" 作为字段值。
复合设备有多个功能部分。每个功能部分的 compatibleID 字段必须指定 "WINUSB"。
1
// "WINUSB\0\0" : wIndex : 0x0004
2
const U8 WINUSB_ExtendedCompatId_Descritpor[ ] =
3
{
4
0x28, 0x00, 0x00, 0x00, // dwLength
5
0x00, 0x01, // bcdVersion
6
0x04, 0x00, // wIndex
7
0x01, // bCount
8
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reserved[7]
9
0x00, // bFirstInterfaceNumber
10
0x01, // RESERVED ( 0x01 )
11
'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, // compactiableID[8]
12
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // subCompactiableID[8]
13
0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Reserved[6]
14
};
3)注册设备接口 GUID
注册设备接口 GUID 所需要的扩展属性 OS 特征描述符。需要使用 GUID 从应用程序或服务查找设备、配置设备以及执行 I/O 操作。在以前版本的 Windows 中,设备接口 GUID 注册通过自定义 INF 完成。从 Windows 8 开始,你的设备应使用扩展属性 OS 特征描述符报告接口 GUID。
扩展属性 OS 特征描述符包含紧跟一个或多个自定义属性部分的标题部分。标题部分描述整个扩展属性描述符,包含其总长度、版本号以及自定义属性部分的数量。若要注册设备接口 GUID,使用 GUID 生成唯一的设备接口 GUID, 请添加将
bPropertyName 字段设置为 "DeviceInterfaceGUID" 且将 wPropertyNameLength 设置为 40 字节的自定义属性部分。bPropertyData 字段设置为该 GUID,如 "{8FE6D4D7-49DD-41E7-9486-49AFC6BFE475}"。
注意,GUID 指定为 Unicode 字符串,且字符串长度为 78 字节(包括 Null 终止符)。在设备枚举过程中,USB 驱动程序堆栈随后从扩展属性 OS 特征描述符检索 DeviceInterfaceGUID 值,并在设备硬件注册表项中注册设备。应用程序通过使用 SetupDiXxx API 检索该值。
1
// L"DeviceInterfaceGUID" : wIndex = 0x0005
2
// L"{12345678-1234-1234-1234-123456789ABC}"
3
const U8 WINUSB_ExtendedProperty_InterfaceGUID_Descritpor[ ] =
4
{
5
0x8E, 0x00, 0x00, 0x00, // dwTotalSize = Header + All sections
6
0x00, 0x01, // bcdVersion
7
0x05, 0x00, // wIndex
8
0x01, 0x00, // wCount
9
10
0x84, 0x00, 0x00, 0x00, // dwSize -- this section
11
12
0x01, 0x00, 0x00, 0x00, // dwPropertyDataType
13
14
0x28, 0x00, // wPropertyNameLength
15
16
'D', 0x00, 'e', 0x00, // bProperytName : WCHAR : L"DeviceInterfaceGUID"
17
'v', 0x00, 'i', 0x00, // bProperytName : WCHAR
18
'c', 0x00, 'e', 0x00, // bProperytName : WCHAR
19
'I', 0x00, 'n', 0x00, // bProperytName : WCHAR
20
't', 0x00, 'e', 0x00, // bProperytName : WCHAR
21
'r', 0x00, 'f', 0x00, // bProperytName : WCHAR
22
'a', 0x00, 'c', 0x00, // bProperytName : WCHAR
23
'e', 0x00, 'G', 0x00, // bProperytName : WCHAR
24
'U', 0x00, 'I', 0x00, // bProperytName : WCHAR
25
'D', 0x00, 0x00, 0x00, // bProperytName : WCHAR
26
27
0x4E, 0x00, 0x00, 0x00, // dwPropertyDataLength : 78 Bytes = 0x0000004E
28
29
'{', 0x00, '1', 0x00, // bPropertyData : WCHAR : L"{12345678-1234-1234-1234-123456789ABC}"
30
'2', 0x00, '3', 0x00, // bPropertyData
31
'4', 0x00, '5', 0x00, // bPropertyData
32
'6', 0x00, '7', 0x00, // bPropertyData
33
'8', 0x00, '-', 0x00, // bPropertyData
34
'1', 0x00, '2', 0x00, // bPropertyData
35
'3', 0x00, '4', 0x00, // bPropertyData
36
'-', 0x00, '1', 0x00, // bPropertyData
37
'3', 0x00, '4', 0x00, // bPropertyData
38
'4', 0x00, '-', 0x00, // bPropertyData
39
'1', 0x00, '2', 0x00, // bPropertyData
40
'3', 0x00, '4', 0x00, // bPropertyData
41
'-', 0x00, '1', 0x00, // bPropertyData
42
'2', 0x00, '3', 0x00, // bPropertyData
43
'4', 0x00, '5', 0x00, // bPropertyData
44
'6', 0x00, '7', 0x00, // bPropertyData
45
'8', 0x00, '9', 0x00, // bPropertyData
46
'A', 0x00, 'B', 0x00, // bPropertyData
47
'C', 0x00, '}', 0x00, // bPropertyData
48
0x00, 0x00 // bPropertyData
49
};
在枚举过程中,USB 驱动程序堆栈会读取扩展属性特征描述符并在该项下创建注册表项。
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Enum\USB<Device Identifier><Instance Identifier>\Device Parameters
DeviceInterfaceGUID : {12345678-1234-1344-1234-123456789ABC}
转存失败重新上传取消
-
启用或禁用 WinUSB 电源管理功能
在 Windows 8 之前,要配置 WinUSB 的电源管理功能,你必须在自定义 INF 的 HW.AddReg 部分中编写注册表项值。在 Windows 8 中,你可以在设备中指定电源设置。你可以通过扩展属性 OS 特征描述符报告值,从而为该设备启用或禁用 WinUSB 中的功能。可配置的功能有两个:选择性挂起和系统唤醒。
选择性挂起允许设备在闲置时进入低能耗状态。系统唤醒是指在系统处于低能耗状态时,设备唤醒系统的功能。
属性名 | 描述 |
---|---|
DeviceIdleEnabled | 此值设置为 1 表示设备在闲置时可关闭(选择性挂起)。 |
DefaultIdleState | 此值设置为 1 表示设备在闲置时可挂起(默认情况下)。 |
DefaultIdleTimeout | 此值设置为 5000 毫秒表示确定设备处于闲置状态所需等待的毫秒时长。 |
UserSetDeviceIdleEnabled | 此值设置为 1 允许用户控制设备启用或禁用 USB 选择性挂起的功能。设备“电源管理”属性页面上的复选框“允许计算机关闭此设备以节约电源”,用户可选中或取消选中该复选框以启用或禁用 USB 选择性挂起。 |
SystemWakeEnabled | 此值设置为 1 允许用户控制设备从低能耗状态唤醒系统的功能。如果启用,“允许此设备唤醒计算机”复选框将显示在设备电源管理属性页面中。用户可选中或取消选中此复选框以启用或禁用 USB 系统唤醒。 |
例如,要在设备上启用选择性挂起,请添加一个自定义属性部分,将 bPropertyName 字段设置为 Unicode 字符串,并将 "DeviceIdleEnabled" 和 wPropertyNameLength 设置为 36 字节。 将 bPropertyData 字段设置为 "0x00000001"。这些属性值会存储为 little-endian 32 位整数。
在枚举过程中,USB 驱动程序堆栈会读取扩展属性特征描述符并在该项下创建注册表项HKEY_LOCAL_MACHINE\System\CurrentControlSet\Enum\USB<Device Identifier><Instance Identifier>\Device Parameters
DeviceIdleEnabled : 0x00000001
- 成功枚举 USB Device
正在上传…重新上传取消
正在上传…重新上传取消
本实例采用STM32f103c6t6实现WinUSB设备,使用STM32CubeIDE生成基础工程,STM32CubeIDE版本号为1.5.0,STM32F4 package版本为1.26.2,电脑系统为WIN10。
学习参考:
STM32 WinUSB(WCID)免驱高速通信 20M/s(附详细测试)https://blog.csdn.net/bingwueyi/article/details/121622001
基于STM32F103的USB学习笔记1 - USB基础知识 https://blog.csdn.net/pq113_6/article/details/105939805
Windows与自定义USB HID设备通信说明. https://recomm.cnblogs.com/blogpost/3026394
WINUSB STM32移植参考 https://blog.csdn.net/wandersky0822/article/details/120729844
USB协议架构及驱动架构 https://blog.csdn.net/MyArrow/article/details/8279156
设备枚举为HID设备
HID设备描述符
https://blog.csdn.net/qq_34870909/article/details/78928893
-
HID协议与这些描述符之间的关系。
当插入USB设备后,主机会向设备请求各种描述符来识别设备。
为了把一个设备识别为HID类别,设备在定义描述符的时候必须遵守HID规范。
正在上传…重新上传取消
从框图中,可以看出除了USB标准定义的一些描述符外,HID设备还必须定义HID描述符。另外设备和主机的通信是通过报告的形式来实现的,所以还必须定义报告描述符;而物理描述符不是必需的。还有就是HID描述符是关联于接口(而不是端点)的,所以设备不需要为每个端点都提供一个HID描述符。
接口描述符中bInterfaceClass的值必须为0x03,bInterfaceSubClass的值为0或1,为1表示HID设备符是一个启动设备(Boot Device,一般对PC机而言才有意义,意思是BIOS启动时能识别并使用您的HID设备,且只有标准鼠标或键盘类设备才能成为Boot Device。如果为0则只有在操作系统启动后才能识别并使用您的HID设备)。
USB HID类描述符的结构 | ||||
---|---|---|---|---|
偏移量 | 域 | 大小 | 值 | 描述 |
0 | bLength | 1 | 数字 | 此描述符的长度(以字节为单位) |
1 | bDescriptorType | 1 | 常量 | 描述符种类(此处为0x21即HID类描述符) |
2 | bcdHID | 2 | 数字 | HID规范版本号(BCD码),采用4个16进制的BCD格式编码,如版本1.0的BCD码为0x0100,版本为1.1的BCD码为0x0110 |
4 | bCountryCode | 1 | 数字 | 硬件目的国家的识别码(BCD码)(见表3) |
5 | bNumDescritors | 1 | 数字 | 支持的附属描述符数目 |
6 | bDescriptorType | 1 | 常量 | HID相关描述符的类型0x21:HID描述符0x22:报告描述符0x23:物理描述符 |
7 | wDescriptorLength | 2 | 数字 | 报告描述符总长度 |
9 | bDescriptorType | 1 | 常量 | 用于识别描述符类型的常量,使用在有一个以上描述符的设备 |
10 | wDescriptorLength | 2 | 数字 | 描述符总长度,使用在有一个以上描述符的设备 |
报告描述符
报告描述符比较复杂,它是以item形式排列组合而成,无固定长途,用户可以自定义长度以及每一bit的含义
- HID设备6种特定请求
HID类请求(命令)包格式 | |||
---|---|---|---|
偏移量 | 域 | 大小 | 说明 |
0 | bmRequestType | 1 | HID设备类请求特性如下: 位7: 0=从USB HOST到USB设备 1=从USB设备到USB HOST 位6~5: 01=请求类型为设备类请求 位4~0: 0001=请求对象为接口(interface)因而,针对HID的设备类请求,仅仅10100001和00100001有效 |
1 | bRequest | 1 | HID类请求(参考下表) |
2 | wValue | 2 | 高字节说明描述符的类型0x21:HID描述符0x22:报告描述符0x23:物理描述符低字节为非0值时被用来选定实体描述符。 |
4 | wIndex | 2 | 2字节数值,根据不同的bRequest有不同的意义 |
6 | wLength | 2 | 该请求的数据段长度 |
- GET_REPORT:主机通过控制端点获取一个Report
域 | 值 | 描述 |
---|---|---|
bmRequestType | 0xA1 | |
bRequest | 0x01 | |
wValue | 高字节表示报告类型0x01:input0x02:output0x03:featureother:reserved低字节表示ReportID,如不使用设为0 | |
wIndex | HID的interface索引值 | |
wLength | Report长度 | |
Data | Report内容 |
- SET_REPORT:主机发送一个Report给设备,用以设置input,output或者feature
域 | 值 | 描述 |
---|---|---|
bmRequestType | 0x21 | |
bRequest | 0x09 | |
wValue | 高字节表示报告类型0x01:input0x02:output0x03:featureother:reserved低字节表示ReportID,如不使用设为0 | |
wIndex | HID的interface索引值 | |
wLength | Report长度 | |
Data | Report内容 |