从零开始学USB(十六、标准的USB请求)

时间:2024-03-26 18:41:11

所有USB设备都响应设备默认控制管道上主机的请求。 这些请求是使用控制传输进行的。 请求和请求的参数将在Setup数据包中发送到设备。 主机负责建立表9-2中列出的字段中传递的值。 每个Setup数据包都有8个字节

从零开始学USB(十六、标准的USB请求)

 

一、bmRequestType(向谁请求)

D7:传输方向

  • 0 = 主机至设备;
  • 1 = 设备至主机;

D6..5:命令类型

  • D6D5=00:标准请求命令; 
  • D6D5=01:类请求命令;
  • D6D5=10:用户定义命令;
  • D6D5=11:保留。

D4..0:接受者类型

  • 0=设备;
  • 1=接口;
  • 2=端点;
  • 3=其它
  • 4..31 保留

这个域表明此请求的特性。特别地,这个域表明了第二阶段控制传输方向。如果wLength域被设作0的话,表明没有数据传送阶段,那Direction位就会被忽略.

USB说明定义了一系列所有设备必须支持的标准请求。这些请求见下面的表。另外,一个设备类可定义更多的请求。设备厂商也可定义设备支持的请求.

请求可被导引到设备,设备接口,或某一个设备端结点(endpoint)上。这个请求域也指定了接收者。当指定的是接口或端结点(endpoint)时,wIndex域指出那个接口或端节点。

二、bmRequest(什么请求)

这个域标识特别的请求。bmRequestType域的Type字段可修改此域的含义。协议中仅定义Type 字段为0即标准设备请求时bRequest域值的含义。

三、 wValue域

此域用来传送当前请求的参数,随请求不同而变。

四、 wIndex域

该字段的内容根据请求而有所不同。它用于将参数传递给设备,特定于请求。

当bmRequestType的Recipient字段为接口或端点时,wIndex域用来表明是哪一个接口或端结。

图9-2显示了用于指定端点时的wIndex格式。
从零开始学USB(十六、标准的USB请求)

Direction位(bit7)设置为零以指示具有指定端点编号的OUT端点,并指定一个以指示IN端点。 对于控制管道,请求应将Direction位设置为零,但设备可以接受Direction位的任一值。

图9-3显示了用于指定接口时的wIndex格式.

从零开始学USB(十六、标准的USB请求)

五、 wLength域

这个域表明第二阶段的数据传输长度。传输方向由bmRequstType域的Direction位指出。wLength域为0则表明无数据传输。在输入请求下,设备返回的数据长度不应多于wLength,但可以少于。在输出请求下,wLength指出主机发出的确切数据量。如果主机发送多于wLength的数据,设备做出的响应是无定义的。

 

六、标准设备请求

本节介绍为所有USB设备定义的标准设备请求。 表9-3概述了标准设备请求,而表9-4和表9-5分别给出了标准请求代码和描述符类型。
USB设备必须响应标准设备请求,即使设备尚未分配地址或尚未配置。

从零开始学USB(十六、标准的USB请求)

七、标准请求码(bRequest的值)

从零开始学USB(十六、标准的USB请求)

八、 描述符类型

从零开始学USB(十六、标准的USB请求)

 

下面说明几种常见的设备请求

1.清除特性(clear Feature)

该请求时用来取消一个特性,其格式如下:

从零开始学USB(十六、标准的USB请求)

该请求中的wVlaue表示特性选择器,它对应的值为:0 = 端点,1 = 设备。当某个特点不允许取消,或者特性根本不存在,或者是指向一个根本不存在的接口或端点时,该请求将会导致设备请求失败,如果一个端点被固件设置为停止状态,主机软件也可以发送一个值为0的CLEAR_FEATURE命令清除该端点的停止状态。

2.获得描述符(GetDescriptor)

该请求可以获得USB设备中存在的特定的描述符,其格式如下:

从零开始学USB(十六、标准的USB请求)

该请求中的wValue的高字节表示要取的设备描述符,低字节表示描述符的索引值,描述的类型见上面9-5表。

wIndex的值为0或语言ID;当要取的值为字符串描述符时,该域的值为语言ID;当为其它的描述符时,该域为0。

wLength表示要返回的数据长度,如果SETUP阶段的地址使用的是预设地址0,(ENDP字段为0),这时wLength值会大于实际的描述的值。这是为什么? 原因是哟用户预设的地址0来取得设备描述符时,不管多少个字节,用户最多只能取前8个字节,即在控制传输过程只有一次数据阶段。但是,如果用户新的地址(ENDP字段不为0)来取得设备描述符时。这时wLength的值就要注意了。

3.设置地址(SetAddress)

该请求给USB设备设备值地址,从而可以对该USB设备进行下一步的访问,其格式如下:

从零开始学USB(十六、标准的USB请求)

该请求与其他请求有一个重要的不同点,该请求下,USB设备一直不改变它的地址,直到该请求的状态阶段被 成功的完成,而其他请求的操作都是在状态阶段之前完成。

4.设置配置(SetConfiguration)

该请求对设备进行设备值。其格式如下:

从零开始学USB(十六、标准的USB请求)

该请求中的wValue域的低字节表示设置的值,该值必须为0或者与配置描述符中的配置值相匹配。如果设置值等于0,表示设备在地址状态。如果wIndex或wLength为非0值,那么该请求不执行。

5.获得接口(GetInterface)

此请求返回指定接口的选定备用设置。

从零开始学USB(十六、标准的USB请求)

某些USB设备的配置具有互斥设置的接口。 此请求允许主机确定当前选择的备用设置。
如果wValue或wLength不是上面指定的,则不指定设备行为。如果指定的接口不存在,则设备将响应请求错误。

  • 默认状态:未指定在设备处于“默认”状态时收到此请求时的设备行为。
  • 地址状态:设备给出了请求错误响应。
  • 已配置状态:当设备处于已配置状态时,这是一个有效请求

 

6.获得状态(Get State)

从零开始学USB(十六、标准的USB请求)

bmRequestType字段的Recipient位指定所需的收件人。 返回的数据是指定收件人的当前状态。
如果wValue或wLength不是上面指定的,或者如果设备状态请求的wIndex不为零,则不指定设备的行为。

如果指定的接口或端点不存在,则设备将响应请求错误。

  • 默认状态:未指定在设备处于“默认”状态时收到此请求时的设备行为。
  • 地址状态:如果指定了端点0以外的接口或端点,则设备将响应请求错误。
  • 已配置状态:如果指定了不存在的接口或端点,则设备将响应请求错误。

 

设备的GetStatus()请求返回如图9-4所示的信息.

从零开始学USB(十六、标准的USB请求)

自供电字段指示设备当前是否为自供电。 如果D0复位为零,则器件由总线供电。 如果D0设置为1,则设备是自供电的。 SetFeature()或ClearFeature()请求不能更改Self Powered字段。
“远程唤醒”字段指示设备当前是否已启用以请求远程唤醒。 禁用支持远程唤醒的设备的默认模式。 如果D1复位为零,则禁用设备发出远程唤醒信号的能力。 如果D1设置为1,则启用设备发出远程唤醒信号的能力。 可以使用DEVICE_REMOTE_WAKEUP功能选择器通过SetFeature()和ClearFeature()请求修改远程唤醒字段。 器件复位时,该字段复位为零。

 

接口的GetStatus()请求返回如图9-5所示的信息。

从零开始学USB(十六、标准的USB请求)

 

端点的GetStatus()请求返回如图9-6所示的信息。

从零开始学USB(十六、标准的USB请求)

需要为所有中断和批量端点类型实现暂停功能。如果端点当前已暂停,则“暂停”功能将设置为1。否则,暂停功能将重置为零。可以选择使用SetFeature(ENDPOINT_HALT)请求设置暂停功能。当由SetFeature()请求设置时,端点表现出相同的停顿行为,就好像该字段已由硬件条件设置一样。如果导致暂停的条件已被删除,则通过ClearFeature(ENDPOINT_HALT)请求清除暂停功能会导致端点不再返回STALL。对于使用数据切换的端点,无论端点是否具有暂停功能集,ClearFeature(ENDPOINT_HALT)请求始终会导致数据切换重新初始化为DATA0。即使请求的配置或接口与当前配置或接口相同,Halt功能也会在SetConfiguration()或SetInterface()请求后重置为零。

既不要求也不建议为默认控制管道实现暂停功能。 但是,设备可以设置默认控制管道的暂停功能,以反映功能错误情况。 如果该功能设置为1,则设备将在每个标准请求的数据和状态阶段将STALL返回到管道,但GetStatus(),SetFeature()和ClearFeature()请求除外。 对于特定于类的特定于供应商的请求,设备无需返回STALL。

 

 

结合上面的格式我们分析一下下面的SETUP令牌事务的作用。

从零开始学USB(十六、标准的USB请求)

结合前面的学习,我们知道了,host发给device的数据SETUP数据是HEX: 80 06 00 01 00 00 40 00

 

第一个字节0x80拆分可以得到,这是一个主机发给设备(bit0~bit4)的一个标准(bit5~bit6)的请求命令,请求的结果是要求设备给Host返回(bit7 == 1)

第二个字节0x06查看表9-4可以得到这是一个GET_DESCRIPTOR,即获取描述符 的请求。

第三四自己传的是0x0100 ,查看描述符表,得知高字节表示描述符类型,01表示设备,02表示配置;低字节表示索引。比如设备有多个配置,那需要读取不同配置的时候就通过低字节。或者一个配置下有多个接口,通过索引选择不同的接口。所以这里高字节的1代表 设备,低字节在本设备没用到。

第四五字节为0x0,这个参数如果为0,则不关心;如果为非零,则表示Langurage ID,每一位都有对应的意义。

第六七字节为0x40,即代表返回的数据不应该多于64字节。


从零开始学USB(十六、标准的USB请求)

分析总结:该SETUP事务为主机获取从机的设备描述符。

 

接下来再看一个例子:

从零开始学USB(十六、标准的USB请求)

结合前面的学习,我们知道了,host发给device的数据SETUP数据是HEX: 00 05 03 00 00 00 00 00 

第一个字节0x0,这是一个主机发给设备(bit0~bit4)的一个标准(bit5~bit6)的请求命令,请求的结果是主机和设备发送(bit7 == 0)信息。

第二个字节0x05,从table 9-4可以看到,SET_ADDRESS,主机给从机设置地址

第三四个字节合起来是0x03,对照标准的设备请求表,可以知道,这是就是主机给设备分配的设备地址3

第五六字节合起来是0x0,从标准的设备请求表可以看到,这里没任何作用,只是为了满足标准的SETUP令牌请求格式。

第七八字节同上。

从零开始学USB(十六、标准的USB请求)

分析总结:该请求为,主机给设备设置从机地址为3

 

接下来看最后一个例子:

从零开始学USB(十六、标准的USB请求)

结合前面的学习,我们知道了,host发给device的数据SETUP数据是HEX: 80 06 02 03 09 04 FF 00 

第一个字节0x0,这是一个主机发给设备(bit0~bit4)的一个标准(bit5~bit6)的请求命令,请求的结果是设备给Host返回(bit7 == 1)信息。

第二个字节0x06,从table 9-4可以看到,Get_DESCRIPTOR,主机获取从机描述符

第三四个字节合起来是0x03 02,对照标准的设备请求表,可以知道,这是就是主机请求获取设备的字符串描述符,且为第二个索引。

第五六字节合起来是0x04 09,对照标准的设备请求表,可以知道,这里是指定字符串描述符的语言ID

第七八字节合起来是0xFF,表示即代表返回的字符串长度不应该多于255个字节

 

从零开始学USB(十六、标准的USB请求)

分析总结:该请求为主机获取设备的字符串描述符

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
    原文链接:https://blog.csdn.net/qq_16777851/article/details/85715436