前面学习了那么多的概念,这里需要记住一点分层概念即设备 ---> 配置 ---> 接口 ---> 端点,这种分层的概念结构 。 也可以理解为端点构成接口,接口组成配置,配置组成设备。
USB设备的枚举过程
前面说过了,USB只是一种串行通信总线。也就是说USB是一种物理通信通道。但是实际中我们使用了各种各样的USB设备,如U盘,鼠标、键盘等。这些设备都是使用USB总线和主机(PC)进行通信的,但是主机却可以区分不同的设备,这里靠的就是,前面定义的描述符。当我们将USB设备接入主机后主机很快就能知道设备的属性并为其安装对应的驱动,其实在这之前,设备已经和主机进行了很多次数据交换了,这个过程就是枚举。开始了解枚举之前还有明白一个规则,每个USB设备都至少有一个端点即0,这个端点就是USB的控制端点,用来USB设备自己和主机主机间“协商”交换数据用。如端点地址 0x00表示控制输出端点地址,0x80表示控制输入地址。接下来看枚举过程:
以上的这些过程都是使用的USB控制传输。
以上过程忽略了一个概念,就是USB标准请求,即获取描述符是怎么告诉设备的,也有一套标准通信规则如下表:
bRequest的命令码表
具体的请求命令帧组成,可以查阅USB标准文档。这里拿一个不完整的设备枚举过程展示一下设备的枚举过程,数据使用BusHound 软件抓包得到的。
//获取设备描述符 CTL 80 06 00 01 00 00 12 00 //设备返回设备描述符 IN 12 01 00 02 00 00 00 40 93 39 16 14 00 02 01 02 03 01 //先获取设备配置描述符的前9个字节 == 获取知配置描述符的总长度 CTL 80 06 00 02 00 00 09 00 //设备返回配置描述符的前9个字节 == 得知配置描述符的总长度为0x29(41个字节) IN 09 02 29 00 01 01 00 c0 64 //获取全部配置描述符 CTL 80 06 00 02 00 00 29 00 //设备返回全部配置描述符其中还包括接口配置描述符和断点配置描述符(因为是HID设备还有一个HID设备配置描述符) IN 09 02 29 00 01 01 00 c0 64 09 04 00 00 02 03 00 00 00 09 21 10 01 00 01 22 21 00 07 05 81 03 40 00 01 07 05 01 03 40 00 01 //设置配置值,配置描述符中有一个位置就是配置这个值的 CTL 00 09 01 00 00 00 00 00 //获取接口 CTL 21 0a 00 00 00 00 00 00 //获取HID设备配置描述符 CTL 81 06 00 22 00 00 61 00 //设备返回全部HID设备报告配置描述符 IN 05 8c 09 01 a1 01 09 03 15 00 26 00 ff 75 08 95 40 81 02 09 04 15 00 26 00 ff 75 08 95 40 91 02 c0
上面大概说了一下设备的枚举过程,如果以上过程完成了即---在电脑中可以看到一个USB设备了,接下来就是完成对应的用户数据传送过程的应用逻辑代码的实现了,这个根据不同的设备包括自定义设备,这一部分除非是一些标准设备,否则你可以做的很有个性化,只要收发双方约定一个统一的标准规则就可以。但是需要记住的是如果你要使用USB进行数据的收发,配置描述符中应该包含一个非0端点的配置,因为端点0是仅用于控制传输的。具体的实现可以详细参考《圈圈教你玩USB(第二版)》一书。
参考:《圈圈教你玩USB(第二版)》
22:17:11 2019-06-04
原文:https://www.cnblogs.com/w-smile/p/10970439.html