USB描述符之间的关系
USB只是一个总线,只提供一个数据通路而已,USB总线驱动程序并不知道一个设备具体如何操作,有哪些行为。
具体的一个设备要实现什么功能,需要设备自己决定,那USB主机如何知道一个设备的功能及行为呢?这就需要通过描述符来实现。描述符中记录了设备的类型,厂商ID和产品ID(通常依靠他们来加载对应的驱动程序),端点情况,版本号等
USB1.1协议定义的标准描述符有设备描述符,配置描述符,接口描述符,端点描述符,字符串描述符,USB2.0协议中增加了两个新的描述符: Device Qualifier Descriptor 和 Other Speed Configuration Descriptor.另外还有一些特殊的描述符: 类特殊描述符(HID描述符和音频接口描述符),厂商自定义描述符
-
一个usb设备中只有一个设备描述符,设备描述符里决定了该设备有多少种配置,
-
每种配置都有一个配置描述符,而在每个配置描述符中又定义了该配置里有多少个接口,
-
每个接口都有一个接口描述符,在接口描述符中又定义了又多少个端点,
-
每个端点都有一个端点描述符,端点描述符定义了端点的大小,类型等,
-
如果有类特殊描述符,他跟在相应的接口描述符之后.USB描述符之间的关系是一层一层的
设备描述符: USB协议版本号,设备类型,端点0的最大包大小,厂商ID(VID: Vendor)和产品ID(PID product),设备版本号,厂商字符串索引,产品字符串索引,设备序号索引,可能的配置参数等.
配置描述符: 配置包含的接口数,配置的编号,供电方式,是否支持原创唤醒,电流需求量等
接口描述符: 接口的编号,接口的端点数,接口所使用的类,子类,协议
端点描述符: 端点号及方向,端点的传输类型,最大包长度,查询时间间隔等.
字符描述符: 主要提供一些人们阅读的信息,他不是必须的
这里说的设备,就是一个实实在在的USB设备(例如USB鼠标);设备只有一个设备地址,USB主机通过这个设备地址来访问设备,而在设备内部会分的更细,他会分出一些端点出来,有了设备地址和端点地址,就能够准确的对端点发送和读取数据了。一个设备可以有多个配置,但是同一时刻只能有一个配置有效,每个皮遏制下又可以有多个接口,当我们需要不同的功能时,只需要选择不同的配置既可。
枚举过程
USB主机检测到USB设备插入后,就要对设备进行枚举了,为什么要枚举呢?枚举其实就是从设备中读取各种描述符信息,这样主机就可以根据这些信息来加载合适的驱动程序,从而知道该设备是什么样的设备。
-
等待稳定:主机通过电平差检测到设备,等待100ms让设备电平趋于稳定
-
首次复位:HUB发起复位,让设备进入初始的地址0模式
-
首次查询设备描述符:GET_DESCRIPTOR 主机查询设备描述符,只要前8字节 ==> 80 06 01 00 00 00 12 00
-
二次复位:在接收到设备描述符前8个字节后,再次重启设备
-
设置地址:SET_ADDRESS 主机下发设置地址命令,设备获取新地址 ==> 00 05 01 00 00 00 00 00
-
二次查询设备描述符:GET_DEVICE_DESCRPTOR获取整个18字节的设备描述符 ==> 80 06 01 00 00 00 12 00
-
获取配置描述符:GET_CONFIGURATION 获取9字节配置描述符 ==> 80 06 02 00 00 00 09 00
-
完成配置:SET_CONFIGURATION,