USB协议详解第9讲(USB描述符-HID描述符)

目录

1.HID设备概述

2.HID描述符组成

3.STM32配置描述符集合代码(必须按顺序)

4.HID描述符组成详解


1.HID设备概述

USB设备中有一大类就是HID设备,即Human Interface Devices,人机接口设备。这类设备包括鼠标、键盘、游戏手柄等,主要用于人与计算机进行交互。HID设备可以作为低速、 全速、高速设备用。由于HID设备要求用户输入能得到及时响应,故其传输方式通常采用中断传输

在USB协议中,HID设备的类型定义放置在接口描述符中,USB的设备描述符和配置描述符中不包含HID设备的信息。因此,对于某些特定的HID设备,可以定义多个接口,一个接口为HID设备类即可。当USB一个设备为HID设备时,其设备描述符里面的bDeviceClass、bDeviceSubClass、bDeviceProtocol应为0,具体的定义在接口描述符中,接口描述符bInterfaceClass、bInterfaceSubClass、bInterfaceProtocol三个值如下:

图片

bInterfaceClass0x03:表示HID为设备
bInterfaceSubClass

0x00:对无需支持引导的HID设备;

0x01:对支持引导的USB设备(鼠标、键盘);

其他:保留。

bInterfaceProtocol

当bInterfaceSubClass为0x00,此值无效

当bInterfaceSubClass为0x01

设置为0x01:键盘接口

设置为0x02:鼠标接口

注:说明下,支持引导就是在BIOS界面USB设备就可以使用了,比如我们的键盘和鼠标。

2.HID描述符组成

当一个USB设备被定义为HID设备的时候,设备必须实现HID描述符。首先要明确的一点是HID描述符不能单独返回给USB主机,主机会请求获得配置描述符集合,配置描述符集合主要由标准配置描述符、接口描述符、HID描述符、端点描述符,报告描述符物理描述符是单独返回给USB主机。HID描述符组成如下:

图片

3.STM32配置描述符集合代码(必须按顺序)

/* USB Configuration Descriptor */
const uint8_t CustomHID_ConfigDescriptor[CUSTOMHID_SIZ_CONFIG_DESC] =
{
//
// 标准配置描述符
//	
    0x09, /* bLength: Configuation Descriptor size */
    USB_CONFIGURATION_DESCRIPTOR_TYPE, 	/* bDescriptorType: Configuration */
    CUSTOMHID_SIZ_CONFIG_DESC,			/* wTotalLength low : Bytes returned */
    0x00,								/* wTotalLength high: Bytes returned */
    0x01,         /* bNumInterfaces: 1 interface */
    0x01,         /* bConfigurationValue: Configuration value */
    0x00,         /* iConfiguration: Index of string descriptor describing the configuration*/
    0xC0,         /* bmAttributes: Bus powered */
                  /*Bus powered: 7th bit, Self Powered: 6th bit, Remote wakeup: 5th bit, reserved: 4..0 bits */
    0x96,         /* MaxPower 300 mA: this current is used for detecting Vbus */
    
//
// 接口描述符
//		
	/************** Descriptor of Custom HID interface ****************/
    /* 09 */
    0x09,         						/* bLength: Interface Descriptor size */
    USB_INTERFACE_DESCRIPTOR_TYPE,		/* bDescriptorType: Interface descriptor type */
    0x00,         /* bInterfaceNumber: Number of Interface */
    0x00,         /* bAlternateSetting: Alternate setting */
    0x02,         /* bNumEndpoints 此接口有两个端点 */
    0x03,         /* bInterfaceClass: HID */
    0x00,         /* bInterfaceSubClass : 1=BOOT, 0=no boot */
    0x00,         /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
    0,            /* iInterface: Index of string descriptor */
    
//
// HID描述符
//		
	/******************** Descriptor of Custom HID HID ********************/
    0x09,         			/* bLength: HID Descriptor size */
    HID_DESCRIPTOR_TYPE, 	/* bDescriptorType: HID */
    0x10,         			/* bcdHID: HID Class Spec release number */
    0x01,
    0x00,         /* bCountryCode: Hardware target country 国家代码 */
    
	0x01,         /* bNumDescriptors: Number of HID class descriptors to follow
					 类别描述符数目(至少有一个报表描述符)*/
    0x22,         /* bDescriptorType 报告描述符 */
    CUSTOMHID_SIZ_REPORT_DESC,	/* wItemLength: Total length of Report descriptor 报告描述符大小 */
    0x00,						/* 标志类别描述符说明结束 */ 
	
	
//
// 端点1描述符
//		
	/******************** Descriptor of Custom HID endpoints ******************/
    /* 27 */
    0x07,          /* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */

    0x82,          /* bEndpointAddress: Endpoint Address (IN) */               
                   // bit 3...0 : the endpoint number
                   // bit 6...4 : reserved
                    // bit 7     : 0(OUT), 1(IN)
    0x03,          /* bmAttributes: Interrupt endpoint */
    0x40,          /* wMaxPacketSize: 64 Bytes max */
    0x00,
    0x02,          /* bInterval: Polling Interval (2 ms) */
    /* 34 */

//
// 端点2描述符
//		
    0x07,	/* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE,	/* bDescriptorType: */
			/*	Endpoint descriptor type */
    0x01,	/* bEndpointAddress: */
			/*	Endpoint Address (OUT) */
    0x03,	/* bmAttributes: Interrupt endpoint */
    0x40,	/* wMaxPacketSize: 64 Bytes max  */
    0x00,
    0x02,	/* bInterval: Polling Interval (2 ms) */
    /* 41 */
}; /* CustomHID_ConfigDescriptor */

4.HID描述符组成详解

1.bLength

描述符长度。HID描述符长度不是固定的,长度多少与描述符中包含的下级描述符个数相关。如果只有一个下级描述符,也就是不包括可选的部分,一共有9字节的长度,如果有多个下级描述符,按照长度往上加。

2.bDescriptorType

描述符类型,设置为0x21。

3.bcdHID

HID设备所遵循的HID版本号,为4位16进制的BCD码。1.0即0x0100,1.1即0x0101,2.0即0x0200。

4.bCountryCode

HID设备国家/地区代码,如下表格自行查询。

图片

5.bNumDescriptor

HID设备支持的下级描述符的数量。在这里大家一定要注意,下一级描述符的类型有两种,报告描述符物理描述符,对于HID设备报告描述符和物理描述符可以有多个,但是至少有一个报告描述符,物理描述符是可选的,bNumDescriptor表示报告描述符和物理描述符的个数总和。由于HID设备至少需要包括一个报告描述符,故其值至小为0x01,一般的HID设备也为1,也就是有一个报告描述符,物理描述符很少用到。

6.bDescriptorTyep

下级描述符的类型,下级描述符第1个必须是报告描述符,所以这里存放报告描述符类型,如下表格,报告描述符的类型为0x22,其他描述符的类型可速查。

图片

7.wDescriptorLength

下级描述符的长度,下级描述符第1个必须是报告描述符,所以这里存放报告描述符的长度,每种HID设备的报告描述符长度是不一样的,比如STM32某HID设备的报告描述符长度为43字节,代码如下,下一节详解报告描述符

//
// 报告描述符
//
const unsigned char ReportDesc[0x2b] =   // Report descriptor
	{
	0x05,0x01,		/* Usage Page (generic desktop) */
	0x09,0x06,		/* Usage (keyboard) */
	0xA1,0x01,		/* Collection */
	0x05,0x07,		/*   Usage Page 7 (keyboard/keypad) */
	0x19,0xE0,		/*   Usage Minimum = 224 */
	0x29,0xE7,		/*   Usage Maximum = 231 */
	0x15,0x00,		/*   Logical Minimum = 0 */
	0x25,0x01,		/*   Logical Maximum = 1 */
	0x75,0x01,		/*   Report Size = 1 */
	0x95,0x08,		/*   Report Count = 8 */
	0x81,0x02,		/*  Input(Data,Variable,Absolute) */
	0x95,0x01,		/*   Report Count = 1 */
	0x75,0x08,		/*   Report Size = 8 */
	0x81,0x01,		/*  Input(Constant) */
	0x19,0x00,		/*   Usage Minimum = 0 */
	0x29,0x65,		/*   Usage Maximum = 101 */
	0x15,0x00,		/*   Logical Minimum = 0 */
	0x25,0x65,		/*   Logical Maximum = 101 */
	0x75,0x08,		/*   Report Size = 8 */
	0x95,0x01,		/*   Report Count = 1 */
	0x81,0x00,		/*  Input(Data,Variable,Array) */
	0xC0};			/* End Collection */
#endif

1.本文部分素材来源网络,版权归原作者所有,如涉及作品版权问题,请与我联系删除。

2.未经原作者允许不得转载本文内容,否则将视为侵权;

3.转载或者引用本文内容请注明来源及原作者;

4.对于不遵守此声明或者其他违法使用本文内容者,本人依法保留追究权等。

下面是我的个人微信公众号,关注【一个早起的程序员】精彩系列文章每天不断。

  • 19
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
gu8ConfigDescriptor是一个USB配置描述符数组,用于描述USB设备的配置信息。它通常由USB设备的制造商在设备固件中定义,由USB主机在插入设备时读取。 USB配置描述符包含了USB设备的配置信息,包括配置的唯一标识符、配置的描述信息、配置所需的最大功率、以及该配置所包含的所有接口和其他描述符的信息。 以下是一个典型的USB配置描述符的格式: ``` typedef struct { uint8_t bLength; // 描述符长度 uint8_t bDescriptorType; // 描述符类型 uint16_t wTotalLength; // 描述符总长度 uint8_t bNumInterfaces; // 接口数目 uint8_t bConfigurationValue; // 配置唯一标识符 uint8_t iConfiguration; // 配置描述信息 uint8_t bmAttributes; // 配置属性 uint8_t bMaxPower; // 配置所需的最大功率 } USB_ConfigurationDescriptorTypeDef; ``` 其中,bLength字段表示该描述符的长度;bDescriptorType字段表示该描述符的类型,这里应该为0x02,表示该描述符是一个配置描述符;wTotalLength字段表示该配置描述符及其后续的所有描述符的总长度;bNumInterfaces字段表示该配置所包含的接口数目;bConfigurationValue字段表示该配置的唯一标识符;iConfiguration字段表示该配置的描述信息的字符串索引;bmAttributes字段表示该配置的属性,包括是否需要供电、是否支持远程唤醒等;bMaxPower字段表示该配置所需的最大功率,单位为2mA。 在gu8ConfigDescriptor描述符数组中,每个USB配置描述符之后通常还会包括该配置所包含的所有接口的描述符和其他描述符,如字符串描述符、端点描述符等。这些描述符的总长度应该等于wTotalLength字段指定的长度。通过读取gu8ConfigDescriptor数组中的各个描述符USB主机可以了解到USB设备支持的配置信息、接口信息和传输方式等,从而选择最合适的驱动程序进行通信。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个早起的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值