Universal Serial Bus

Revision as of 07:50, 28 December 2006 by osdev>Jhawthorn
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Functioning

USB looks much more like a network protocol than like RS232 (good old serial cables). Data transmissions follow formatted packets rather than being made of plain characters. However, unlike network protocols like Ethernet, Token Ring, etc. all communications are directed by the host (i.e. your computer), and even 'interrupts' are actually polled by the host.

More information about this section can be found on Usb In A Nutshell (ch. 3)

Packets

These are the smallest formatted things that may transfer on the USB cable. Each USB packet at least have a SYNC header and a EOP trailer that carry no information but help in identifying packets boundaries. Each USB must also have a PID field (Packet IDentifier) that tells the role of the packet in a transfer or a transaction.

Transaction

A transaction is a "single sentence" between the host and a device. Transactions may be used to send/read data from the device, initiate transfers, set up parameters, get information, etc. Each transaction is typically made of 3 packets:

  1. a token packet that always comes from the host and carries the address of the device/endpoint concerned in the transaction. USB defines 4 types of tokens: SETUP (initiates a control transaction), IN (initiates a device->host data transaction) and OUT (initiates a host->device data transaction). Tokens are typically have a small fixed size.
  2. a data packet which carries the transaction payload. Depending on the USB version, transfer speed and type of data packet used (DATA0, DATA1, DATA2 or MDATA), the maximum payload may be 8, 64 or 1024.
  3. a handshake packet which informs the data emitter of the reception status. Handshake may be ACK (data received correctly), NAK (unable to receive/emit data right now, or no data to send) or STALL (device state invalid, host intervention required)

Transfers

Transactions are used to build more complex protocols like control transfer, interrupt transfer (single small sized status poll), isochronous transfer (periodic non-acknowledged packet transmission, like a sample to play on speakers) and bulk transfer (non-predictable large-sized transfers like a page to print)

More on USB transfers can be found on USB in a nutshell, ch 4

Configuration

The configuration part of the USB standard occurs through the notion of descriptors. Descriptors are blocks of information retrieved through the host controller which defines things like vendor/product identifiers for each device and class/subclass/protocol codes for each device's interface. Based on these informations, the Operating System can assign the proper driver to each device/interface.

A list of structures defining USB descriptors is available in usbdescr.h from Clicker's CVS (LGPL)

Endpoints

Configuration communications are performed on endpoint 0. The USB device will usually define more endpoints used as communication channels between the device and the host, link those endpoints to interfaces which can be assigned a class, subclass and protocol codes (identifying what the device is able to do). For instance a digital camera could offer a couple of endpoints to implement the USBstorage interface (for the camera's memory card) and other endpoints for a webcam interface.

Reading descriptors

The host has to explicitly request descriptors from the device before it manipulates them. This is achieved by a setup transfer using a GET_DESCRIPTOR as the host->device data and receiving the descriptor as the data from the host. The whole transfer will look like

  • command transaction:
Setup_TOKEN(addr=device, endpoint=0) : host -> device
DATA[ RequestType=0x80, Request=0x06, value=DESCR_TYPE|DESCR_SELECTOR,
    index=0, length=wished_length] : h->d, 8 bytes
ACK : host <- device
  • response transaction:
IN_TOKEN(addr=device, endpoint=0) : host -> device
DATA(the_descriptor) : host <- device (as much bytes as requested)
ACK : host -> device
  • confirm transaction:
OUT_TOKEN(addr=device, endpoint=0) : host -> device
DATA() : host -> device (empty)
ACK : host <- device

The DATA packet in the command transaction is called the "Setup Packet" (according to Beyond Logic), and carries almost all of the 'interesting' stuff:

  • the RequestType of 0x80 (DeviceToHost=0x80| StandardRequest=0| DeviceTargetted=0)
  • the Request (command) 0x06 for "GET_DESCRIPTOR"
  • the value (encoding unknown atm)