Introduction
TinyUSB is an open-source USB stack in C for embedded microcontrollers. It provides device and host functionality across RP2040, STM32, nRF, ESP32-S2/S3, and many other chip families with a portable driver abstraction.
What TinyUSB Does
- Implements USB device classes: CDC, MSC, HID, MIDI, Audio, and vendor-specific
- Provides USB host support for enumerating and talking to attached devices
- Abstracts chip-specific USB registers behind a portable driver layer
- Ships with ready-to-build examples for dozens of boards
- Runs bare-metal or integrates with an RTOS
Architecture Overview
Three layers separate concerns: chip-specific drivers at the bottom, a core protocol engine handling standard requests and endpoint management in the middle, and class drivers exposing application-level APIs on top. A lightweight event queue dispatches callbacks outside ISR context, keeping interrupt handlers short.
Self-Hosting & Configuration
- Add TinyUSB as a submodule or copy the source into your project
- Set the MCU family and board in tusb_config.h or via build defines
- Enable only the USB classes you need to minimize flash and RAM
- Call tud_task() or tuh_task() from your main loop or RTOS thread
- Build with Make, CMake, or integrate into your IDE project
Key Features
- Supports 20+ MCU families from multiple vendors
- Device and host stacks in one codebase
- Minimal CDC build fits under 16 KB of flash
- Extensive examples: CDC serial, mass storage, HID, MIDI, composite
- Active community with regular releases and broad CI
Comparison with Similar Tools
- STM32 USB Library — tightly coupled to STM32 HAL; not portable to other chips
- Zephyr USB subsystem — powerful but requires the full Zephyr RTOS and build system
- LUFA — well-documented; limited to Atmel AVR and XMEGA chips
- CherryUSB — similar scope; newer with fewer supported MCUs and examples
FAQ
Q: Which MCUs are supported? A: RP2040, STM32 (F0/F1/F4/H7/L4 and others), nRF52/nRF53, ESP32-S2/S3, LPC, SAMD, Renesas, and more. See the hw/bsp directory for the full list.
Q: Can I use it without an RTOS? A: Yes. Call its task function from your main loop and it processes events cooperatively.
Q: How do I make a composite USB device? A: Enable multiple class drivers in tusb_config.h and write a composite descriptor with interfaces for each class. The cdc_msc example demonstrates this.
Q: Does it support USB 3.x? A: No. It supports USB 2.0 full-speed and high-speed where hardware allows.
Sources
- Repository: https://github.com/hathach/tinyusb
- Documentation: https://docs.tinyusb.org/