原文地址:www.beyondlogic.org/usbnutshell…
原文作者:
发布时间:
设置包
每个USB设备都必须响应默认管道上的设置数据包。设置数据包用于检测和配置设备,并执行常见的功能,如设置USB设备的地址、请求设备描述符或检查端点的状态。
符合USB标准的主机希望所有的请求都能在最多5秒的时间内得到处理。它还为特定请求指定了更严格的时间。
-
没有数据阶段的标准设备请求必须在50ms内完成。
-
有数据阶段的标准设备请求必须在请求后500ms开始返回数据。
- 每个数据包必须在前一个数据包成功传输后500ms内发送。
- 状态阶段必须在最后一个数据包传输后50ms内完成。
-
SetAddress命令(包含数据阶段)必须在50ms内处理命令并返回状态。然后设备在发送下一个请求之前有2ms的时间来改变地址。
这些超时时间段即使对于最慢的设备来说也是相当可以接受的,但在调试过程中可能是一种限制。50mS并不能为异步串行端口上以9600bps的速度发送许多调试字符,也不能为电路内调试器/仿真器提供单步或中断执行以检查内部Registers。因此,USB需要一些不同于其他微控制器项目的调试方法。
随便阅读XP DDK,可以注意到主机控制器驱动程序现在有一个USBUSER_OP_SEND_ONE_PACKET命令,其注释为 "该API用于实现'单步'USB事务开发工具"。虽然这样的工具还没有发布,但我们只能希望尽快看到一个。
每个请求都以一个8字节长的Setup Packet开始,它的格式如下。
| / | 偏移 | 字段 | 大小 | 值 | 说明 |
|---|---|---|---|---|---|
| 0 | bmRequestType | 1 | Bit-Map | 注0 | |
| 1 | bRequest | 1 | 值 | 要求 | |
| 2 | wValue | 2 | 值 | 价值 | |
| 4 | wIndex | 2 | 索引或偏移 | 索引 | |
| 6 | wLength | 2 | 计数 | 如果有数据阶段,要传输的字节数。 |
注0
D7 数据相位传输方向。
0 = 主机到设备
1 = 设备到主机
D6.5 类型
0 = 标准
1 = 班级
2 = 供应商
3 = 保留
D4.0 接受者
0 = 设备
1 = 接口
2 = 端点
3 = 其他
4..31 = 保留
bmRequestType字段将决定请求的方向、请求的类型和指定的接收者。bRequest字段决定了正在进行的请求。bmRequestType通常会被解析并执行到一些处理程序,如标准设备请求处理程序、标准接口请求处理程序、标准端点请求处理程序、类设备请求处理程序等。如何解析设置包完全取决于你的喜好。其他人可能会选择先解析bRequest,然后根据每个请求确定类型和接收者。
标准请求是所有USB设备的通用请求,在接下来的页面中会详细介绍。类请求是驱动程序类的共同请求。例如,所有符合HID类别的设备都有一组共同的类别特定请求。这些请求与符合通信类的设备不同,也与符合大容量存储类的设备不同。
最后是供应商定义的请求。这些请求是您作为USB设备设计者可以分配的。这些请求通常因设备而异,但这完全取决于你的实现和想象力。
一个普通的请求可以指向不同的接收者,并根据接收者执行不同的功能。例如一个GetStatus标准请求,可以指向设备、接口或端点。当指向设备时,它会返回标志,指示远程唤醒的状态以及设备是否自供电。然而,如果同样的请求指向接口,它总是返回零,或者如果指向端点,它将返回端点的停止标志。
wValue和wIndex字段允许参数与请求一起传递。wLength用于指定数据阶段要传输的字节数。
标准请求
USB规范的第9.4节详细说明了每个USB设备需要实现的 "标准设备 "请求。该标准提供了一个单一的表格,按请求项目进行分组。考虑到大多数固件将按接收者解析设置数据包,我们将选择按接收者分解请求,以便于检查和实施。
标准设备请求
目前有8个标准设备请求,详细情况见下表。
| bmRequestType | bRequest | wValue | wIndex | wLength | 数据 |
|---|---|---|---|---|---|
| 1000 0000b | GET_STATUS (0x00) | 零 | 0 | 2 | 设备状态 |
| 0000 0000b | CLEAR_FEATURE (0x01) | 功能选择器 | 0 | 0 | 无。 |
| 0000 0000b | SET_FEATURE (0x03) | 功能选择器 | 0 | 0 | 无。 |
| 0000 0000b | SET_ADDRESS (0x05) | 设备地址 | 0 | 0 | 无。 |
| 1000 0000b | GET_DESCRIPTOR (0x06) | 描述符类型和索引 | 0或语言ID | 描述符长度 | 描述符 |
| 0000 0000b | SET_DESCRIPTOR (0x07) | 描述符类型和索引 | 0或语言ID | 描述符长度 | 描述符 |
| 1000 0000b | GET_CONFIGURATION (0x08) | 零 | 0 | 1 | 配置值 |
| 0000 0000b | SET_CONFIGURATION (0x09) | 配置值 | 0 | 0 | 无 |
- 在数据阶段,针对设备的Get Status请求将返回两个字节,格式如下。
| D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| -> | - | - | - | - | - | 预留 | - | - | - | - | - | <- | 远程 | 唤醒 | 自供电 |
如果D0被设置,则表示设备为自供电。如果为清,则表示设备为总线供电。如果D1被设置,则表示器件启用了远程唤醒,可以在暂停期间唤醒主机。远程唤醒位可以通过SetFeature和ClearFeature请求,特征选择器为DEVICE_REMOTE_WAKEUP(0x01)
-
清除特征和设置特征请求可以用来设置布尔特征。当指定的接收者是设备时,只有DEVICE_REMOTE_WAKEUP和TEST_MODE两个特征选择器可用。测试模式允许设备表现出各种条件。这些在USB规范2.0修订版中有进一步的记载。
-
设置地址在枚举过程中用于为USB设备分配一个唯一的地址。该地址用wValue指定,最大只能是127。该请求是唯一的,因为设备在完成状态阶段后才会设置其地址。(参见控制传输。)所有其他请求必须在状态阶段之前完成。
-
Set Descriptor/Get Descriptor用于返回wValue中指定的描述符。对配置描述符的请求将在一次请求中返回设备描述符和所有接口和端点描述符。
-
Get Configuration/Set Configuration用于请求或设置当前设备配置。在获取配置请求的情况下,在数据阶段将返回一个字节,表示设备状态。零值表示设备未配置,非零值表示设备已配置。设置配置用于启用设备。它应该在wValue的低字节中包含所需配置描述符的bConfigurationValue的值,以选择要启用的配置。
标准接口请求
该规范目前定义了五个标准接口请求,详见下表。有趣的是,只有两个请求做了任何可以理解的事情。
| bmRequestType | bRequest | wValue | wIndex | wLength | 数据 |
|---|---|---|---|---|---|
| 1000 0001b | GET_STATUS (0x00) | 零 | 接口 | 2 | 接口状态 |
| 0000 0001b | CLEAR_FEATURE (0x01) | 功能选择器 | 接口 | 0 | 无 |
| 0000 0001b | SET_FEATURE (0x03) | 功能选择器 | 接口 | 0 | 无 |
| 1000 0001b | GET_INTERFACE (0x0A) | 零 | 接口 | 1 | 备用接口 |
| 0000 0001b | SET_INTERFACE (0x11) | 备用设置 | 接口 | 0 | 无 |
- wIndex通常用来指定指向该接口的请求的引用接口。它的格式如下所示。
| D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 保留 | - | - | - | - | - | - | <- | 接口号 | - | - | - | - | - | - | <- |
-
Get Status用于返回接口的状态。这种对接口的请求应该返回0x00、0x00两个字节。(这两个字节都是保留给将来使用的)
-
清除特性和设置特性请求可用于设置布尔特性。当指定的接收者是接口时,当前的USB Specification Revision 2没有指定接口特征。
标准端点请求
标准端点请求有以下四种。
| bmRequestType | bRequest | wValue | wIndex | wLength | 数据 |
|---|---|---|---|---|---|
| 1000 0010b | GET_STATUS (0x00) | 零 | 端点 | 2 | 端点状态 |
| 0000 0010b | CLEAR_FEATURE (0x01) | 特征选择器 | 端点 | 0 | 无 |
| 0000 0010b | SET_FEATURE (0x03) | 功能选择器 | 端点 | 0 | 无 |
| 1000 0010b | SYNCH_FRAME (0x12) | 零 | 端点 | 2 | 帧号 |
- wIndex字段通常用于指定指向某个端点的请求的引用端点和方向。它的格式如下所示: D15 D14 D13 D12 D11 D10 D8 D7 D6 D5 D4 D3
| D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| -> | - | - | - | 保留 | - | - | <- | Dir | 保留 | 保留 | 保留 | -> | 端点号 | - | <- |
- Get Status返回两个字节,表示端点的状态(Halted/Stalled)。返回的两个字节的格式如下图所示。
| D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| -> | - | - | - | - | - | - | 保留 | - | - | - | - | - | - | <- | 停止 |
-
清除特征和设置特征用于设置端点特征。目前标准定义了一个端点特性选择器ENDPOINT_HALT (0x00),允许主机停滞和清除端点。只有除默认端点以外的端点才建议具有此功能。
-
同步帧请求用于报告端点同步帧。