USB is a universal Bus and ports are unified. However, there are various USB devices, such as USB mouse, USB keyboard, and USB flash disks. How do USB hosts identify different devices? This depends on the descriptor.
USB descriptors include device descriptors, configuration descriptors, interface descriptors, endpoint descriptors, string descriptors, hid descriptors, and report descriptors. For details about the report descriptor, see Introduction to the USB hid report and report descriptor.
Http://group.ednchina.com/93/198.aspx.
A USB device has a device descriptor, which determines the number of configurations of the device. Each configuration descriptor corresponds to the configuration descriptor; in the configuration descriptor, the number of interfaces in the configuration is defined, and each interface has the corresponding interface descriptor. In the interface descriptor, the number of endpoints of the interface is defined, each endpoint corresponds to an endpoint descriptor, which defines the size and type of the endpoint. From this we can see that the relationship between the USB descriptors is one layer, the top layer is the device descriptor, the following is the configuration descriptor, then the interface descriptor, and then the endpoint descriptor. When obtaining the descriptor,
Get the device descriptor first, and then get the configuration descriptor. According to the length of the configuration set in the configuration descriptor, the configuration descriptor, interface descriptor, and Endpoint descriptor are read back at a time. The device serial number, vendor string, and product string may also be obtained.
Each descriptor has its own unique ID, as shown below:
# Define device_descriptor 0x01 // device descriptor
# Define configuration_descriptor 0x02 // configure the descriptor
# Define string_descriptor 0x03 // string Descriptor
# Define interface_descriptor 0x04 // interface Descriptor
# Define endpoint_descriptor 0x05 // endpoint Descriptor
Each descriptor is described in detail below.
1. device descriptor
// Define the standard device descriptor Structure
Typedef struct _ device_dcescriptor_struct
{
Byte blength; // The Byte size of the device descriptor
Byte bdescriptortype; // device descriptor type number
Word bcdusb; // USB Version
Byte bdeviceclass; // device code assigned by USB
Byte bdevicesubclass; // subclass code assigned by USB
Byte bdeviceprotocol; // protocol code of the device allocated by USB
Byte bmaxpacketsize0; // maximum package size of endpoint 0
Word idvendor; // vendor ID
Word idproduct; // product ID
Word bcddevice; // device factory id
Byte imanufacturer; // device manufacturer string Index
Byte iproduct; // index that describes the product string
Byte iserialnumber; // index that describes the device serial number string
Byte bnumconfigurations; // The number of possible configurations
}
Device_descriptor_struct, * pdevice_descriptor_struct;
// Actual device descriptor example
Code device_descriptor_struct device_descriptor = // device descriptor
{
Sizeof (device_descriptor_struct), // The number of bytes of the device descriptor, which is 18 bytes
Device_descriptor, // device descriptor type number, device descriptor is 01
0x1001, // USB version number, which is USB. Because 51 is a big-end mode, high/low bytes are exchanged.
0x00, // The device class code assigned by USB. 0 indicates that the type is defined in the interface descriptor.
0x00, // The Sub-class code assigned by USB. If the previous item is 0, this item must be set to 0.
0x00, // The protocol code of the device allocated by the USB. If the above parameter is set to 0, this item must also be set to 0.
0x10, // The maximum package size of the endpoint 0, which is 16 bytes
0x7104, // manufacturer ID. This is the ID number that needs to be applied with the USB organization, indicating the manufacturer code.
0xf0ff, // The product ID, used together with the vendor ID, allows the host to register the device and load the corresponding driver
0x0100, // device factory id
0x01, // device manufacturer string index. This index number is used to identify different strings when obtaining string descriptors.
0x02, // index that describes the product string, same as above
0x03, // index that describes the device serial number string, same as above
0x01 // The possible number of configurations is 1, that is, the device has only one Configuration
};
2. Configure the descriptor
// Define the standard configuration descriptor Structure
Typedef struct _ configuration_descriptor_struct
{
Byte blength; // configure the number of bytes of the descriptor
Byte bdescriptortype; // configure the descriptor type number
Word wtotallength; // the size of all data returned by this configuration
Byte bnuminterfaces; // number of interfaces supported by this configuration
Byte bconfigurationvalue; // The parameter value required by the set_configuration command
Byte iconfiguration; // the index value of the string that describes the configuration
Byte bmattributes; // Power Supply Mode Selection
Byte maxpower; // maximum current that the device extracts from the bus
}
Configuration_descriptor_struct, * pconfiguration_descriptor_struct;
2. Interface Descriptor
// Define the standard interface descriptor Structure
Typedef struct _ interface_descriptor_struct
{
Byte blength; // The number of bytes in the interface Descriptor
Byte bdescriptortype; // type Number of the interface Descriptor
Byte binterfacenumber; // the ID of this interface
Byte balternatesetting; // backup interface descriptor number
Byte bnumendpoints; // Number of endpoints used by this interface, excluding the number of endpoints 0
Byte binterfaceclass; // Interface Type
Byte binterfacesubclass; // interface subtype
Byte binterfaceprotocol; // protocol followed by the interface
Byte iinterface; // string index value that describes this interface
}
Interface_descriptor_struct, * pinterface_descriptor_struct;
4. endpoint Descriptor
// Define the standard endpoint descriptor Structure
Typedef struct _ endpoint_descriptor_struct
{
Byte blegth; // The number of bytes in the endpoint descriptor.
Byte bdescriptortype; // endpoint descriptor type number
Byte bendpointaddress; // endpoint address and input/output attributes
Byte bmattributes; // transmission type attribute of the endpoint
Word wmaxpacketsize; // maximum package size received and sent by the endpoint
Byte binterval; // interval at which the host queries the endpoint
}
Endpoint_descriptor_struct, * pendpoint_descriptor_struct;
The following is the definition of a configuration descriptor set.
Typedef struct _ con_int_endp_descriptor_struct
{
Configuration_descriptor_struct configuration_descriptor;
Interface_descriptor_struct interface_descritor;
Endpoint_descriptor_struct endpoint_descriptor [endpoint_number];
} Con_int_endp_descriptor_struct;
Example of configuring a descriptor set
Code con_int_endp_descriptor_struct con_int_endp_descriptor = // configure the descriptor set
{
// Configuration_descriptor // configure the descriptor
{
Sizeof (configuration_descriptor_struct), // configure the number of bytes of the descriptor. Here it is 9
Configuration_descriptor, // configure the descriptor type number, and the configuration descriptor is 2
(Sizeof (configuration_descriptor_struct) +
Sizeof (interface_descriptor_struct) +
Sizeof (endpoint_descriptor_struct) * endpoint_number) * 256 +
(Sizeof (configuration_descriptor_struct) +
Sizeof (interface_descriptor_struct) +
Sizeof (endpoint_descriptor_struct) * endpoint_number)/256, // configure the total size of the descriptor set
0x01, // contains only one interface
0x01, // the ID of the Configuration
0x00, // iconfiguration Field
0x80, // bus power supply, remote wakeup not supported
0xc8 // obtain the maximum current of 400mA from the bus
},
// Interface_descritor // interface Descriptor
{
Sizeof (interface_descriptor_struct), // The number of bytes of the interface descriptor, which is 9
Interface_descriptor, // ID of the interface descriptor type. The interface descriptor is 3.
0x00, // The interface number is 4
0x00, // the ID of this API descriptor is 0
Endpoint_number, // The number of non-0 endpoints is 2. Only the input and output of the endpoint master endpoint are used.
0x08, // defined as a USB large-capacity storage device
0x06, // subclass used to simplify the block command
0x50, // The protocol used. The Single Batch Transfer protocol is used here.
0x00 // interface descriptor string index, 0, indicating no string
},
// Endpoint_descriptor []
{
{// Master endpoint input description
Sizeof (endpoint_descriptor_struct), // The number of bytes of the endpoint descriptor, which is 7
Endpoint_descriptor, // ID of the endpoint descriptor type. The endpoint descriptor is 5.
Main_point_in, // endpoint number, main input endpoint
Endpoint_type_bulk, // transmission type used, batch transmission
0X4000, // The maximum package size supported by this endpoint, 64 bytes
0x00 // interrupt scan time, which is invalid for Batch Transfer
},
{// Main endpoint output description
Sizeof (endpoint_descriptor_struct), // The number of bytes of the endpoint descriptor, which is 7
Endpoint_descriptor, // ID of the endpoint descriptor type. The endpoint descriptor is 5.
Main_point_out, // endpoint number, Master output endpoint
Endpoint_type_bulk, // transmission type used, batch transmission
0X4000, // The maximum package size supported by this endpoint, 64 bytes
0x00 // interrupt scan time, which is invalid for Batch Transfer
}
}
};
The endpoint type is defined as follows:
// Define the endpoint type
# Define endpoint_type_control 0x00 // Control Transmission
# Define endpoint_type_isochronous 0x01 // Synchronous Transmission
# Define endpoint_type_bulk 0x02 // Batch Transfer
# Define endpoint_type_interrupt 0x03 // interrupt transmission
The endpoint number is defined as follows:
# Define main_point_out 0x02 // output endpoint 2
# Define main_point_in 0x82 // input endpoint 2