USB键盘实现——设备描述符(一)

  • Post author:
  • Post category:其他




设备描述符

设备描述符内容解析和

HID鼠标

一致。



仓库地址


仓库地址



获取设备描述符请求



标准设备请求

typedef struct __attribute__ ((packed)){
    union {
        struct __attribute__ ((packed)) {
          uint8_t recipient :  5; ///< Recipient type usb_request_recipient_t.
          uint8_t type      :  2; ///< Request type usb_request_type_t.
          uint8_t direction :  1; ///< Direction type. usb_dir_t
        } bmRequestType_bit;

        uint8_t bmRequestType;
    };

    uint8_t  bRequest;
    uint16_t wValue;
    uint16_t wIndex;
    uint16_t wLength;
} usb_control_request_t;



USB 控制端点收到的数据

0x80 0x6 0x0 0x1 0x0 0x0 0x40 0x0
  • bmRequestType:0x80

    • 数据传输方向为 1,device-to-host
    • 标准请求
    • 请求的接收者为设备
  • bRequest:0x06

    • GET_DESCRIPTOR 获取描述符请求
  • wValue:0x0001(LSB)

    • 低位:0x01 设备描述符
    • 高位:0x00 索引号
  • wIndex:0x0000(LSB)

    • 低位:0x00
    • 高位:0x00
  • wLength:0x40

    • 低位:0x40 请求返回的字节数为 0x40,设备实际返回的字节数可以比该域指定的字节数少
    • 高位:0x00



设备描述符返回



设备描述符实现

usb_desc_device_t const desc_device =
{
    .bLength            = sizeof(usb_desc_device_t),
    .bDescriptorType    = USB_DESC_DEVICE,
    .bcdUSB             = 0x0200,
    .bDeviceClass       = 0x00,
    .bDeviceSubClass    = 0x00,
    .bDeviceProtocol    = 0x00,
    .bMaxPacketSize0    = 0x40,

    .idVendor           = 0xCafe,
    .idProduct          = USB_PID,
    .bcdDevice          = 0x0100,

    .iManufacturer      = 0x01,
    .iProduct           = 0x02,
    .iSerialNumber      = 0x03,

    .bNumConfigurations = 0x01
};



设备描述符数据

0x12 0x1 0x0 0x2 0x0 0x0 0x0 0x40 0xfe 0xca 0x8 0x40 0x0 0x1 0x1 0x2 0x3 0x1



设备描述符分析

  • bLength:0x12

    • 表示该描述符的长度。设备描述符的长度为 18 字节,写成十六进制就是 0x12。
  • bDescriptorType:0x01

    • 描述符类型。设备描述符的编号为 0x01。
  • bcdUSB:0x00 0x02

    • 2 字节,该设备所使用的 USB 协议的版本。USB2.0 就是 0x0200,USB1.1 就是 0x0110。实际传输的时候是低字节在前的。
  • bDeviceClass:0x00

    • 是设备所使用的类代码,不在设备描述符中定义设备类,而在接口描述符中定义设备类,所以该字段的值设置为 0。
  • bDeviceSubClass:0x00

    • 是设备所使用子类代码,bDeviceClass字段为0时,该字段也为0。
  • bDeviceProtocol:0x00

    • 是设备所使用的协议,协议代码由 USB 协会规定。
  • bMaxPacketSize0:0x40

    • 端点 0 的最大包长。它的取值可以是 8 16 32 64,这里设置为 64。
  • idVender:0xCafe

    • 2 字节,厂商 ID
  • idProduct:0x4008

    • 2 字节,产品 ID
  • bcdDevice:0x0100

    • 2 字节,设备的版本号
  • iManufacturer:0x01

    • 描述厂商的字符串的索引值,获取字符串描述符时,对应的索引需要返回相应的描述符。
  • iProduct:0x02

    • 描述产品的字符串索引值,获取字符串描述符时,对应的索引需要返回相应的描述符。
  • iSerialNumber:0x03

    • 设备的序列号字符串索引值,获取字符串描述符时,对应的索引需要返回相应的描述符。
  • bNumberConfigurations:0x01

    • 表示该设备有多少种配置,当前只用了一种配置



附 STM32 枚举日志

HID 键盘枚举日志

suspend int
bus reset int
enum done int
rxflvl int
setup packed recvd
setup packed done
output ep int 
h->d: 0x80 0x6 0x0 0x1 0x0 0x0 0x40 0x0 
dcd xfer 12
input ep int 
d->h :0x12 0x1 0x0 0x2 0x0 0x0 0x0 0x40 0xfe 0xca 0x8 0x40 0x0 0x1 0x1 0x2 0x3 0x1 
turn off txfe
input ep int 
edpt int send xfer complete event
dcd xfer 0
rxflvl int
bus reset int
output ep int 
send xfer complete event
enum done int
rxflvl int
setup packed recvd
setup packed done
output ep int 
h->d: 0x0 0x5 0x4 0x0 0x0 0x0 0x0 0x0 
dcd xfer 0
input ep int 
edpt int send xfer complete event
rxflvl int
setup packed recvd
setup packed done
output ep int 
h->d: 0x80 0x6 0x0 0x1 0x0 0x0 0x12 0x0 
dcd xfer 12
input ep int 
d->h :0x12 0x1 0x0 0x2 0x0 0x0 0x0 0x40 0xfe 0xca 0x8 0x40 0x0 0x1 0x1 0x2 0x3 0x1 
turn off txfe
input ep int 
edpt int send xfer complete event
dcd xfer 0
rxflvl int
output ep int 
send xfer complete event
rxflvl int
setup packed recvd
setup packed done
output ep int 
h->d: 0x80 0x6 0x0 0x2 0x0 0x0 0xff 0x0 
dcd xfer 22
input ep int 
d->h :0x9 0x2 0x22 0x0 0x1 0x1 0x0 0xa0 0x32 0x9 0x4 0x0 0x0 0x1 0x3 0x1 0x1 0x0 0x9 0x21 0x11 0x1 0x0 0x1 0x22 0x41 0x0 0x7 0x5 0x81 0x3 0x8 0x0 0xa 
turn off txfe
input ep int 
edpt int send xfer complete event
dcd xfer 0
rxflvl int
setup packed recvd
setup packed done
output ep int 
h->d: 0x80 0x6 0x3 0x3 0x9 0x4 0xff 0x0 
send xfer complete event
dcd xfer e
input ep int 
d->h :0xe 0x3 0x31 0x0 0x32 0x0 0x33 0x0 0x34 0x0 0x35 0x0 0x36 0x0 
turn off txfe
input ep int 
edpt int send xfer complete event
dcd xfer 0
rxflvl int
setup packed recvd
setup packed done
output ep int 
h->d: 0x80 0x6 0x0 0x3 0x0 0x0 0xff 0x0 
send xfer complete event
dcd xfer 4
input ep int 
d->h :0x4 0x3 0x9 0x4 
turn off txfe
input ep int 
edpt int send xfer complete event
dcd xfer 0
rxflvl int
setup packed recvd
setup packed done
output ep int 
h->d: 0x80 0x6 0x2 0x3 0x9 0x4 0xff 0x0 
send xfer complete event
dcd xfer 1e
input ep int 
d->h :0x1e 0x3 0x74 0x0 0x79 0x0 0x75 0x0 0x73 0x0 0x74 0x0 0x6c 0x0 0x69 0x0 0x20 0x0 0x44 0x0 0x65 0x0 0x76 0x0 0x69 0x0 0x63 0x0 0x65 0x0 
turn off txfe
input ep int 
edpt int send xfer complete event
dcd xfer 0
rxflvl int
setup packed recvd
setup packed done
output ep int 
h->d: 0x80 0x6 0x0 0x6 0x0 0x0 0xa 0x0 
send xfer complete event
get device qualifier
stall ep0
rxflvl int
setup packed recvd
setup packed done
output ep int 
h->d: 0x80 0x6 0x0 0x1 0x0 0x0 0x12 0x0 
dcd xfer 12
input ep int 
d->h :0x12 0x1 0x0 0x2 0x0 0x0 0x0 0x40 0xfe 0xca 0x8 0x40 0x0 0x1 0x1 0x2 0x3 0x1 
turn off txfe
input ep int 
edpt int send xfer complete event
dcd xfer 0
rxflvl int
setup packed recvd
setup packed done
output ep int 
h->d: 0x80 0x6 0x0 0x2 0x0 0x0 0x9 0x0 
send xfer complete event
dcd xfer 9
input ep int 
d->h :0x9 0x2 0x22 0x0 0x1 0x1 0x0 0xa0 0x32 
turn off txfe
input ep int 
edpt int send xfer complete event
dcd xfer 0
rxflvl int
setup packed recvd
setup packed done
output ep int 
h->d: 0x80 0x6 0x0 0x2 0x0 0x0 0x22 0x0 
send xfer complete event
dcd xfer 22
input ep int 
d->h :0x9 0x2 0x22 0x0 0x1 0x1 0x0 0xa0 0x32 0x9 0x4 0x0 0x0 0x1 0x3 0x1 0x1 0x0 0x9 0x21 0x11 0x1 0x0 0x1 0x22 0x41 0x0 0x7 0x5 0x81 0x3 0x8 0x0 0xa 
turn off txfe
input ep int 
edpt int send xfer complete event
dcd xfer 0
rxflvl int
setup packed recvd
setup packed done
output ep int 
h->d: 0x0 0x9 0x1 0x0 0x0 0x0 0x0 0x0 
send xfer complete event
edpt open
dcd xfer 0
input ep int 
edpt int send xfer complete event
rxflvl int
setup packed recvd
setup packed done
output ep int 
h->d: 0x21 0xa 0x0 0x0 0x0 0x0 0x0 0x0 
dcd xfer 0
input ep int 
edpt int send xfer complete event
rxflvl int
setup packed recvd
setup packed done
output ep int 
h->d: 0x81 0x6 0x0 0x22 0x0 0x0 0x81 0x0 
dcd xfer 40
input ep int 
d->h :0x5 0x1 0x9 0x6 0xa1 0x1 0x5 0x7 0x19 0xe0 0x29 0xe7 0x15 0x0 0x25 0x1 0x95 0x8 0x75 0x1 0x81 0x2 0x95 0x1 0x75 0x8 0x81 0x1 0x5 0x8 0x19 0x1 0x29 0x5 0x95 0x5 0x75 0x1 0x91 0x2 0x95 0x1 0x75 0x3 0x91 0x1 0x5 0x7 0x19 0x0 0x2a 0xff 0x0 0x15 0x0 0x26 0xff 0x0 0x95 0x6 0x75 0x8 0x81 0x0 
turn off txfe
input ep int 
edpt int send xfer complete event
dcd xfer 1
input ep int 
d->h :0xc0 
turn off txfe
input ep int 
edpt int send xfer complete event
dcd xfer 0
rxflvl int
output ep int 
send xfer complete event
rxflvl int
setup packed recvd
setup packed done
output ep int 
h->d: 0x21 0x9 0x0 0x2 0x0 0x0 0x1 0x0 
dcd xfer 1
rxflvl int
output ep int 
send xfer complete event
dcd xfer 0
input ep int 
edpt int send xfer complete event
rxflvl int
setup packed recvd
setup packed done
output ep int 
h->d: 0x80 0x6 0x0 0x3 0x0 0x0 0xff 0x0 
dcd xfer 4
input ep int 
d->h :0x4 0x3 0x9 0x4 
turn off txfe
input ep int 
edpt int send xfer complete event
dcd xfer 0
rxflvl int
setup packed recvd
setup packed done
output ep int 
h->d: 0x80 0x6 0x1 0x3 0x9 0x4 0xff 0x0 
send xfer complete event
dcd xfer 10
input ep int 
d->h :0x10 0x3 0x74 0x0 0x79 0x0 0x75 0x0 0x73 0x0 0x74 0x0 0x6c 0x0 0x69 0x0 
turn off txfe
input ep int 
edpt int send xfer complete event
dcd xfer 0
rxflvl int
setup packed recvd
setup packed done
output ep int 
h->d: 0x80 0x6 0x2 0x3 0x9 0x4 0xff 0x0 
send xfer complete event
dcd xfer 1e
input ep int 
d->h :0x1e 0x3 0x74 0x0 0x79 0x0 0x75 0x0 0x73 0x0 0x74 0x0 0x6c 0x0 0x69 0x0 0x20 0x0 0x44 0x0 0x65 0x0 0x76 0x0 0x69 0x0 0x63 0x0 0x65 0x0 
turn off txfe
input ep int 
edpt int send xfer complete event
dcd xfer 0
rxflvl int
output ep int 
send xfer complete event
dcd xfer 8
0x0 0x0 0x4 0x0 0x0 0x0 0x0 0x0 
input ep int 
d->h :0x0 0x0 0x4 0x0 0x0 0x0 0x0 0x0 
turn off txfe
input ep int 
edpt int send xfer complete event
dcd xfer 8
0x0 0x0 0x4 0x0 0x0 0x0 0x0 0x0 
input ep int 
d->h :0x0 0x0 0x4 0x0 0x0 0x0 0x0 0x0 
turn off txfe
input ep int 
edpt int send xfer complete event
dcd xfer 8
0x0 0x0 0x4 0x0 0x0 0x0 0x0 0x0 
input ep int 
d->h :0x0 0x0 0x4 0x0 0x0 0x0 0x0 0x0 
turn off txfe
input ep int 
edpt int send xfer complete event
dcd xfer 8
0x0 0x0 0x4 0x0 0x0 0x0 0x0 0x0 
input ep int 
d->h :0x0 0x0 0x4 0x0 0x0 0x0 0x0 0x0 
turn off txfe
input ep int 
edpt int send xfer complete event
dcd xfer 8
0x0 0x0 0x4 0x0 0x0 0x0 0x0 0x0 
input ep int 
d->h :0x0 0x0 0x4 0x0 0x0 0x0 0x0 0x0 
turn off txfe
input ep int 
edpt int send xfer complete event
dcd xfer 8
0x0 0x0 0x4 0x0 0x0 0x0 0x0 0x0 
input ep int 
d->h :0x0 0x0 0x4 0x0 0x0 0x0 0x0 0x0 
turn off txfe
input ep int 
edpt int send xfer complete event
dcd xfer 8
0x0 0x0 0x4 0x0 0x0 0x0 0x0 0x0 
input ep int 
d->h :0x0 0x0 0x4 0x0 0x0 0x0 0x0 0x0 
turn off txfe
input ep int 
edpt int send xfer complete event
dcd xfer 8
0x0 0x0 0x4 0x0 0x0 0x0 0x0 0x0 
input ep int 
d->h :0x0 0x0 0x4 0x0 0x0 0x0 0x0 0x0 
turn off txfe
input ep int 
edpt int send xfer complete event
dcd xfer 8
0x0 0x0 0x4 0x0 0x0 0x0 0x0 0x0 
input ep int 
d->h :0x0 0x0 0x4 0x0 0x0 0x0 0x0 0x0 
turn off txfe
input ep int 
edpt int send xfer complete event
dcd xfer 8
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
input ep int 
d->h :0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
turn off txfe
input ep int 
edpt int send xfer complete event



版权声明:本文为tyustli原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。