欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

USB HID

发布时间:2023/12/15 编程问答 52 豆豆
生活随笔 收集整理的这篇文章主要介绍了 USB HID 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

文章目录

目录

一、USB简介

二、USB(HID)协议及描述符

1.USB描述符简介

2.USB描述符

  

一、USB简介

USB根据速度可分为:

  • 低速USB  Low Speed Device (LS)  
  • 全速USB Full Speed Device (FS)  
  • 高速USB设备 Hight Speed Device (HS)
  • 具体应用以及特性如下:

    一般USB接口有4根线,分别是VCC DM DP GND。DM,DP是数据线。

    USB的检测:

    每一个主机USB的DM, DP都有内部15K下拉到GND,没有外设插入情况下是低电平。在USB从设备中,如果设备是高速USB则在DP上加有1.5K上拉到VCC,如果是低速设备则在DM上加1.5K上拉到VCC。当DP或者DM被拉高就可以检测USB插入,并且可以区分是高速还是低速USB。

    二、USB(HID)协议及描述符

    1.USB描述符简介

    USB的硬件端口是统一的,但是USB设备却是多种多样的,USB主机根据USB设备的描述符来区分不同的USB设备。每一个USB设备都有自己的描述符,当插入USB设备之后,主机会向从机发送命令,从机收到命令之后,会返回特定的描述符信息。主机通过解析收到的描述符,来识别从机设备的相关信息,这个过程,就是设备枚举(enumeration)过程。

    USB有5种标准设备描述符,分别是:设备描述符、配置描述符、字符串描述符、接口描述符、端点描述符。

    另外还有:HID描述符、报告描述符等各个类特有的描述符。见下表:

    要注意的是,设备描述符有且只有一个。其包含关系如下图所示。

    2.USB描述符

             2.1 USB设备描述符

    设备描述符有且仅有一个!

    描述符使用到的宏定义如下:

    #define USB_DEVICE_DESCRIPTOR_TYPE              0x01#define USB_CONFIGURATION_DESCRIPTOR_TYPE       0x02#define USB_STRING_DESCRIPTOR_TYPE              0x03#define USB_INTERFACE_DESCRIPTOR_TYPE           0x04#define USB_ENDPOINT_DESCRIPTOR_TYPE            0x05#define HID_DESCRIPTOR_TYPE                     0x21

    设备描述符类型定义固定为0x01

    USB HID设备的设备描述符代码例子(STM32 USB HID)如下:

    /* USB Standard Device Descriptor */ const uint8_t CustomHID_DeviceDescriptor[CUSTOMHID_SIZ_DEVICE_DESC] ={0x12, /*bLength */USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/0x00, /*bcdUSB */0x02,0x00, /*bDeviceClass*/0x00, /*bDeviceSubClass*/0x00, /*bDeviceProtocol*/0x40, /*bMaxPacketSize40*/0x83, /*idVendor (0x0483)*/0x04,0x50, /*idProduct = 0x5750*/0x57,0x00, /*bcdDevice rel. 2.00*/0x02,1, /*Index of string descriptor describingmanufacturer */2, /*Index of string descriptor describingproduct*/3, /*Index of string descriptor describing thedevice serial number */0x01 /*bNumConfigurations*/}; /* CustomHID_DeviceDescriptor */

    其结构成员意义如下:

    (1)bLength

    描述符长度(18字节,十六进制为0x12),就是标志描述符数据结构的长度。

    (2)bDescriptorType

    bDescriptorType代表了本描述符的类型,设备描述符为0x01 (设备描述符固定为0x01)

    (3)bcdUSB

        USB协议版本,表示形式0xJJMN版本JJ.M.N(JJ  - 主要版本号,M  - 次要版本号,N  - 次要版本)

        例子:如果是USB2.0,写成:0200H;如果是USB1.1,写成:0110H 如果是USB3.11,写成:0311H

    (4)bDeviceClass、bDeviceSubClass、bDeviceProtocol

        bDeviceClass、bDeviceSubClass、bDeviceProtocol分别代表设备类型,子类型,设备使用的协议,USB-IF区分设备类分了三个等级(类-子类-协议码)其中,类包含人机交互类、图像类、无线类、音频类等等,子类比如音频类的音频控制、音频流等等,协议比如人机接口类中的鼠标、键盘、触摸屏等,为何会有这么多USB的Class分类,子分类,设备协议。我们要知道,USB协议设计的目的,就是为实现通用,用单一的USB接口取代之前种类繁多的各种其他接口。而为了取代其他各种接口,那意味着就要实现各种设备所对应的各种功能。如下图显示USB设备的各种类别,USB设备类信息更详细内容可进入https://www.usb.org/defined-class-codes查看。

    (5)bMaxPackeSize0

    就是端点一次最大传多少个字节。USB协议里有规定,端点0最低8字节,端点的最大传输大小和USB速度等级以及传输类型有关,控制传输一般使用端点0,低速最大8字节,全速和高速最大传输64字节,如下图:

    (6)idVender

        厂商ID,就是个2字节的编号,由USB协议分配,厂商申请时需要交费。自己随便写的话,仅限于学习、测试的情况下,不能用做产品。

    (7)idProduct

        产品ID,厂家自己随便定义。

    (8)bcdDevice

        产品版本号,厂家自己随便定义。

    (9)iManufacturer

        描述厂商的字符串的索引,为0则表示没有。

    (10)iProduct

        描述产品的字符串的索引,为0则表示没有。

    (11)iSerialNumber

        产品序列号字符串的索引,为0则表示没有。

    (12)bNumConfigurations

    指示设备由多少个配置,前面提到过,一个USB可能有多个配置,一般USB产品都是1个配置。

            2.2 配置描述符

    配置描述符至少有一个,可以有多个,一般一个设备只设置一个配置描述符。

    配置描述符类型定义固定为0x02

    USB HID设备的配置描述符代码例子(STM32 USB HID)如下:(注意其中除了配置描述符还包括其他如接口描述符和端点描述符)

    /* USB Configuration Descriptor */ /* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */ const uint8_t CustomHID_ConfigDescriptor[CUSTOMHID_SIZ_CONFIG_DESC] = {0x09, /* bLength: Configuration Descriptor size */USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */CUSTOMHID_SIZ_CONFIG_DESC,/* wTotalLength: Bytes returned */0x00,0x01, /* bNumInterfaces: 1 interface */0x01, /* bConfigurationValue: Configuration value */0x00, /* iConfiguration: Index of string descriptor describingthe configuration*/0xC0, /* bmAttributes: Self powered */0x32, /* MaxPower 100 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 *//******************** Descriptor of Custom HID HID ********************//* 18 */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,/******************** Descriptor of Custom HID endpoints ******************//* 27 */0x07, /* bLength: Endpoint Descriptor size */USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */0x81, /* bEndpointAddress: Endpoint Address (IN) */0x03, /* bmAttributes: Interrupt endpoint */0x02, /* wMaxPacketSize: 2 Bytes max */0x00,0x20, /* bInterval: Polling Interval (32 ms) *//* 34 */0x07, /* bLength: Endpoint Descriptor size */USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: *//* Endpoint descriptor type */0x01, /* bEndpointAddress: *//* Endpoint Address (OUT) */0x03, /* bmAttributes: Interrupt endpoint */0x02, /* wMaxPacketSize: 2 Bytes max */0x00,0x20, /* bInterval: Polling Interval (20 ms) *//* 41 */}; /* CustomHID_ConfigDescriptor */

    其中配置描述符代码段:

    0x09, /* bLength: Configuration Descriptor size */USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */CUSTOMHID_SIZ_CONFIG_DESC,/* wTotalLength: Bytes returned */0x00,0x01, /* bNumInterfaces: 1 interface */0x01, /* bConfigurationValue: Configuration value */0x00, /* iConfiguration: Index of string descriptor describingthe configuration*/0xC0, /* bmAttributes: Self powered */0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */

    配置描述符的各个域的意义如下:

    bLength:大小为1字节,表示该描述符的长度。标准的USB配置描述符的长度为9字节。

    bDescriptorType:配置描述符的类型。

    wTotalLength:表示整个配置描述符集合的总长度,包括配置描述符、接口描述符、端点描述符和类特殊描述符(HID类)。注意低字节在前。

    bNumInterfaces:该配置描述符所支持的接口数量(接口编号数量而不是接口描述符数量,不同的接口描述符可能使用同一个编号接口)。功能单一设备只有一个,而复合设备则具有多个接口。

    bConfigurationValue:表示该配置的值。通常一个USB设备可以支持多个配置,bConfigurationValue就是每个配置的标识。

    iConfiguration:描述该配置的字符串的索引值。如果该值为0,则表示没有字符串。

    bmAttributes:用来描设备的一些特性。其中,D7是保留的,必须要设置为1。D6表示供电方式,D6=1时,表示设备自供电;D6=0时,表示设备时总线供电。D5表示是否支持远程唤醒,D5=1时,支持远程唤醒。D4~D0保留,设置为0

    bMaxPower:表示设备需要从总线获取的最大电流量,单位为2mA。如需要200mA的最大电流,则该字节的值为100

            2.3 接口描述符

    如上面代码中

    /************** 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的接口描述符。


    USB_INTERFACE_DESCRIPTOR_TYPE为固定值表示该配置是接口描述符。

    bNumEndpoints,该接口使用的端点个数。注意一点,这个端点个数不包括0端点。

    bInterfaceClass的定义如下表:

    bInterfaceSubClass 除带有由接口定义的类的设备外,此字段于设备描述符中的bDeviceSubClass 相同。若 bInterfaceClass 等于00h,bInterfaceSubClass 也必须等于 00h。若 bInterfaceClass 取从 01h到FEh的值,bInterfaceSubClass则等于00h或等于一个为接口的类定义的值。FFh表明为厂商定义的子类。

        bInterfaceProtocol 除了带有接口定义的类的设备外,此字段于设备描述符中的bDeviceProtocol相同。此字段可为所选bInterfaceClass和bInterfaceSubClass 所规定的协议。若bInterfaceClass取从01h到FEh的值,bInterfaceProtocol必须等于00h,或等于为接口的类定义的值。FFh表明为厂商定义的协议。

        iInterface 是指向描述接口的字符串的索引。若没有字符串描述符,该值为0.

            2.4HID描述符

    上面在接口描述符中定义了设备类型为0x03的HID设备,那么需要定义HID描述符,上面代码中HID描述符代码如下:

    /* 18 */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,

    bcdHID为0x0110,表面该HID协议为1.1版本

    bCountryCode: 设备所适用的国家。如果使用的键盘是美式键盘,代码为33,即0x21

    bNumDescriptors:下级描述符的数量。这个值至少为1,也就是HID类设备至少要有一个报告描述符。下级描述符可以是报告描述符或者物理描述符。

    wItemLength: 报告描述符的总长度。

      2.5 端点描述符

    上面HID的端点描述符代码:

    /******************** Descriptor of Custom HID endpoints ******************//* 27 */0x07, /* bLength: Endpoint Descriptor size */USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */0x81, /* bEndpointAddress: Endpoint Address (IN) */0x03, /* bmAttributes: Interrupt endpoint */0x02, /* wMaxPacketSize: 2 Bytes max */0x00, 0x20, /* bInterval: Polling Interval (32 ms) */

    bEndpointAddress: bit7 :方向  1/0 :in/out,对于控制端点可以忽略;bit4~bit6 保留,bit3~bit0:端点号 

    bmAttributes,属性。如下

    bit1~bit0:

    00 = Control-控制传输

    01 = Isochronous-等时传输

    10 = Bulk-批量传输

    11 = Interrupt-中断传输

    如果不是一个等时传输端点,第5~2位是保留的,必须设置为0。如果它是等时的,则定义如下:

    Bits 3..2: Synchronization Type-同步类型

    00 = No Synchronization-无同步

    01 = Asynchronous-异步

    10 = Adaptive-适配

    11 = Synchronous-同步

    /*Bits 5..4: Usage Type-用途*/

    00 = Data endpoint-数据端点

    01 = Feedback endpoint-反馈端点

    10 = Implicit feedback Data endpoint-暗含反馈的数据端点

    11 = Reserved-保留

    wMaxPackeSize,端点支持的最大包长。对于等时端点,此值用于在调度中保留总线时间,这是每(微)帧数据有效负载所需的时间。在进行中,管道实际使用的带宽可能比保留的带宽少。如果有必要,设备会报告通过其正常的、非usb定义的机制所使用的实际带宽。

    对于所有的端点,bit10~bit0指定最大数据包大小(以字节为单位)。

    /*5.对于高速同步和中断端点:bit12~bit11指定每个微帧的额外通信次数:

    00 = None (1 transaction per microframe)

    01 = 1 additional (2 per microframe)

    10 = 2 additional (3 per microframe)

    11 = Reserved

    bInterval,查询时间,说白了就是主机多久和设备通讯一次。根据设备运行速度以帧或微帧表示。

    对于全/高速等时端点,此值必须在1到16之间。bInterval值用作2的指数;例如,bInterval为4,表示周期为8, 2(4 – 1)。

    对于全速/低速中断端点,该字段的值可以是1到255。

    对于高速中断端点,使用bInterval值作为2的指数;例如,bInterval为4表示周期为8 ,2(4-1)。这个值必须在1到16之间。

    对于高速批量/控制输出端点,bInterval必须指定端点的最大NAK速率。值0表示端点永不NAK。其它值表示每个微帧的bInterval数最多1个NAK。这个值的范围必须在0到255之间。

    2.6 报告描述符

    报告描述符包含多个报告,不同的报告通过报告ID来识别,报告的第一个字节就是报告ID。当报告描述符中没有定义报告ID时,开始就是数据。

    报告描述符由条目(item)来组成,一个条目占据一行。HID协议规定了两种条目:短条目和长条目,常用的是短条目。

    短条目的构成:一字节的前缀 + 可选的数据字节。可选的数据字节可以是0、1、2、4字节。实际中所使用的条目,大部分是1字节的可选数据

    一个条目前缀如下

    bSize:bit1~bit0后面紧跟的字节数

    总结

    以上是生活随笔为你收集整理的USB HID的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。