The most exciting thing about this world is its ever changing quality.

Friday, November 27, 2009

All about USB

Pre-defined USB device classes provide standard USB drivers for the devices falling into these classes. Otherwise USB device vendor will provide their own.

USB Device driver = USB Host driver (Host controller/Hub/Master) OR USB gadget (Device/Slave)

Host - Linux
LDD3 - USB

Endpoint - The basic uni-direction data channel, either from Host to Device (OUT) or Device to Host (IN)
  • CONTROL - configure, retrieve device information, send commands to device, retrieve device status report. Every USB device has a control endpoint "endpoint 0", used by USB core to configure the device at insertion time.
  • INTERRUPT - endpoints transfer small amount of data at a fixed rate everytime Host asks Device for data. These endpoints are the primary transportation method for USB mice, keyboards. Also can be used by Host to send control command to Device. NOT generally for large amount of data.
  • BUILK - for large amount of data transfer. Commonly used in printers, storage, and network devices to transfer bulk packets from or to devices. Data MUST gets through without loss, but time could NOT be guaranteed.
  • ISOCHRONOUS - also for large amount of data transfer, but data loss is possible. Used in application for constant stream of data flowing such as real time data collection, audio and video streaming.
CONTROL and BULK types of Endpoints are used in asynchronous transfer. INTERRUPT and ISOCHRONOUS are periodic. In Linux, usb_host_endpoint structure describe an endpoint, which contains a usb_endpoint_descriptor.

Interface - a bundle of Endpoints, handles one type of USB logical connection, such as mouse, keyboard, audio stream. Some USB devices have multiple interfaces (for example, an USB speaker device has one interface for audio stream, one interface for keyboard for the buttons). USB device driver and USB Interface is a one-to-one mapping relation. Each USB driver controls one interface in an USB devices. So it is likely we need multiple USB drivers to control one USB hardware device. USB driver is bound to USB Interface.

Interface structure in the kernel is usb_interface. USB core passes usb_interface structure to USB driver to control.

Each USB device will have a USB major number. Every interface will be assigned a minor number by USB core via calling usb_register_dev.


Configuration - a bundle of Interfaces. A USB device can have multiple configurations to switch in between to change the state of the device. In the kernel, structure usb_host_config represents a Configuration. usb_device represents entire USB device.

Descriptors

All USB devices have a hierarchy of descriptors which describe to the host information such as what the device is, who makes it, what version of USB it supports, how many ways it can be configured, the number of endpoints and their types etc. The more common USB descriptors are
• Device Descriptors
• Configuration Descriptors
• Interface Descriptors
• Endpoint Descriptors
• String Descriptors

LDD3 - USB

Enumeration - is the process of determining what device has just been connected to the bus and what parameters it requires such as power consumption, number and type of endpoint(s), class of product etc. The host will then assign the device an address and enable a configuration allowing the device to transfer data on the bus. A fairly generic enumeration process is detailed in section 9.1.2 of the USB specification.

USB File system
The first USB device is a root hub, or known as USB controller, usually contained in a PCI device acting as a bridge between PCI bus and USB bus. It is also the first USB device on USB bus. All root hubs will be assigned unique number by USB core.

USB sysfs device naming scheme: root_hub-hub_port:config.interface
[USB Selective Suspend - The USB selective suspend feature allows the hub driver to suspend an individual port without affecting the operation of the other ports on the hub.]

Kernel will bind the correct USB driver to interfaces specified by configuration based on bConfigurationValue in a USB device.

sysfs (/sys/) stops at the interface level without exposing all parts of USB device.
Detail information of endpoints can be found in usbfs filesystem, mounted in /proc/bus/usb/. /proc/bus/usb/devices will show all configurations and endpoints in the system. It also can allow user space programs talk directly to USB devices. (Hence user space USB driver is possible to be in user space rather than kernel.)

Data transfer
Via URB
usb_alloc_urb usb_xxxxxpipe usb_submit_urb
create URB URB URB Notify
Apps ---> USB device driver ---------------> USB device driver assign URB to endpoint -------> USB core -------> USB host controller (for this USB device) <> ---------> USB device driver

Different URBs are created to be bound to different types of endpoints. After a urb has been submitted to the USB core successfully, it should never try to access any fields of the urb structure until the complete function is called.

• When the function is usb_kill_urb, the urb lifecycle is stopped. This function is usually used when the device is disconnected from the system, in the disconnect callback.
usb_unlink_urb function should be used to tell the USB core to stop an urb. This function does not wait for the urb to be fully stopped before returningto the caller.

Without URB
Synchrounous usb_bulk_msg, usb_control_msg

To write a USB driver
Same thing to other subsystem drivers really, create driver structure -> register to USB kernel subsystem (-> create char driver interface for USB devices)

USB core handles the addition and removal of USB devices within a single thread, so any slow device driver can cause the USB device detection time to slow down and become noticeable by the user.

VCP over USB
COM port redirector is a powerful concept in hardware connection limited device.

USB CDC ACM: Abstract Control Model. This access model provides a serial (COM) like interface to a USB device. Each CDC-ACM channel utilizes 3 USB end-points for end-to-end communication. Linux has a generic CDC ACM host-side implementation in the kernel module cdc_acm.ko.
USB CDC ECM: Ethernet Networking Control Model. This access model provides a standardized networking interface for handling of IP transmission over a physical interface such as USB.
USB CDC OBEX: Object Exchange
http://www.jungo.com/st/embedded_usb_cdc.html


Gadget - Linux

Instead of Host controller, we have peripheral controller taking it place in USB 'slave' device end.


Typical gadget drivers under Linux are:
• Gadget Zero
• Ethernet over USB (To support different host, there are different modes: CDC Ethernet, CDC subset, RNDIS)
• GadgetFS
• File-backed storage (implementing USB Mass storage class)
• Serial (implementing CDC ACM class)
• MIDI

No comments: