USB Descriptors

Last modified by Microchip on 2023/11/10 11:19

Each Universal Serial Bus (USB) device has a set of descriptors. The descriptors are read by the host during enumeration. Descriptors inform the host of the following information about a device:

  • The version of USB supported by the device
  • Who made the device
  • How many ways the device can be configured by the host
  • The power consumed by each device configuration
  • The number and length of endpoints on the device
  • What type of transfer method is to be used to communicate with endpoints
  • How often the endpoints are to be serviced
  • What text to display if the host operating systems accept text descriptions

Descriptor Structure

There are several types of descriptors for USB devices arranged in a logical hierarchy. The following diagram illustrates the hierarchy of a descriptor for a single device with two possible configurations for the host to activate. Each of these configurations has a single interface with two endpoints.

usb descriptor table

Back to Top

Descriptor Types

The most commonly used descriptors include:

  • Device descriptor
  • Configuration descriptor
  • Interface descriptor
  • Endpoint descriptor
  • String descriptor

Every USB device must have one device descriptor and at least one each of the configuration, interface, and endpoint descriptors.

A full description of the Byte by Byte contents of the descriptor tables can be found in the USB specifications. This page explains some of the important features of each of the descriptor types and how they are used.

Back to Top

Device Descriptor

The device descriptor is the first descriptor read by the host during enumeration. The purpose of the device descriptor is to let the host know what specification of USB the device complies with and how many possible configurations are available on the device. Upon successful processing of the device descriptor, the host will read all the configuration descriptors.

Structure of a Device Descriptor

typedef struct _USB_DEVICE_DESCRIPTOR {
  UCHAR  bLength;
  UCHAR  bDescriptorType;
  USHORT bcdUSB;
  UCHAR  bDeviceClass;
  UCHAR  bDeviceSubClass;
  UCHAR  bDeviceProtocol;
  UCHAR  bMaxPacketSize0;
  USHORT idVendor;
  USHORT idProduct;
  USHORT bcdDevice;
  UCHAR  iManufacturer;
  UCHAR  iProduct;
  UCHAR  iSerialNumber;
  UCHAR  bNumConfigurations;
} USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;
Key Elements of a Device Descriptor
bcdUSBInforms the host of what version of USB the device supports
bDeviceClass00 - The device class is defined in the Interface Descriptor
FF - the device class is Vendor class
any other number is the specification for the class of this device
idVendor16-bit number assigned by USB.org to the product's manufacturer
idProduct16-bit product model ID assigned by the Vendor to this product
bNumConfigurationsHow many different configurations are available for this device

Note: All certified USB products must have a valid Vendor ID and Product ID. See the "Developing USB Applications with Microchip" page for details on obtaining these numbers

Back to Top

Configuration Descriptor

A device may have more than one configuration. Each device configuration is assigned a number. The configuration descriptor serves two purposes:

  1. Informs the host as to how many interfaces (i.e., virtual devices) are in the configuration: While it is common for a configuration to offer only one interface, devices that appear like two or more products have more than one interface.
  2. How much power the device will consume if this configuration is activated by the host: If the device is capable of controlling its power consumption, it may offer more than one configuration. Each configuration will advertise how much power would be consumed if the configuration were to be activated.

Structure of a Configuration Descriptor

typedef struct _USB_CONFIGURATION_DESCRIPTOR {
  UCHAR  bLength;
  UCHAR  bDescriptorType;
  USHORT wTotalLength;
  UCHAR  bNumInterfaces;
  UCHAR  bConfigurationValue;
  UCHAR  iConfiguration;
  UCHAR  bmAttributes;
  UCHAR  MaxPower;
} USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR;
Key Elements of Configuration Descriptor
bNuminterfacesNumber of Interface Descriptor tables available
MaxPowerPower load of this device if the Host activates this configuration

Back to Top

Interface Descriptor

An interface descriptor describes the details of the function of the product. Key elements include the number of endpoints on the device and which USB device class is implemented by the endpoints. For example, if the device were a keyboard, the specified device class would be Human Interface Device (HID) and the number of endpoints would be two. See the "USB Device Classes" page for details on how device classes are implemented in USB.

Structure of an Interface Descriptor

typedef struct _USB_INTERFACE_DESCRIPTOR {
  UCHAR bLength;
  UCHAR bDescriptorType;
  UCHAR bInterfaceNumber;
  UCHAR bAlternateSetting;
  UCHAR bNumEndpoints;
  UCHAR bInterfaceClass;

  UCHAR bInterfaceSubClass;
  UCHAR bInterfaceProtocol;
  UCHAR iInterface;
} USB_INTERFACE_DESCRIPTOR, *PUSB_INTERFACE_DESCRIPTOR;
Key Elements of an Interface Descriptor
bNumEndpointsNumber of endpoints in the interface
bInterfaceClassUSB device class used to set transfer types for the endpoints

Only one configuration can be active at any time. When a configuration is active, all of its interfaces and endpoints are available to the host. Devices that have multiple interfaces are referred to as composite devices. One physical product with one available USB connector would appear to the host as two separate devices. A keyboard with an integrated mouse (or trackball) is an example of a composite device.

Back to Top

Endpoint Descriptor

Each endpoint on a device has its own descriptor. The descriptor provides the endpoint address (i.e., endpoint number), the size of the endpoint, and the data transfer type used to access the endpoint.

typedef struct _USB_ENDPOINT_DESCRIPTOR {
  UCHAR  bLength;
  UCHAR  bDescriptorType;
  UCHAR  bEndpointAddress;
  UCHAR  bmAttributes;
  USHORT wMaxPacketSize;
  UCHAR  bInterval;
} USB_ENDPOINT_DESCRIPTOR, *PUSB_ENDPOINT_DESCRIPTOR;
Key Elements of Endpoint Descriptors 
bEndpointAddressThe address of the endpoint (i.e. endpoint number) 
wMaxPacketSizeLength of the endpoint 
bIntervalHow often in frames is this endpoint to be serviced by the host 

Note: Even though the device class will usually indicate the endpoint numbers and transfer types to be used, these items must be included in the endpoint descriptor.

Back to Top

String Descriptor

Strings descriptors are optional, human-readable strings that the host OS may display.

FieldSize
(in bytes)
Description
bLengthn + 2Size of the String Descriptor
bDescriptorTypes10x03 used for String Descriptors
bStringnUnicode string of length n

Back to Top

Learn More

Back to Top