您好,欢迎来电子发烧友网! ,新用户?[免费注册]

您的位置:电子发烧友网>电子元器件>接口定义>

usb标准描述符之技巧

2009年04月12日 11:09 www.elecfans.com 作者:本站 用户评论(0

usb标准描述符之技巧

USB是个通用的总线,端口都是统一的。但是USB设备却各种各样,例如USB鼠标,USB键盘,U盘等等,那么USB主机是如何识别出不同的设备的呢?这就要依赖于描述符了。
??? USB的描述符主要有设备描述符,配置描述符,接口描述符,端点描述符,字符串描述符,HID描述符,报告描述符等等。

??? 一个USB设备有一个设备描述符,设备描述符里面决定了该设备有多少种配置,每种配置描述符对应着配置描述符;而在配置描述符中又定义了该配置里面有多少个接口,每个接口有对应的接口描述符;在接口描述符里面又定义了该接口有多少个端点,每个端点对应一个端点描述符;端点描述符定义了端点的大小,类型等等。由此我们可以看出,USB的描述符之间的关系是一层一层的,最上一层是设备描述符,下面是配置描述符,再下面是接口描述符,再下面是端点描述符。在获取描述符时,先获取设备描述符,然后再获取配置描述符,根据配置描述符中的配置集合长度,一次将配置描述符、接口描述符、端点描述符一起一次读回。其中可能还会有获取设备序列号,厂商字符串,产品字符串等。
???
???? 每种描述符都有自己独立的编号,如下:
#define DEVICE_DESCRIPTOR?????????????? 0x01? //设备描述符
#define CONFIGURATION_DESCRIPTOR??????? 0x02? //配置描述符
#define STRING_DESCRIPTOR?????????????? 0x03? //字符串描述符
#define INTERFACE_DESCRIPTOR??????????? 0x04? //接口描述符
#define ENDPOINT_DESCRIPTOR???????????? 0x05? //端点描述符
???
下面分别详细介绍一下各描述符。

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,????????????????????????????? //设备描述符类型编号,设备描述符是01
?0x1001,?? //USB版本号,这里是USB01.10,即USB1.1。由于51是大端模式,所以高低字节交换
?0x00,???????????????????????????????? //USB分配的设备类代码,0表示类型在接口描述符中定义
?0x00,???????????????????????????????? //USB分配的子类代码,上面一项为0时,本项也要设置为0
?0x00,??????????????????????????????? //USB分配的设备协议代码,上面一项为0时,本项也要设置为0
?0x10,??????????????????????????????? //端点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;

2.接口描述符

//定义标准的接口描述符结构

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,????????????????????????????????? //接口编号为4
?0x00,????????????????????????????????? //该接口描述符的编号为0
?ENDPOINT_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号输入端点

非常好我支持^.^

(3) 100%

不好我反对

(0) 0%

( 发表人:admin )

      发表评论

      用户评论
      评价:好评中评差评

      发表评论,获取积分! 请遵守相关规定!

      ?