USB驱动开发——USB描述符
- 格式:pdf
- 大小:611.80 KB
- 文档页数:9
USB驱动开发——USB描述符观察USB设备1.usbview图1 通用串行总线控制器usbview 在C:\WINDDK\2600\src\wdm\usb\usbview\objchk\i386文件夹下,如图2所示的usbview.exe文件。
图2 usbview目录图3 usbview观察USB外接设备如图3所示,可以看出端口8(port8),以及图形右边关于插入U盘的描述信息。
2.bus hound 使用指南bus hound 5.0使用方法如下:1.请下载安装bus hound 5.0全功能版:/down/view.asp?id=282.安装完毕后请一定要重启,否则软件不能工作;3.进行USB监控的主要步骤如下:(1)启动软件,将USB设备插入USB口;(2)在DEVICE内选择设备,例如我的设备是一个U盘,则设备为USB DEVICE,选中该设备,可以在下面的PROPERTIES看到设备的总线类型,设备的电源以及各个端点的功能,在该设备下面还有两个分支:USB AUDIO DEVICE 和 "USB人体学输入设备"(这就是本设备占用的两个接口),一样在PROPERTIES里面可以看到他们的类代码为0x01和0x03。
(3)在看完基本信息后,将上述的某个接口,或者全部打勾。
(4)切换到"SETTING"选项卡,将MAX PHASE设置为512,这样你就可以看到完全的DESCRIPTOR 和其他的数据了。
(5)在"PHASE TO CAPTURE"里面的几个和USB相关的选项如下:CDB:命令描述符块;CTL:USB控制传输;DI/D数据输入/输出;LEN:数据长度;INSOC:同步传输;RSET:总线复位;URB:USB请求块;USTS:USB状态。
查看USB数据传输就把它们都打勾就行了;(6)在"Coloumn to display"里面,把里面的全部打勾。
注意,这样要把窗体最大化才可以看见全部数据。
(7)在"CAPTURE"选项卡里面可以看捕捉的数据了,在文本框输入文字,再点旁边的箭头,可以查询。
按STOP,再按START可以清屏。
(8)举个例子,接上设备,在文本框输入GET DESCRIPTOR(大小写无所谓),点箭头,可以找到你的DESCRIPTOR,但是值得注意的是这个DESCRIPTOR主要是CONFIG,如果是设备描述符会有专门的说明GET DEVICE DESCRIPTOR;这个软件好像不会捕捉STRING DESCRIPTOR。
设备返回的信息在DI里面。
图4 bus hound界面图5 bus hound捕获图6 bus hound界总线命令设置USB的描述符及各种描述符之间的依赖关系USB是个通用的总线,端口都是统一的。
但是USB设备却各种各样,例如USB鼠标,USB键盘,U盘等等,那么USB主机是如何识别出不同的设备的呢?这就要依赖于描述符了。
USB的描述符主要有设备描述符,配置描述符,接口描述符,端点描述符,字符串描述符,HID描述符,报告描述符等等。
具体内容参见USB2.0协议第九章《USB设备架构》。
关于报告描述符,请看:《USB HID报告及报告描述符简介 》/93/198.aspx。
一个USB设备有一个设备描述符,设备描述符里面决定了该设备有多少种配置,每种配置描述符对应着配置描述符;而在配置描述符中又定义了该配置里面有多少个接口,每个接口有对应的接口描述符;在接口描述符里面又定义了该接口有多少个端点,每个端点对应一个端点描述符;端点描述符定义了端点的大小,类型等等。
由此我们可以看出,USB的描述符之间的关系是一层一层的,最上一层是设备描述符,下面是配置描述符,再下面是接口描述符,再下面是端点描述符。
在获取描述符时,先获取设备描述符,然后再获取配置描述符,根据配置描述符中的配置集合长度,一次将配置描述符、接口描述符、端点描述符一起一次读回。
其中可能还会有获取设备序列号,厂商字符串,产品字符串等。
每种描述符都有自己独立的编号,如下:#define DEVICE_DESCRIPTOR 0x01 //设备描述符#define CONFIGURATION_DESCRIPTOR 0x02 //配置描述符#define STRING_DESCRIPTOR 0x03 //字符串描述符#define INTERFACE_DESCRIPTOR 0x04 //接口描述符#define ENDPOINT_DESCRIPTOR 0x05 //端点描述符下面分别详细介绍一下各描述符。
具体的内容可以在DDK下面找到,具体路径如下:C:\WINDDK\2600\inc\wxp。
当然不同的安装环境路径就不一样,笔者是按照默认安装路径安装的,因此在C盘下面。
具体的安装请参考《Windows驱动开发环境配置》介绍。
1.设备描述符//定义标准的设备描述符结构。
typedef struct _DEVICE_DCESCRIPTOR_STRUCT{BYTE blength; //设备描述符的字节数大小BYTE bDescriptorType; //设备描述符类型编号WORD bcdUSB; //USB版本号BYTE bDeviceClass; //USB分配的设备类代码BYTE bDeviceSubClass; //USB分配的子类代码BYTE bDeviceProtocol; //USB分配的设备协议代码BYTE bMaxPacketSize0; //端点0的最大包大小WORD idVendor; //厂商编号WORD idProduct; //产品编号WORD bcdDevice; //设备出厂编号BYTE iManufacturer; //设备厂商字符串的索引BYTE iProduct; //描述产品字符串的索引BYTE iSerialNumber; //描述设备序列号字符串的索引BYTE bNumConfigurations; //可能的配置数量}DEVICE_DESCRIPTOR_STRUCT, * pDEVICE_DESCRIPTOR_STRUCT;//实际的设备描述符示例code DEVICE_DESCRIPTOR_STRUCT device_descriptor= //设备描述符{sizeof(DEVICE_DESCRIPTOR_STRUCT), //设备描述符的字节数大小,这里是18字节DEVICE_DESCRIPTOR, //设备描述符类型编号,设备描述符是010x1001, //USB版本号,这里是USB01.10,即USB1.1。
由于51是大端模式,所以高低字节交换0x00, //USB分配的设备类代码,0表示类型在接口描述符中定义0x00, //USB分配的子类代码,上面一项为0时,本项也要设置为00x00, //USB分配的设备协议代码,上面一项为0时,本项也要设置为00x10, //端点0的最大包大小,这里为16字节0x7104, //厂商编号,这个是需要跟USB组织申请的ID号,表示厂商代号。
0xf0ff, //该产品的编号,跟厂商编号一起配合使用,让主机注册该设备并加载相应的驱动程序0x0100, //设备出厂编号0x01, //设备厂商字符串的索引,在获取字符串描述符时,使用该索引号来识别不同的字符串0x02, //描述产品字符串的索引,同上0x03, //描述设备序列号字符串的索引,同上0x01 //可能的配置数为1,即该设备只有一个配置};2.配置描述符//定义标准的配置描述符结构typedef struct _CONFIGURATION_DESCRIPTOR_STRUCT{BYTE bLength; //配置描述符的字节数大小BYTE bDescriptorType; //配置描述符类型编号WORD wTotalLength; //此配置返回的所有数据大小BYTE bNumInterfaces; //此配置所支持的接口数量BYTE bConfigurationValue; //Set_Configuration命令所需要的参数值BYTE iConfiguration; //描述该配置的字符串的索引值BYTE bmAttributes; //供电模式的选择BYTE MaxPower; //设备从总线提取的最大电流}CONFIGURATION_DESCRIPTOR_STRUCT, * pCONFIGURATION_DESCRIPTOR_STRUCT;3.接口描述符//定义标准的接口描述符结构typedef struct _INTERFACE_DESCRIPTOR_STRUCT{BYTE bLength; //接口描述符的字节数大小BYTE bDescriptorType; //接口描述符的类型编号BYTE bInterfaceNumber; //该接口的编号BYTE bAlternateSetting; //备用的接口描述符编号BYTE bNumEndpoints; //该接口使用的端点数,不包括端点0 BYTE bInterfaceClass; //接口类型BYTE bInterfaceSubClass; //接口子类型BYTE bInterfaceProtocol; //接口遵循的协议BYTE iInterface; //描述该接口的字符串索引值}INTERFACE_DESCRIPTOR_STRUCT, * pINTERFACE_DESCRIPTOR_STRUCT;4.端点描述符//定义标准的端点描述符结构typedef struct _ENDPOINT_DESCRIPTOR_STRUCT{BYTE bLegth; //端点描述符字节数大小BYTE bDescriptorType; //端点描述符类型编号BYTE bEndpointAddress; //端点地址及输入输出属性BYTE bmAttributes; //端点的传输类型属性WORD wMaxPacketSize; //端点收、发的最大包大小BYTE bInterval; //主机查询端点的时间间隔}ENDPOINT_DESCRIPTOR_STRUCT, * pENDPOINT_DESCRIPTOR_STRUCT;下面是一个配置描述符集合的定义:typedef struct _CON_INT_ENDP_DESCRIPTOR_STRUCT{CONFIGURATION_DESCRIPTOR_STRUCT configuration_descriptor;INTERFACE_DESCRIPTOR_STRUCT interface_descritor;ENDPOINT_DESCRIPTOR_STRUCT endpoint_descriptor[ENDPOINT_NUMBER];}CON_INT_ENDP_DESCRIPTOR_STRUCT;配置描述符集合的示例code CON_INT_ENDP_DESCRIPTOR_STRUCT con_int_endp_descriptor= //配置描述符集合 {//configuration_descriptor //配置描述符{sizeof(CONFIGURATION_DESCRIPTOR_STRUCT), //配置描述符的字节数大小,这里为9 CONFIGURATION_DESCRIPTOR, //配置描述符类型编号,配置描述符为2 (sizeof(CONFIGURATION_DESCRIPTOR_STRUCT)+sizeof(INTERFACE_DESCRIPTOR_STRUCT)+sizeof(ENDPOINT_DESCRIPTOR_STRUCT)*ENDPOINT_NUMBER)*256+(sizeof(CONFIGURATION_DESCRIPTOR_STRUCT)+sizeof(INTERFACE_DESCRIPTOR_STRUCT)+sizeof(ENDPOINT_DESCRIPTOR_STRUCT)*ENDPOINT_NUMBER)/256, //配置描述符集合的总大小0x01, //只包含一个接口0x01, //该配置的编号0x00, //iConfiguration字段0x80, //采用总线供电,不支持远程唤醒0xC8 //从总线获取最大电流400mA},//interface_descritor //接口描述符{sizeof(INTERFACE_DESCRIPTOR_STRUCT), //接口描述符的字节数大小,这里为9 INTERFACE_DESCRIPTOR, //接口描述符类型编号,接口描述符为3 0x00, //接口编号为40x00, //该接口描述符的编号为0ENDPOINT_NUMBER, //非0端点数量为2,只使用端点主端点输入和输出 0x08, //定义为USB大容量存储设备0x06, //使用的子类,为简化块命令0x50, //使用的协议,这里使用单批量传输协议 0x00 //接口描述符字符串索引,为0,表示没有字符串 },//endpoint_descriptor[]{{ //主端点输入描述sizeof(ENDPOINT_DESCRIPTOR_STRUCT), //端点描述符的字节数大小,这里为7 ENDPOINT_DESCRIPTOR, //端点描述符类型编号,端点描述符为5 MAIN_POINT_IN, //端点号,主输入端点ENDPOINT_TYPE_BULK, //使用的传输类型,批量传输0x4000, //该端点支持的最大包尺寸,64字节0x00 //中断扫描时间,对批量传输无效},{ //主端点输出描述sizeof(ENDPOINT_DESCRIPTOR_STRUCT), //端点描述符的字节数大小,这里为7 ENDPOINT_DESCRIPTOR, //端点描述符类型编号,端点描述符为5 MAIN_POINT_OUT, //端点号,主输出端点ENDPOINT_TYPE_BULK, //使用的传输类型,批量传输0x4000, //该端点支持的最大包尺寸,64字节0x00 //中断扫描时间,对批量传输无效}}};其中关于端点的类型定义如下://定义的端点类型#define ENDPOINT_TYPE_CONTROL 0x00 //控制传输#define ENDPOINT_TYPE_ISOCHRONOUS 0x01 //同步传输#define ENDPOINT_TYPE_BULK 0x02 //批量传输#define ENDPOINT_TYPE_INTERRUPT 0x03 //中断传输端点号的定义如下:#define MAIN_POINT_OUT 0x02 //2号输出端点#define MAIN_POINT_IN 0x82 //2号输入端点。