The USB Programming Model

USB, the Universal Serial Bus, is designed to be able to connect practically any kind of peripheral to a PC. This makes it more versatile than any port which came before, but this versatility comes at a cost in terms of the complication of communicating with it. However, in practice much of this complication is hidden from the programmer; rather than needing to program drivers to communicate with the port directly, each operating system which supports USB provides a set of API calls for signalling to and from the port.

In addition to the raw API calls, both Linux and Windows (from Win 95 OSR 2.1 onwards) provide sets of ready-made class drivers, each designed to service a whole class of device. For example: Imaging Devices, such as cameras, scanners and so on; Audio Devices, like microphones and speakers; and Human Interface Devices, which include practically any peripheral which allows the user to interact with the machine: Keyboards, joysticks and mice, obviously, but also any number other devices which feature buttons, sliders or switches of any sort (including many devices which also fall into one or more of the other categories). The HID class is very powerful, but it only supports USB's low-speed data transfer rate of 1.5Mb/s. The faster rate of 12Mb/s is needed by peripherals which transfers significant amounts of audiovisual data, while the extra-fast rate of 480Mb/s introduced with USB 2.0 will allow pretty good quality real-time video to be input or output.

USB uses a multi-layered architecture for drivers, which means that rather than one driver providing for the whole range of communication between PC and peripheral there will typically be two or more drivers (usually at least four for USB) involved in communicating with any one peripheral. This approach is superficially more complex than having a single driver per peripheral, but in fact it makes things simpler for people writing or using drivers because it avoids unnecessary duplication of code; common functionality (such as communicating with the USB hub) can be handled by shared drivers.

Windows divides drivers into two types: Device drivers and bus drivers. Device drivers handle tasks which are specific to a single device or class of devices, while bus drivers handle tasks associated more generally with a bus. An application using a peripheral may communicate with one or more device drivers (in many cases, the two HID drivers plus one of the other class drivers). The device driver(s) in turn sends data down through three separate bus drivers. The first of these is the Hub Driver, which initialises ports and manages interactions between the device drivers and the next bus driver: The USB Bus-Class Driver. This is in charge of enumeration, power and general USB transactions, and intermediates between the Hub Driver and the final bus driver, the Host Controller Driver. This communicates directly with the hardware.

From Windows 98 on, drivers in Windows generally fit into a common framework called the WDM, the Win32 Device Model (before this Windows NT and Windows 95 used quite different driver models, forcing people to write separate drivers in order to support both OSs; Win 98 continues to support older drivers). Communication between drivers in Windows is achieved by means of Interrupt Request Packets (IRPs).

USB supports four distinct types of transfer:


References

  • Jan Axelson, HIDs Up, Embedded Systems Programming October 2000.
  • Jan Axelson, USB Complete (Introduction & Chapter 1 only), http://www.lvr.com
  • Jack G. Ganssle, An Introduction to USB Development Embedded Systems Programming
  • www.usb.org, Approved Class Specification Documents.
  • Microsoft Corporation, WDM:Human Interface Device Class Support, http://www.microsoft.com/hwdev/desinit/WDMINput.HTM
  • Microsoft Corporation, Mike Zerkus, Jonathan Lusher and Jonathan Ward, USB Primer part 1, Circuit Cellar, May 1999
  • Jim Lyle, USB Primer part 2, Circuit Cellar, June 1999

Node your homework