当前位置: 首页 > 工具软件 > ccid > 使用案例 >

USB描述符解析和USB_CCID描述符设置

鲁华皓
2023-12-01

USB描述符解析

USB描述符信息会被存储在USB设备中,在设备枚举过程中,USB主机会向USB设备发送GetDescriptor请求,USB设备在收到这个请求之后,会将USB描述符信息返回给USB主机,USB主机分析返回来的数据,判断出该设备是哪一种USB设备,按照描述符中的一些配置信息与设备建立相应的数据通道。USB描述符信息在USB协议中有详细描述。

标准的USB设备有5种USB描述符:设备描述符,配置描述符,字符串描述符,接口描述符,端点描述符。下面详解:

1.设备描述符 一个设备只有一个设备描述符,列出这个设备的配置参数

typedef struct _USB_DEVICE_DESCRIPTOR_
{
BYTE bLength,
BYTE bDescriptorType,
WORD bcdUSB,
BYTE bDeviceClass,
BTYE bDeviceSubClass,
BYTE bDeviceProtol,
BYTE bMaxPacketSize0,
WORD idVenderI,
WORD idProduct,
WORD bcdDevice,
BYTE iManufacturer,
BYTE iProduct,
BYTE iSerialNumber,
BYTE iNumConfiguations
}USB_DEVICE_DESCRIPTOR;

bLength : 描述符大小.固定为0x12.
bDescriptorType : 设备描述符类型.固定为0x01.
bcdUSB : USB 规范发布号.表示了本设备能适用于那种协议,如2.0=0200,1.1=0110等.
bDeviceClass :类型代码(由USB指定)当它的值是0时,表示所有接口在配置描述符里,并且所有接口是独立的。当它的值是1到FEH时,表示不同的接口关联的。当它的值是FFH时,它是厂商自己定义的.
bDeviceSubClass : 子类型代码(由USB分配).如果bDeviceClass值是0,一定要设置为0.其它情况就跟据USB-IF组织定义的编码.
bDeviceProtocol : 协议代码(由USB分配).如果使用USB-IF组织定义的协议,就需要设置这里的值,否则直接设置为0。如果厂商自己定义的可以设置为FFH.
bMaxPacketSize0 : 端点0最大分组大小(只有8,16,32,64有效).
idVendor : 供应商ID(由USB分配).
idProduct : 产品ID(由厂商分配).由供应商ID和产品ID,就可以让操作系统加载不同的驱动程序.
bcdDevice : 设备出产编码.由厂家自行设置.
iManufacturer : 厂商描述符字符串索引.索引到对应的字符串描述符.为0则表示没有.
iProduct : :产品描述符字符串索引.同上.
iSerialNumber : 设备序列号字符串索引.同上.
bNumConfigurations : 可能的配置数.指配置字符串的个数

2.配置描述符 一个设备中可以有多个配置描述符,每套配置描述符含有接口描述符,端点描述符

typedef struct _USB_CONFIGURATION_DESCRIPTOR_
{
    BYTE bLength,
    BYTE bDescriptorType,
    WORD wTotalLength,
    BYTE bNumInterfaces,
    BYTE bConfigurationValue,
    BYTE iConfiguration,
    BYTE bmAttributes,
    BYTE MaxPower
}USB_CONFIGURATION_DESCRIPTOR;

bLength: 描述符大小.固定为0x09.
bDescriptorType: 配置描述符类型.固定为0x02.
wTotalLength: 整个数据的长度.指此配置返回的配置描述符,接口描述符以及端点描述符的全部大小.
bNumInterfaces: 配置所支持的接口数.指该配置配备的接口数量,也表示该配置下接口描述符数量.
bConfigurationValue:当使用SetConfiguration和GetConfiguration请求时所指定的配置索引值
iConfiguration: 用于描述该配置字符串描述符的索引.
bmAttributes: 供电模式选择.D7:总线供电,D6:自供电,D5:远程唤醒,D4~D0:保留
MaxPower: 总线供电的USB设备的最大消耗电流.以2mA为单位.例如0x32为50*2=100mA

3.接口描述符 一个配置描述符内可以含有多个接口,数量由配置描述符决定

typedef struct _USB_INTERFACE_DESCRIPTOR_
{
    BYTE bLength,
    BYTE bDescriptorType,
    BYTE bInterfaceNumber,
    BYTE bAlternateSetting,
    BYTE bNumEndpoint,
    BYTE bInterfaceClass,
    BYTE bInterfaceSubClass,
    BYTE bInterfaceProtocol,
    BYTE iInterface
}USB_INTERFACE_DESCRIPTOR;

bLength:描述符大小.固定为0x09
bDescriptorType:接口描述符类型.固定为0x04
bInterfaceNumber:该接口的编号
bAlternateSetting:用于为上一个字段选择可供替换的位置.即备用的接口描述符标号
bNumEndpoint:使用的端点数目.端点0除外
bInterfaceClass:类型代码(由USB分配)
bInterfaceSubClass:子类型代码(由USB分配)
bInterfaceProtocol:协议代码(由USB分配)
iInterface:字符串描述符的索引

4.端点描述符 每个接口所需要的端点及其设置,数量由配置描述符决定

typedef struct _USB_ENDPOINT_DESCRIPTOR_
{
    BYTE bLength,
    BYTE bDescriptorType,
    BYTE bEndpointAddress,
    BYTE bmAttributes,
    WORD wMaxPacketSize,
    BYTE bInterval
}USB_ENDPOINT_DESCRIPTOR;

bLength : 描述符大小.固定为0x07.
bDescriptorType : 接口描述符类型.固定为0x05.
bEndpointType : USB设备的端点地址.D7端点方向,对于控制端点可以忽略,1/0:IN/OUT.D6-D4,保留.D3-D0:端点号.
bmAttributes : 端点属性.D7-D2,保留.D1-D0,传输类型:00控制,01同步,02批量,03中断.
wMaxPacketSize : 本端点接收或发送的最大信息包大小.
bInterval : 轮询数据传送端点的时间间隔.对于批量传送和控制传送的端点忽略.对于同步传送的端点,必须为1,对于中断传送的端点,范围为1-255.

5.字符串描述符 字符串描述符是可选的.如果不支持字符串描述符,其设备,配置,接口描述符内的所有字符串描述符索引都必须为0,每个字符串描述符都有一个索引,USB主机会在请求时按照顺序获取对应的字符串描述符,默认0位语言字符串描述符,后边都由每个描述符内容中指定,一般1为设备厂商字符串描述符,2为产品描述符,3为设备序列号字符串描述符,4为接口描述符

typedef struct _USB_STRING_DESCRIPTION_
{
    BYTE bLength,
    BYTE bDescriptionType,
    BYTE bString[];
}USB_STRING_DESCRIPTION;

bLength : 描述符大小.由整个字符串的长度加上bLength和bDescriptorType的长度决定.
bDescriptorType : 接口描述符类型.固定为0x03.
bString[] : Unicode编码字符串.

下边是一套USB_CCID的设备描述符、配置描述符、接口描述符、端点描述符和字符串描述符

CCID描述符配置

/*------------Descriptor of USB Device---------------------------*/ 
const UINT8 DeviceDescFS[18]= 
{     
	0x12,  //bLength          //设备描述符的字节数大小,为0x12
	0x01,  //bDescriptorType  //设备描述符类型编号,为0x01
	0x00,  //bcdUSB           //USB规范版本号(BCD码)  0x0110
	0x02,  
	0x00,  //bDeviceClass     //USB分配的设备类代码,0x01~0xfe 为标准设备类,0xff 为厂商自定义类型 0x00 不是在设备描述符中定义的,如HID
	0x00,  //bDeviceSubClass  //USB分配的设备子类代码,同上,值由USB 规定和分配的
	0x00,  //bDeviceProtocl   //USB分配的设备协议代码,同上
	CTRL_PACKET_LEN, //bMaxPacketSize0 //端点0控制传输所支持的最大数据包长度,单位字节
	0x12,  //idVendor         //厂商编号VID=0x2012
	0x20,
	0x02,  //idProduct        //产品编号PID=0x1402
	0x14,
	0x01,  //bcdDevice        //设备出厂编号bcdDevice=0x0100
	0x02,  
	0x04,  //iManufacturer    //描述厂商字符串的索引Index of Vendor
	0x1C,  //iProduct         //描述产品字符串的索引Index of Producr
	0x14,  //iSerialNumber    //描述设备序列号字符串的索引0x03;//Index of SN
	0x01   //bNumConfiguration//可能的配置数量
}; 

/*------------Descriptor of USB Configuation---------------------------*/ 
#define USB_SIZ_CONFIG_DESC		(93 + 77)
UINT8 USBD_CCID_ConfigDescriptor[] =
{
	/*Configuation Descriptor*/
	0x09,/* bLength: Configuation Descriptor size */
	0x02,/* bDescriptorType: Configuration */
	LOBYTE(USB_SIZ_CONFIG_DESC),/* wTotalLength:no of returned bytes low*/
	HIBYTE(USB_SIZ_CONFIG_DESC),,/* wTotalLength:no of returned bytes higt*/
	0x02,   /* bNumInterfaces: 2 interface */
	0x01,   /* bConfigurationValue: Configuration value */
	0x04,   /* iConfiguration: Index of string descriptor describing the configuration */
	0x80,   /* bmAttributes:bus powered */    
	0x32,   /* MaxPower 200 mA */

	/*Interface Descriptor*/
	0x09,   /* bLength: Interface Descriptor size */
	0x04,	/* bDescriptorType: Interface descriptor type*/
	0x01,   /* bInterfaceNumber: Number of Interface */		//接口号
	0x00,   /* bAlternateSetting: Alternate setting */
	0x03,   /* bNumEndpoints*/								//接口端点数量
	0x0B,   /* bInterfaceClass: Smart Card */				//接口类型:0x0B智能卡类型
	0x00,   /* bInterfaceSubClass : SCSI transparent*/
	0x00,   /* nInterfaceProtocol */
	0X05,   /* iInterface: */								//接口字符串描述符的索引

	//CCID class desc
	0x36,					//bLength                      //描述符长度, = 36H
	0x21,			 		//bDescriptorType              //描述符类型, = 21H
	0x10,0x01,				//bcdCCID                      //CCID类规范版本号  = 1.1
	0x00,					//bMaxSlotIndex                //所支持的最大插槽数 1个	
	0x03,					//bVoltageSupport  5.0V        //所支持卡的操作电压 01--5V; 02--3V; 04--1.8V 5V&3V
	0x03,0x00,0x00,0x00,	//dwProtocols  T = 0           //所支持的卡通讯协议T=0&T=1
	0xb8,0x0b,0x00,0x00,	//dwDefaultClock  3MHz         //默认卡操作时钟,以KHz为单位 3000KHz
	0xb8,0x0b,0x00,0x00,    //dwMaximumClock  3MHz         //所支持的最小时钟 3000KHz
	0x00,					//bNumClockSupported  1        //所支持的时钟数 仅支持默认时钟
	0x80,0x25,0x00,0x00,	//dwDataRate  9600bps          //默认IC卡通讯的位速率 9600
	0x80,0x25,0x00,0x00,	//dwMaxDataRate  115200bps     //所支持的与IC卡通讯的最大位速率 9600
	0x00,					//bNumDataRatesSupported  1    //所支持的位速率数 仅支持默认速率
	0xFE,0x00,0x00,0x00,	//dwMaxIFSD                    //T=1协议下的最大FSD 254
	0x00,0x00,0x00,0x00,	//dwSynchProtocols             //所支持的同步协议 当前版本为0x00000000
	0x00,0x00,0x00,0x00,	//dwMechanical                 //所支持的机械特性,00-无任何特性
	0xBA,0x00,0x02,0x00,	//dwFeatures                   //卡片特性 0x0002008A/0x0004023A
	0x80,0x01,0x00,0x00,	//dwMaxCCIDMessageLength       //最大CCID信息长度 短格式下为261+10,此处设为384
	0x00,					//bClassGetResponse            //GetReponse指令获取数据的缺省值 00
	0x00,					//bClassEnvelope               //Envelope指令缺省值 00
	0x00,0x00,				//wLcdLayout                   //液晶尺寸0x0000 没有液晶
	0x00,					//bPINSupport                  //密码支持 不支持PIN
	0x01,					//bMaxCCIDBusySlots	           //所支持的可同时操作的插槽数 1个

	/*Endpoint 1 Descriptor*/
	0x07, //bLength							//端点描述符的字节数大小
	0x05, //bDescriptorType					//端点描述符类型编号 
	EP1IN_NUMBER, //bEndpointAddress		//端点地址及输入输出属性 
	0x02, //bmAttributes					//端点的传输类型属性
	0x40, //wMaxPacketSize 					//端点收、发的最大包的大小
	0x00, 
	0x01, //bInterval	                   //主机查询端点的时间间隔	
	/*Endpoint 1 Descriptor*/
	0x07, //bLength                        //端点描述符的字节数大小
	0x05, //bDescriptorType                //端点描述符类型编号  
	EP1OUT_NUMBER, //bEndpointAddress      //端点地址及输入输出属性  
	0x02, //bmAttributes                   //端点的传输类型属性
	0x40, //wMaxPacketSize 					//端点收、发的最大包的大小
	0x00, 
	0x01,  //bInterval	                   //主机查询端点的时间间隔 
	/*Endpoint 2 Descriptor*/
	0x07, //bLength                        //端点描述符的字节数大小
	0x05, //bDescriptorType                //端点描述符类型编号  
	EP2IN_NUMBER, //bEndpointAddress       //端点地址及输入输出属性  
	0x03, //bmAttributes                   //端点的传输类型属性
	0x08, //wMaxPacketSize                 //端点收、发的最大包的大小//产生 xact error
	0x00, 
	0x0a, //bInterval	                   //主机查询端点的时间间隔

	/*Interface Descriptor*/
	0x09,	/* bLength: Interface Descriptor size */
	0x04,	/* bDescriptorType: Interface */   
	0x00,   /* bInterfaceNumber: Number of Interface */
	0x00,   /* bAlternateSetting: Alternate setting */
	0x02,   /* bNumEndpoints*/
	0x0B,   /* bInterfaceClass: Smart Card */
	0x00,   /* bInterfaceSubClass : SCSI transparent*/
	0x00,   /* nInterfaceProtocol */
	0X06,   /* iInterface: */

	0x36,
	0x21,
	0x10,0x01,
	0x00,
	0x03,
	0x03,0x00,0x00,0x00,
	0xb8,0x0b,0x00,0x00,
	0xb8,0x0b,0x00,0x00,
	0x00,
	0x80,0x25,0x00,0x00,
	0x80,0x25,0x00,0x00,
	0x00,
	0xfe,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,
	0xba,0x00,0x02,0x00,
	0x80,0x01,0x00,0x00,
	0x00,
	0x00,
	0x00,0x00,
	0x00,
	0x01,

	/*Endpoint 3 Descriptor*/
	0x07,			/* bLength: Endpoint Descriptor size */
	0x05,			/* bDescriptorType: Endpoint */
	EP3OUT_NUMBER,	/* bEndpointAddress: (OUT3) */
	0x02,			/* bmAttributes: Bulk */
	0x40,			/* wMaxPacketSize: */
	0x00,
	0x0A,			/* bInterval: ignore for Bulk transfer */

	/*Endpoint 3 Descriptor*/
	0x07,			/* bLength: Endpoint Descriptor size */
	0x05,			/* bDescriptorType: Endpoint */
	EP3IN_NUMBER,	/* bEndpointAddress: (IN3) */
	0x02,			/* bmAttributes: Bulk */
	0x40,			/* wMaxPacketSize: */
	0x00,
	0x0A,			/* bInterval: ignore for Bulk transfer */
	
};
/*------------Descriptor of Device String---------------------------*/ 

uint8_t USBD_LangIDDesc[0x04] =
{
	0x04,	/* bLength */      
	0x03,	/* bDescriptorType */
	0x09,	/*English(US)*/
	0x04, 
};

#define USB_SIZ_STRING_SERIAL		(10)
uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] =
{
	USB_SIZ_STRING_SERIAL,	/* bLength */
	0x03,  /* bDescriptorType */
	'8', 0, '0', 0, '0', 0, '0', 0
};
uint8_t USBD_Interface1Strings[USB_DESCRIPTOR_LENGTH_STRING3] = {
	sizeof(USBD_Interface1Strings),
	0x03,                                                             
	'S',0,'M',0,'A',0,'R',0,'T',0,' ',0,'C',0,'A',0,'R',0,'D',0, 
};


 类似资料: