4.1 设备描述符

功能概述

设备描述符(Device Descriptor)是 USB设备 的根描述符,包含设备的基本信息,如厂商ID、产品ID、设备类、支持的配置数量等。每个USB设备必须有且仅有一个设备描述符。

数据结构定义

struct usb_device_descriptor {
    uint8_t  bLength;            // 描述符长度(18字节)
    uint8_t  bDescriptorType;    // 描述符类型(固定为0x01)
    uint16_t bcdUSB;             // USB规范版本号(BCD码)
    uint8_t  bDeviceClass;       // 设备类代码
    uint8_t  bDeviceSubClass;    // 设备子类代码
    uint8_t  bDeviceProtocol;    // 设备协议代码
    uint8_t  bMaxPacketSize0;    // 端点0的最大包大小
    uint16_t idVendor;           // 厂商ID(由USB-IF分配)
    uint16_t idProduct;          // 产品ID(厂商自定义)
    uint16_t bcdDevice;          // 设备版本号(BCD码)
    uint8_t  iManufacturer;      // 厂商字符串描述符索引
    uint8_t  iProduct;           // 产品字符串描述符索引
    uint8_t  iSerialNumber;      // 序列号字符串描述符索引
    uint8_t  bNumConfigurations; // 支持的配置数量
} __attribute__ ((packed));

字段详解

字段名 大小 类型 描述
bLength 1 数字 描述符长度(固定为0x12,即18字节)
bDescriptorType 1 常量 描述符类型(设备描述符固定为0x01
bcdUSB 2 BCD码 设备兼容的USB规范版本(如0x0200表示USB 2.0)
bDeviceClass 1 设备类代码 设备类代码详见下表
bDeviceSubClass 1 子类 子类代码(依赖bDeviceClass
bDeviceProtocol 1 协议 协议代码(依赖bDeviceClassbDeviceSubClass
bMaxPacketSize0 1 数字 端点0的最大包大小(合法值:8, 16, 32, 64)
idVendor 2 ID 厂商ID(由USB-IF分配)
idProduct 2 ID 产品ID(厂商自定义)
bcdDevice 2 BCD码 设备版本号(如0x0100表示V1.0)
iManufacturer 1 索引 厂商字符串描述符索引(0表示无)
iProduct 1 索引 产品字符串描述符索引(0表示无)
iSerialNumber 1 索引 序列号字符串描述符索引(0表示无)
bNumConfigurations 1 数字 支持的配置描述符数量(至少为1

设备类代码(bDeviceClass)

值(十六进制) 类别描述
0x00 由接口描述符定义类
0x02 通信设备类(CDC)
0x09 集线器类
0xE0 无线控制器类
0xFF 厂商自定义类

示例(USB鼠标设备描述符)

字段 值(十六进制) 说明
bLength 0x12 描述符长度18字节
bDescriptorType 0x01 设备描述符类型
bcdUSB 0x0110 USB 1.1
bDeviceClass 0x00 由接口定义类
bDeviceSubClass 0x00 无子类
bDeviceProtocol 0x00 无协议
bMaxPacketSize0 0x08 端点0最大包8字节
idVendor 0x045E 微软公司
idProduct 0x0047 鼠标产品ID
bcdDevice 0x0300 设备版本3.0
iManufacturer 0x01 厂商字符串索引1
iProduct 0x02 产品字符串索引2
iSerialNumber 0x00 无序列号
bNumConfigurations 0x01 1个配置

关键说明

  1. 端点0所有USB设备必须支持端点0(控制端点),用于枚举和配置。
  2. 字符串描述符:索引值为0表示无对应字符串。
  3. 版本号:均以BCD码格式存储(如0x0200表示2.0)。
  4. 配置数量:即使设备只有一种工作模式,bNumConfigurations也必须≥1。

获取方式

主机通过控制传输的GET_DESCRIPTOR请求获取设备描述符:

struct usb_ctrlrequest {
    uint8_t  bmRequestType = 0x80; // 主机到设备
    uint8_t  bRequest = 0x06;       // GET_DESCRIPTOR
    uint16_t wValue = 0x0100;       // 高字节=0x01(设备描述符)
    uint16_t wIndex = 0x0000;       // 语言ID(0表示默认)
    uint16_t wLength = 0x0012;      // 请求长度(18字节)
};