Los descriptores del USB sirven para identificar el dispositivo conectado y que el sistema operativo pueda instalar el driver sin necesidad de instalación previa (plug and play).

Trama del paquete de Setup

Antes de empezar con los descriptores, creo que conviene explicar cómo se compone el paquete del USB que llega desde el HOST.

Offset
Campo
Nº Bytes
Valor
Descripción
0
bmRequestType
1
Bit-Map
(leed después)
1
bRequest
1
valor
Petición
2
wValue
2
valor
Valor
4
wIndex
1
Índice u Offset
Índice
6
wLength
1
Cuenta
Número de bytes a transferir si es la fase de datos

bmRequestType se compone de:

  • b7 Dirección de la transmisión:
    • 0 = host-to-Device
    • 1 = Device-to-Host
  • b6..5 Tipo:
    • 0 = estandar
    • 1 = clase
    • 2 = vendedor
    • 3 = reservado
  • b4..0 Receptor:
    • 0 = dispositivo
    • 1 = Interfaz
    • 2 = Endpoint
    • 3 = otros
    • 4 = Reservado

Device Descriptor

Offset
Campo
Nº Bytes
Descripción
0
bLength
1
Tamaño del descriptor en bytes
1
bDescriptorType
1
Tipo del descriptor
2
bcdUSB
2
Versión del USB (ej., 2.10 es 0x0210)
4
bDeviceClass
1
Clase del dispositivo
5
bDeviceSubClass
1
Subclase del dispositivo
6
bDeviceProtocol
1
Protocolo del dispositivo
7
bMaxPacketSize
1
Tamaño máximo del endpoint cero (8,16,32,64)
8
idVendor
2
ID del fabricante
10
idProduct
2
ID del dispositivo
12
bcdDevice
2
Versión del protocolo USB máximo (i.e., V3.1 is 0x0301)
14
iManufacturer
1
Índice del string descriptor del fabricante
15
iProduct
2
Índice del string descriptor del dispositivo
16
iSerialNumber
1
Índice del string descriptor del número de serie
17
bNumConfigurations
1
Número de configuraciones

Los valores que puede tomar bDescriptorType son:

  • USB_DEVICE_DESCRIPTOR_TYPE: 0x01
  • USB_CONFIGURATION_DESCRIPTOR_TYPE: 0x02
  • USB_STRING_DESCRIPTOR_TYPE: 0x03
  • USB_INTERFACE_DESCRIPTOR_TYPE: 0x04
  • USB_ENDPOINT_DESCRIPTOR_TYPE: 0x05
  • USB_BOS_DESCRIPTOR_TYPE: 0x0F
  • USB_DEVICE_CAPABILITY_DESCRIPTOR_TYPE: 0x10
  • USB_HID_DESCRIPTOR_TYPE: 0x21
  • USB_REPORT_DESCRIPTOR_TYPE: 0x22
  • USB_PHYSICAL_DESCRIPTOR_TYPE: 0x23
  • USB_HUB_DESCRIPTOR_TYPE: 0x29
  • USB_SUPERSPEED_HUB_DESCRIPTOR_TYPE: 0x2A
  • USB_SS_ENDPOINT_COMPANION_DESCRIPTOR_TYPE: 0x30

bDeviceClass, bDeviceSubClass y bDeviceProtocol los usa el sistema operativo para encontrar el driver para el dispositivo.

idVendor se asigna comprando una licencia en www.usb.org aunque ya hay registros libres como OpenMoko Inc

Configuration Descriptor

Offset 
Campo 
Nº de bytes
Descripción 
0
bLength
1
Tamaño del descriptor en bytes
1
bDescriptorType
1
Tipo del descriptor (wValue)
2
wTotalLength
2
Tamaño total de los descriptroes unidos
4
bNumInterfaces
1
Número de interfaces
5
bConfigurationValue
1
Valor usado como argumento en esta configuración
6
iConfiguration
1
Índice del string descriptor de la configuración
7
bmAttributes
1
Atributos
8
MaxPower
1
La corriente máxima que puede consumir el dispositivo en mútiplos de 2mA

Como los descriptores de configuración, de interfaces, de endpoints y de unión de interfaces van en el mismo paquete, wTotalLength indica el tamaño de dicho paquete.

bmAttributes indica:

  • b7 reservado, poner a 1
  • b6 A 1 Self Powered, a 0 Bus Powered
  • b5 Remote Wakeup
  • .0 reservado , poner a 0.

Interface Descriptor

Offset 
Campo 
Nº de bytes
Descripción 
0
bLength
1
Tamaño del descriptor en bytes
1
bDescriptorType
1
Tipo de descriptor (wValue)
2
bInterfaceNumber
1
Número de la interface (si hay varias, sino un 0)
3
bAlternateSetting
1
Interface secundaria que soporta
4
bNumEndpoints
1
Número de endpoints que necesita
5
bInterfaceClass
1
Código de la clase
6
bInterfaceSubClass
1
Código de la subclase
7
bInterfaceProtocol
1
Código del protocolo
8
iInterface
1
Índice del string descriptor de la interface

bInterfaceNumber indica el índice de la interfaz en el caso de que bNumInterfaces del Configuration descriptor sea más de 1.

bAlternateSetting se utiliza para asignar una interfaz secundaria.

bInterfaceClass indica la utilidad genérica del dispositivo:

  • CLASS_PER_INTERFACE = 0x00 indica que cada interfaz da la información de su propia clase
  • CLASS_AUDIO = 0x01 Clase de audio
  • CLASS_COMM = 0x02 Clase de comunicaciones
  • CLASS_HID = 0x03 Clase de interacción humano máquina
  • CLASS_PHYSICAL = 0x05 Clase física
  • CLASS_PRINTER = 0x07 Impresoras
  • CLASS_PTP = 0x06 imágen
  • CLASS_MASS_STORAGE = 0x08 clase de almacenamiento
  • CLASS_HUB = 0x09 concentrador de dispositivos
  • CLASS_DATA = 0x0A clase de datos
  • CLASS_SMART_CARD = 0x0B clase de tarjeta de memoria
  • CLASS_CONTENT_SECURITY = 0x0D clase de contenido seguro
  • CLASS_VIDEO = 0x0E clase de video
  • CLASS_PERSONAL_HEALTHCARE = 0x0F clase de cuidado personal
  • CLASS_DIAGNOSTIC_DEVICE = 0xDC clase de dispositivos de diagnóstico
  • CLASS_WIRELESS = 0xE0 clase inalámbrica
  • CLASS_APPLICATION = 0xFE clase de aplicación
  • CLASS_VENDOR_SPEC = 0xFF clase específica del vendedor

Endpoint Descriptor

Offset 
Campo 
Nº de bytes 
Descrición 
0
bLength
1
Tamaño del descriptor en bytes
1
bDescriptorType
1
Tipo del descriptor
2
bEndpointAddress
1
Dirección del endpoint en el dispositivo descrita
3
bmAttributes
1
atributos
4
wMaxPacketSize
2
Tamaño máximo del paquete del endpoint. Los bits 12...11 indican el número de transacciones que se puede hacer en microframes.
6
bInterval
1
Intervalo de muestreo de las transferencias del endpoint en un rango de 1 a 255ms

bEndpointAddress:

  • Bits 3…0 nº del endpoint
  • Bits 6…4 Reservado, poner a 0
  • Bit 7 Dirección, ignorado en endpoints de control, 0=OUT, 1=IN

bmAttributes:

  • Bit 1..0 tipo de transferencia
    • 00 Control
    • 01 Sincronizada
    • 10 Bulk
    • 11 interrupción
  • Bits 2..7 reservado. Si es sincronizada:
    • Bits 3..2 tipo de sincronización (modo ISO):
      • 00 sin sicronización
      • 01 Asíncrona
      • 10 Adaptativa
      • 11 síncrona
    • Bits 5..4 tipo de uso (Modo ISO):
      • 00 Endpoint de datos
      • 01 Endpoint de feedback
      • 10 Endpoint de feedback de datos específico
      • 11 Reservado

String Descriptor

Da información para que sea entendible.

Los strings están codificados en UNICODE.

El índice 0 indica los idiomas que soporta el dispositivo. La lista de idiomas se puede encontrar en usb.org

Offset 
Campo 
Nº de bytes 
Descripción
0
bLength
1
Tamaño del descriptor en bytes
1
bDescriptorType
1
Tipo del descriptor
2
wLANGID[0]
2
Idiomas disponibles
...
...............................
2
 
2+2N
wLANGID[N-1]
2
 

Cuando el índice es mayor que 0, la información proporcionada por el fabricante

El resto de información tiene el siguiente patrón

Offset 
Campo 
Nº de bytes 
Descripción
0
bLength
1
Tamaño del descriptor en bytes
1
bDescriptorType
1
Tipo de descriptor
2
bString
n
 

bString puede ser el fabricante si es el string direccionado por iManufacturer, el producto si es el indicado por iProduct, etc.

Class Specific Descriptor

Algunas clases necesitan un descriptor para configurar el dispositivo.

Interface Association Descriptor

Si el dispositivo tiene varias interfaces, hay que indicar que todos los descriptores de interfaz corresponden al mismo dispositivo. Para ello existe el Association Descriptor.

Offset 
Campo 
Nº de bytes 
Descripción
0
bLength
1
Tamaño del descriptor en bytes
1
bDescriptorType
1
Tipo del descriptor
2
bFirstInterface
1
Número de la primera interfaz asociada a esta función
3
bInterfaceCount
1
Número de la interfaz contigua asociada a esta función
4
bFunctionClass
1
Corresponde con bInterfaceClass
5
bFunctionSubClass
1
Corresponde con bInterfaceSubClass
6
bFunctionProtocol
1
Corresponde con bInterfaceProtocol
7
iFunction
1
Índice del string de la función

El esquema de descriptores sería:

  1. Device descriptor
  2. Configuration descriptor
  3. Interface Association descriptor
  4. Interface descriptor
  5. Class Specific Descriptor
  6. Endpoint Descriptor/s
  7. Interface descriptor
  8. Class Specific Descriptor
  9. Endpoint Descriptor/s
  10. ....