USB1.1协议定义的标准描述符有设备描述符(Device Descriptor)、配置描述符(Configuration Descriptor)、接口描述符(Interface Descriptor)、端点描述符(Endpoint Descriptor)和字符串描述符(String Descriptor)。USB2.0相比于USB1.1新增加的两个描述符:限定符描述符(Qualifier Descriptor)和其他速度配置描述符(Other Speed Configuration Descriptor)。另外还有一些类描述符,例如HID描述符,音频接口描述符,以及厂商自定义描述符
一个设备只有一个设备描述符,设备描述符中会有字段描述有多少种配置描述符,而配置描述符中又有字段描述有多少种接口(接口描述符),接口描述符中又有字段描述有多少个端点(endpoint),而endpoint描述符中又描述了一个端点的大小,还有一种是特殊的类描述符,例如hid,cdc,uvc,uac的类描述符,这种描述符是在接口描述符之后描述的。
主机读取这些描述符的过程是先获取设备描述符,然后根据设备描述符获取配置描述符,然后根据配置描述符中的总长度一次性将后面的描述符一并读取。还有一种是字符串描述符,是通过单独的命令获取的。
设备描述符:usb协议的版本号,设备类型,端点0的大小,VID,PID,设备版本号,厂商字符串索引,产品字符串,设备序列号,以及配置数目(配置描述符相关)
配置描述符:配置所含有的接口数量,配置的编号,供电方式,是否支持远程唤醒,需要的电流数大小
接口描述符:接口的编号,接口的端点数,接口所使用的类,子类,协议等。
端点描述符:端点号,端点的大小方向,最大包的长度等等。
字符串描述符:不是必须的,提供可供阅读的字符串。
设备枚举的简单过程:
设备插入主机,主机复位设备,发送获取设备描述符的指令,正确获取之后,然后再复位usb设备,设置usb设备的地址,设置成功 之后,再获取剩余的描述符,最后完成整个枚举过程。需要注意的是有的描述符是单独获取的。
usb输出传输过程中,是LSB在前,MSB在后,传输的数据以一个包(packet)为单位的,包和包之间不同的地方,但是每个包都是以同步域开始,紧随包的标识符(PID,packet id),然后最后以EOP(end of packet)结束包的传输。
在低速和全速传输中,同步域是00000001开始,而高速中是以32位数据,最后一位是1结束
而且针对包结束符低速和高速设备也是不同的。
关于PID(包描述符)可以描述整个包的类型,比如说令牌包,数据包,握手包,以及特殊包,PID 0~3 bit是真正描述符,而bit4~7是0~3bit的取反。
USB每次传输都是有主机发起,而令牌包是用来启动一次usb传输的。
@1:OUT:发送给设备,表明下次数据紧随而来从主机发送到设备
@2:IN:发送给设备,要求从设备端回传数据给主机
@3:SOF:帧起始包每毫秒产生一个帧,而高速设备每毫秒产生8个帧,这8个帧号相同
@4:SETUP:类似与OUT,但是下次数据包必须是DATA0数据包
以下是各个令牌包的结构:
其中5bit的CRC校验是对前面11bit的数据进行校验
数据包:
数据包不同的类型,可以区分数据包是否是因为握手包发生错误时导致数据没有传输成功。
握手包:
握手包数据类型有ACK,NAK,STALL,NYET,而ACK主机和设备都可以发出,其它只能是设备发出,注意NAK,不是错误,而是设备端没有能力接收数据或者没有什么数据可以返回,而STALL 表明设备端点挂起,或者无法执行相关的操作,需要主机进行相关的干预解除这种状态,而NYET是说设备已经成功接受数据,但是没有空间存储下一次数据,告知主机下一次可以使用ping令牌包去试探设备是否有能力接收数据,保证带宽。