主机在第一次发送获取配置描述符的命令时,只会读取配置描述符的前九个字节,它包含了配置描述符以及所有从属的接口,端点(及其他特定类描述符)的总长度。
获取其他长度不固定的描述符也是这样分成两步执行
如果一个配置描述符不只支持一个接口描述符,并且每个接口描述符都有自己从属的端点描述符,那么我们USB设备在响应USB主机发送获取配置描述符命令时,会将这每一个接口与端点描述符作为配置描述符的一部分被返回。
USB接口描述符
第一个字段(bLength)表示接口描述符的长度,
第二个字段(bDescriptorType)表示描述符类型 此处应该为0x04
第三个字段(bInterfaceNumber)表示接口的编号 他是由配置描述符的接口数量(bNumInterfaces)来决定的。
从0递增 所以这里为0 表示只有一个接口
第四个字段(bAlternateSetting)表示备用接口编号,它的用法和接口编号一样,就是下一个层次的接口,用的很少,不用就可以设置为0,
我们一个设备允许拥有多个配置,主机在总线枚举的时候会选择并激活其中一个,这个备用接口就是允许我们在只有一个配置的情况下,在同一个接口内实现多种模式的转换,从而实现达到多个配置的目的。
举个例子,我们使用USB声卡,他有暂停和播放两个功能,我们在播放的时候会不停给声卡设备端点发送数据,这个时候就会占用一定的总线带宽,如果暂停播放呢,我们可以选择不给端点发送数据,但是因为是同步传输,仍然会占用一定的总线带宽,这时候我们可以使用备用接口功能,就是设置两个备用接口,一个包含输出数据的端点,一个不包含,我们默认的时候就选择不包含端点的接口,就可以不占用总线线宽了,需要播放的的时候就启用包含端点的接口。
第五个字段(bNumEndpoints)表示接口使用的端点数量。该字段表示的端点数量不包含端点0
如果是0x01 就表示 0 1 使用了两个端点。
第六个字段(bInterfaceClass),第七个字段(bInterfaceSubClass),第八个字段(nInterfaceProtocol),他们分别代表接口类,接口子类,接口协议,如果我们在设备描述符中将bDeviceClass(设备类)定义为0,那么我们要在接口描述符中进一步定义具体要求的接口功能。
下面是bDeviceClass的一点简单介绍
如果bInterfaceClass为0xFF表示接口类由厂商自定义,如果是0x00,则为将来标准化保留,其他的字段由USB-IF分配,该字段为0x03,就表示该设备想把自己枚举成HID设备,
bInterfaceSubClass这个字段的值的设置随bInterfaceClass的不同而不同,如果为0,则bInterfaceSubClass也是必须为0,其他非0xFF都是由USB-IF分配的,HID设备的接口子类代码只有0x01和0x00是有效的,后者0x00表示没有子类代码,后者0x01表示基本输入输出系统,
所以该字段设置成了0x01
nInterfaceProtocol这个字段为0x02 意思如下图所示,代表鼠标的意思
如果我们要设计一个集线器设备,设备描述符的bDeviceClass同样可以为0,但是接口描述符中的bInterfaceClass的设置为0x09,第七个字段(bInterfaceSubClass),第八个字段(nInterfaceProtocol)都可以为0,集线器是没有分规范的。
第九个字段(Interface)表示接口字符串描述表的索引值,没有就为0
USB端点描述符
接口的端点数量是可以灵活调整的
第一个字段都是长度,
第二个字段也是固定的为0x05 表示为端点描述符类型
第三个字段(bEndpointAddress)用来描述端点地址和方向信息
端点号在低四位 可使用16个端点(低速只有两位 三个端点 )
端点的方向是以主机为参考的,输出OUT端点的数据传输方向是从主机到设备,输入IN端点则是相反的。(方向的定义对控制端点无效,控制传输类型是双向的,定义方向是无效的)
第三个字段(bmAttributes)决定了端点是什么传输类型
这里我们是0x03表示中断传输
第五个字段(wMaxPacketSize)表示端点支持接收或发送的最大数据包字节长度。
第六个字段(0x20)表示主机轮询中断端点,其范围是1-255 我们STM32f103是全速的USB,没有高速,所以程序里就是32ms查询一次。计算方法如下图,简单了解一下就好。