Linux-USB Gadget API Framework (2022)

Last Modified: 8 June 2005

The <linux/usb_gadget.h> API makes it easy forperipherals and other devices embedding GNU/Linux system software to actin the USB "device" (slave) role.The drivers implementing and using that API combine to make a usefuldriver framework for Linux systems that implement USB peripherals.Many Linux systems will not be able to use it, since they only havePC-style USB Host (master) hardware in a PC, workstation, or server.But when you're putting together embedded Linux systems, a USB peripheralcontroller option is routine; it's often integrated into processors.Smart gadgets like PDAs, printers,cell phones,cash registers,and network routers often rely on this type of "Device Controller"USB link as one of their basic connectivity options.Sometimes it will be the only option; there areLinux devices that rely on USB even for their power supplies.

This is the first such "USB Gadget" framework on GNU/Linux to supporthigh speed (USB 2.0) devices and arbitrary numbers of endpoints,sharing core models and data structures with the "host side" USB API.It's designed for flexibility:the API handles simple devices,composite (multi-function) ones,multiple configurations,class (or vendor) specific functionality,and more.It a good base for integrating and re-using this type of driver code.Tests are available too, which can speed hardware bringup substantially.

Many developers have asked about easy ways to start working with this API.If you're comfortable working with embedded Linux platforms, many ARM systemsalready have Linux support for their integrated USB controllers.Otherwise, a Net2280 PCI card lets you work on a standard PC, developing ordebugging gadget drivers on computers you may already own.

Getting the Code

The API and several supporting drivers areincluded in current 2.4 and 2.6 Linux kernels,available through kernel.org as tarballs,or from vendors supporting customized Linux distributions.The BitKeeper trees are nolonger current, but the "mm" patchsets or various other GIT treesmay well have more current code than the current mainstream kernel.

(Video) Modern USB Gadget with Custom USB Functions & its Integration with systemd - Andrzej Pietrasiewicz

There may be other public trees with controller or gadget drivers too.The handhelds.org websiteincludes pointers to a number of these; a USB network linkcan be extremely useful.Kernel trees that support specific System-on-Chip platforms ofteninclude a driver for that platform's USB Peripheral Controller.

The "gadget" framework is available in 2.6 kernels,as well as 2.4.23 and later.(2.4.27 is the first 2.4 kernel to bundle RNDIS support, andsome other framework improvements.)At this writing, other than architecture- or board-specific setup,and the <linux/usb_*.h> header files, all thegadget code is in the drivers/usb/gadgetdirectory.It's easy to backport current 2.4 gadget code (e.g. 2.4.31)onto older 2.4 kernels.Most new development is based on 2.6 kernels;differences relevant to 2.4 based development are minor,mostly limited to kernel configuration and the 2.6 kernel's"generic DMA" and "driver model" infrastructure.Some 2.4 vendor kernels already includesome of that code, making 2.6 backports even easier.

Parts of the Framework

The API standardizes a platform-neutral boundary betweentwo software layers,but the software stack usually has several higher layers.The framework includes that API, some support software, andseveral drivers on each side of that API boundary,integrating well with other Linux subsystems.From the bottom up, those layers are:

  • Peripheral Controller Drivers implement the gadget API, and are the only layers that talk directly to hardware. Different controller hardware will need different drivers, which may also need board-specific customization. These provide a software "gadget" device, visible in sysfs. You can think of that device as being the virtual hardware to which the higher level drivers are written. Other operating systems use other names for this component, perhaps labeling the API plus its libraries as a "Platform Independent Layer" and its implementation as a "Platform Specific Layer".
  • Gadget Drivers use that gadget API, and can often be written to be hardware-neutral. Certain hardware facts need to affect the implementation of configuration management parts of ep0 logic. Those issues may be handled at various points: build time, initialization time, or run time. For example, some controllers have more endpoints than others, many don't support high speed or isochronous transfers, and sometimes endpoints have fixed configurations. A gadget driver implements one or more "functions", each providing a different capability to the USB host, such as a network link or speakers. Other operating systems use other names for this component, such as a "USB Client driver". (These are directly analagous to host side "interface drivers", except for multi-function "composite" gadget drivers.)
  • Upper Layers, such as the network, file system, or block I/O subsystems. These generate and consume the data that the gadget driver transfers to the host through the controller driver. There will often be several such layers, perhaps including user mode components. (Again, this is directly analagous to what host side drivers do, though producer and consumer roles are probably reversed.) On most hardware, several different layers can be fed by the gadget driver at the same time. For example, the functions on a composite device might give hosts concurrent access to local audio, internet, and file servers.

There are two other components worth mentioning.The first is a layer that doesn't exist: a "mid layer", like thehost-side "usbcore" (which is what the USB specification calls "USBD").The USB host side needs such a layer to multiplex potentially hundreds ofperipherals and drivers; the peripheral side has no such requirement.The Linux-USB host-side and peripheral-side driver stacks are directlyanalagous, except that only the host side has a mid layer.(The APIs are of course different; the peripheral side is much loweroverhead, and serves a "slave" role not a "master" one.)The second is an optional component that exists only in USB-OTGsystems: an OTG Controller Driver, switching control of the USBport between the gadget stack (as summarized above) and the USB host stack.(More information about OTG on Linux is available.)"Layer cake" style architecture diagrams would put an OTG ControllerDriver below the USB Peripheral and Host Controller Drivers, talkingto both of those drivers as well as specialized hardware.

(Video) Make your own USB gadget

The Linux 2.6 kernel tree includes kerneldoc for this API,including a structural overview as well as API reference.You can generate a current version of that yourself directlywith commands like "make pdfdocs", or use apre-generated version (which may not be as up-to-date as whatyou make from current kernel sources).

Recent versions of this API have improved and grown thecollection of gadget driver library helper functions.These aren't a separate library or midlayer, they're just object filesoptionally linked with gadget drivers that want their functions.

  • The string descriptor utilities now do UTF-8 to UTF-16LE conversion,making it easy to support languages that don't use ISO-8859-1.
  • Configuration buffer utilities combine null-terminated lists ofUSB descriptors, so it's easier to work withmultiple or complex configurations.(USB Wireless Mobile class devices use such configurations.)
  • Endpoint autoconfiguration hides some hardware-specific initializationissues from gadget drivers, such as endpoint addressing;simple gadget drivers may no longer need hardware-specific logic.
  • Convenience functions make it easier to test which of the currentlyconfigured controller chips is being used.

Other recent updates have included support for "soft connect",where the gadget driver controls the pullup used in enumeration;declaring allowable power consumption, helping control thingslike battery recharge rates;supporting external transceiver that sense VBUS sessions;and peripheral-side OTG features.

Controller Drivers

Drivers for several different usb device chips are available.Unless otherwise noted, these are full speed controllers.Many of the chips mentioned are highly integratedSystem-on-Chip (SOC) processors, typically integrating a 32-bitCPU core with cores for USB and numerous other features (such assignal processors) and optimized for efficient use on battery power.There are also several discrete USB controllers.

(Video) William Light - Linux USB HID Interfacing in Userspace

  • The NetChip net2280supports high speed (40+ MByte/sec)and full speed (1.2 MByte/sec) USB through PCI (net2280,in 2.4 and 2.6 kernels)
  • Intel's PXA 25x and IXP4xxXScale/ARMv5TE processors as seen in many PDAs (pxa2xx_udc,in 2.6 kernels with a 2.4 version available)
  • Renesas SH3 processors:SH7705, SH7727 (superh_udc, 2.4 version available)
  • Toshiba TC86c001 "Goku-S", on PCI (goku_udc,in 2.4 and 2.6 kernels)
  • MediaQ 11xx, as found in the Dell Axim X5 PDA (mq11xx_udc,2.6 version available)
  • Hynix HMS30C7202 ARMv4 processors (h7202_udc,2.6 and 2.4 versions available from Pengutronix)
  • National 9603/4 (n9604_udc, 2.4 version available)
  • Texas Instruments OMAPprocessors, including ARMv5TEJ models (omap_udc,in 2.6 kernel)with USB OTG capabilities.
  • Sharp LH7A40x ARMv4T processors (lh7a40x_udc,in 2.6 kernel)
  • Samsung S3C2410 ARMv4T processors (s3c2410_udc,2.6 version in use with Ipaq h1940)
  • Atmel AT91 ARMv4T and ARMv5TEJ processors (at91_udc, a2.6 version)
  • Intel PXA 27x XScale/ARMv5TE processors (pxa27x_udc,2.6 version in development)
  • The dummy_hcd driver simulatesa host-to-peripheral USB link within one kernel; it canbe a huge help when developing new gadget drivers.
  • Mentor Graphics supplies a preliminary GPL'dhigh speed stack, building on the gadget API and usedwith chips integrating their silicon design.(But not, at this writing, supporting USB OTG on Linux 2.6 kernels.)
  • For Texas Instruments parts including the DaVinci tms320dm644x,TUSB 6010, and OMAP 2430, there's a much more robust fork of that Mentor code.It's all but a rewrite, and supports high speed host-only, peripheral-only,and OTG modes.
  • Netchip 2272, high speed, used in some uClinux systems (notably,it's integrated into some Blackfin distributions)
  • Atmel at32ap7000, high speed, the initial implementationof the new AVR32 system-on-chip platform.
  • Freescale's highspeed dual-role controller,integrated in at least the MPC834x PPC based system-on-chip.
  • ... and others not listed here

The controller driver is responsible for handling onlya very few of the standard USB control requests, affectingdevice and endpoint state.(Those requests are frequently handled in hardware.)All other control requests, notably ones to return descriptorsand change configurations, are delegated to the gadget driver.Another key responsibility of the controller driver is managingeach endpoint's I/O queue, transferring data between the hardwareand the gadget driver's buffers (often using DMA).

Certain hardware-specific attributes are visible through thisAPI, since they can affect how gadget drivers must act.These are tested using gadget_is_*() macros, whichwork much like similar CPU and board testing macros;they frequently evaluate to "false" at compile-time.Not all controllers support isochronous transfers, as neededfor audio and video class drivers.Most controllers support at least two bulk/interrupt endpoints,but ones with at least five such endpoints are usually neededto implement multi-function ("composite") devices.Hardware sometimes restricts how software can manage device configurations,in ways that may prevent implemention ofmulti-function devices,multi-configuration ones,or certain standard USB Device Class specifications.

Gadget Drivers

At this writing there are several public "gadget drivers",each implementing a single common USB function so itwill work with virtually any USB peripheral controller.(Drivers for composite gadgets, or for audio/video driversrequiring isochronous transfers, would not be able to workon at least some controller hardware.The gadget API does support such drivers.)You should plan on testing these in conjunction withthe controller driver and system board you'll be using.

  • Gadget Zero ... is essential for controller driver testing. It provides two configurations: one for bulk traffic source/sink, and another for bulk traffic loopback. On the device side it helps verify that the driver stack pass USB-IF and other tests (needed for at least USB branding). On the host side it helps test the USB stack, such as the Linux-USB HCDs and usbcore. If built as a module, start it by modprobe g_zero; no other initialization is needed. (Use the autoresume=N module parameter to make it try triggering remote wakeup N seconds after it's suspended.)
  • Ethernet over USB ... the USB peripheral will enumerate to the host as an Ethernet device, using the "usbnet" driver with Linux hosts or Microsoft's RNDIS driver with Windows hosts. Set it up like any other two-host Ethernet link; bridging it to the LAN from the USB host may be the easiest way to run. Linux hosts do this with CONFIG_BRIDGE and tools like "brctl". Windows XP hosts have a GUI for bridging; it comes up when the RNDIS driver creates a second network link.
    bash# : this implicitly loads the usb controller driver, and helpsbash# : hosts use host_addr in config databases (win32 registry etc)bash# modprobe g_ether host_addr=00:dc:c8:f7:75:05 dev_addr=00:dd:dc:eb:6d:f1bash#bash# : connect the device.bash# : then use dhcp, zcip or static configuration:bash# ifconfig usb0 10.0.0.105bash# ip addr show usb02: usb0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 100 link/ether 00:dd:dc:eb:6d:f1 brd ff:ff:ff:ff:ff:ff inet 10.0.0.105/8 brd 10.255.255.255 scope global usb0bash#bash# : traffic will flow when the usb host is ready toobash# 
    (Video) Debugging Usually Slightly Broken (USB) Devices and Drivers - Krzysztof Opasiak, Samsung

    This driver can interoperate with hosts running Linux, MS-Windows, and other operating systems; if the OS can talk to a cable modem, it probably supports this driver. To do this, it supports several modes:

    • CDC Ethernet ... the Communications Device Class (CDC)"Ethernet Model" protocol is the standard way for USB devicesto expose Ethernet style functionality, with full specificationsavailable at www.usb.org.Linux hosts prefer using CDC Ethernet; they use a class driver,and don't need vendor-specific updates.Most non-Linux hosts support CDC Ethernet, although to use itwith MS-Windows you need a non-Microsoft driver.
    • CDC Subset ... this minimalist protocol is used withcontrollers where hardware limitations (no altsetting support)prevent use of CDC Ethernet.Two examples of such controllers are the PXA25x and SuperH UDCs.The Linux "usbnet" driver handles this, but since it's not astandard class it might need vendor-specific updates.Few non-Linux hosts support this protocol.
    • RNDIS ... when talking to MS-Windows hosts, RNDIS is used.RNDIS is Microsoft's analogue of CDC Ethernet, with complexframe encapsulation and its own internal RPC protocol. (This overview may help you, and a partial protocol specificationis available.For example, some requests from Windows 2000 and XP are undocumented.)Use the Documentation/usb/linux.inf file (convert toDOS CRLF format) to "install" the driver; the driver is bundledin XP, and the url in linux.inf says where to get Microsoft'sdrivers for older Windows releases.For some step-by-step instructions with WinXP screenshots,see the gumstix wiki showing one way to use that "linux.inf" file.Don't forget to read the comments there, explaining how to shorcutpast some needless complications in those instructions.

    To better support DHCP, ZCIP, and related network autoconfiguration, you'll want to manage Ethernet addresses so that each peripheral reuses the same unique address every time it boots. You should assign those addresses using a registered IEEE 802 company id; this will also make the device appear to Linux hosts as an "ethN" interface, not as "usbN". It's easy to do this without a separate ID PROM (or an initrd) if you're using boot firmware like U-Boot:

    # manufacturing assigns Ethernet addresses; company id is xx:xx:xxsetenv eth_a_host xx:xx:xx:01:23:45setenv eth_a_gadget xx:xx:xx:67:89:acsetenv eth_i_vendor "Great Stuff, LLC"setenv eth_i_product "Our Cool Thing"setenv eth_args g_ether.host_addr=\$(eth_a_host)setenv eth_args $(eth_args) g_ether.dev_addr=\$(eth_a_gadget)setenv eth_args $(eth_args) g_ether.iManufacturer=\$(eth_i_vendor)setenv eth_args $(eth_args) g_ether.iProduct=\$(eth_i_product)# you can assign USB vendor/product/version codes too...setenv add_eth_args setenv bootargs $(eth_args) \$(bootargs)...setenv bootcmd run add_eth_args\;bootm
  • GadgetFS ... since not every developer wants to program in the kernel, or rely specifically on the Linux kernel APIs, a user mode API is available. An example user mode driver is usb.c. (It also needs usbstring.c and usbstring.h.) Notice how the device is initialized by writing its configuration and device descriptors to a file (such as /dev/gadget/$CHIP), and how the endpoints are initialized in similar ways (writing descriptors to /dev/gadget/$ENDPOINT). After initializing them, just read or write to the files to transfer data; or to handle events including control requests to retrieve string descriptors, configure alternate settings, and implement class or vendor requests. On Linux 2.6 AIO (Async I/O) support is available, helping user mode drivers avoid i/o latencies and letting them stream data as quickly as in-kernel drivers can stream it. Note that user mode gadget drivers do not necesarily need to be licensed according to the GPL.
  • Mass Storage Gadget ... implements the USB Mass Storage class, appearing to the host as a SCSI disk drive. This uses a file or block device as a backing store for the drive, like the "loop" driver. (Read about how to set up the backing store.) The 2.6 version also lets you change the backing file associated with a given LUN. For example, you might specify the block device for an MMC card when that card is inserted (maybe using a hotplug script, or a GUI). Note that for MS-Windows interoperability, your backing store needs to be formatted with a DOS partition label. Data partitions can then be formatted with VFAT (for the widest interoperability) or some other filesystem (such as ext3 or reiserfs, for use with Linux).
  • Serial ... this exposes a tty style serial line interface, usable with Minicom and similar tools. (There's no serial console support at this time.) Most Linux hosts can talk to this using the generic usb-serial driver. The latest versions of this driver implement the CDC ACM class, as might be implemented by a cell phone or other modem. This driver works with the MS-Windows usbser.sys driver, the Linux cdc-acm driver, and many other USB Host systems. The 2.6.10 kernel has a detailed Documentation/usb/gadget_serial.txt file with information on how to set up this driver with both Windows and Linux systems.
  • MIDI ... this exposes an ALSA MIDI interface, which will appear in /proc/asound/cards with both recording and playback support. On the gadget side, open the MIDI gadget like any other ALSA MIDI device. Then you can write events to the host, or read them from the host.

That list doesn't yet include a dedicated file sharing protocol;for now, use NFS or SAMBA over an ethernet style link.A solution that's simpler to configure might use the USB-IFStill Image Capture Device class specification, whichpresents a hierarchical filesystem as well as some operationsspecific to cameras (setting focal length, shutter speed, etc)and capturing images.It builds on the "Picture Transfer Protocol" (PTP), whichis supported both for GNU/Linux and Microsoft Windows.At this writing, there is no Linux kernel implementation of PTPon either host or peripheral side.However, there are host side user-mode implementations, suchas gPhoto2.

(Video) Framework Laptop Assembly and Setup - Designed to LAST!

Other controller and gadget drivers are in development,but are unreleased or not published here.Examples that have seen some degree of light include:

  • HID driver (userspace, with gadgetfs),
  • "MTP" (Media Transfer Protocol, PTP++) driver (userspace, with gadgetfs),
  • two different printer class drivers (used in various products),
  • audio class driver (very experimental).
  • video class driver (very experimental).

Contributing

Yes, please! Bug fixes, gadget drivers (especially "class" drivers),and new USB device controller drivers will all be of interest.Discussions, patches, and similar work should beon the linux-usb-devel mailing list for now.

Thanks!

This work has been supported by patches, feedback, bug reports,hardware, and other contributions from many groups and individuals.Of particular note areNetChip Technology Inc,Agilent Technologies,Intel Corporation, Pengutronix,MontaVista Software,Auerswald GmbH,Texas Instruments,handhelds.org,Alan Stern,Al Borchers,Julian Back,David Meggy,gumstix,Andrew Zabolotny,Dmitry Krivoschokov,Hewlett-Packard Laboratories,and everyone who's contributed a patch or other feedbackthrough the Linux-USBcommunity.

FAQs

What is Linux USB gadget? ›

The USB Gadget ConfigFS is a file system which allows to configure USB functions by using file system commands such as mkdir and creating/writing files. Typically the file system is mounted under /sys/kernel/config/. The official Linux kernel documentation has more information in Documentation/usb/gadget_configfs.

What is Functionfs? ›

functionfs is part of the usb gadget subsystem. Together with usb_gadget's configfs integration, allows userland to declare and implement an USB device.

What is USB device mode? ›

In USB host mode, the Android-powered device acts as the host. Examples of devices include digital cameras, keyboards, mice, and game controllers. USB devices that are designed for a wide range of applications and environments can still interact with Android applications that can correctly communicate with the device.

What is mass storage gadget? ›

Overview. Mass Storage Gadget (or MSG) acts as a USB Mass Storage device, appearing to the host as a disk or a CD-ROM drive. It supports multiple logical units (LUNs).

What is Configfs in Linux? ›

Configfs is for creating, managing and destroying kernel objects from user-space, and sysfs for viewing and manipulating objects from user-space which are created and destroyed by kernel space. It is typically mounted at /sys/kernel/config (or more rarely at /config ).

What is UDC Linux? ›

A USB Linux Gadget is a device which has a UDC (USB Device Controller) and can be connected to a USB Host to extend it with additional functions like a serial port or a mass storage capability.

What is an OTG function? ›

An OTG or On The Go adapter (sometimes called an OTG cable, or OTG connector) allows you to connect a full sized USB flash drive or USB A cable to your phone or tablet through the Micro USB or USB-C charging port.

What is difference between USB host and USB device? ›

Standard USB uses a Master/Slave architecture; a host acts as the Host device for the entire bus, and a USB device acts as a Peripheral. If implementing standard USB, devices must assume one role or the other, with computers generally set up as hosts, while (for example) printers normally function as a Peripheral.

How do I enable OTG function? ›

Usually, when you try to connect an OTG, you get an alert “Enable OTG”. This is when you need to turn the OTG option ON. To do this, navigate through Settings > Connected devices > OTG. Here, click on the On/Off toggle to activate it.

Videos

1. Coverage-guided USB fuzzing with Syzkaller | OffensiveCon 2019
(Andrey Konovalov)
2. Linux Kernel Module Programming - USB Device Driver 01
(SolidusCode)
3. OffensiveCon19 - Andrey Konovalov - Coverage-Guided USB Fuzzing with Syzkaller
(OffensiveCon)
4. Reading USB in Python
(Alex Lugo)
5. Writing Your Own Gadget with Zephyr OS - Andrei Emeltchenko, Intel
(The Linux Foundation)
6. Getting Started with Mozilla WebThings Part 1: Setup on a Raspberry Pi
(Shawn Hymel)

Top Articles

Latest Posts

Article information

Author: Cheryll Lueilwitz

Last Updated: 11/25/2022

Views: 5583

Rating: 4.3 / 5 (74 voted)

Reviews: 81% of readers found this page helpful

Author information

Name: Cheryll Lueilwitz

Birthday: 1997-12-23

Address: 4653 O'Kon Hill, Lake Juanstad, AR 65469

Phone: +494124489301

Job: Marketing Representative

Hobby: Reading, Ice skating, Foraging, BASE jumping, Hiking, Skateboarding, Kayaking

Introduction: My name is Cheryll Lueilwitz, I am a sparkling, clean, super, lucky, joyous, outstanding, lucky person who loves writing and wants to share my knowledge and understanding with you.