opensourceprojects.dev

A broadsheet for software that doesn't ask for your email

A tiny USB host and device stack for embedded systems
GitHub RepoViews5

Project Description

View on GitHub

CherryUSB: A USB Stack for Embedded Systems That Won't Make You Want to Quit

If you've ever tried to bring up USB on a microcontroller, you know the pain. Descriptors, enumeration, endpoint management, class drivers, and IP-specific quirks all pile up before you've sent a single byte. CherryUSB is an open-source USB host and device stack for embedded systems that aims to take some of that pain away, with an emphasis on being small, portable, and readable.

What It Does

CherryUSB is a USB host and device stack designed for embedded systems with USB IP. It's written in C and organized into clear directories: class for USB class drivers, common for spec macros and utilities, core for the core implementation, port for device and host controller porting, osal for OS wrappers, and demo for device and host examples. There's also a docs directory with documentation, plus platform and tools directories rounding out the layout.

On the device side, CherryUSB provides a unified framework for handling standard device requests, class requests, vendor requests, and custom special requests. It uses what the project describes as an object-oriented and chained approach, which is meant to let you build composite devices without wrestling with the underlying logic. A standard dcd porting interface exists so you can adapt different USB IPs. Supported device classes include CDC (ACM and ECM), HID, MSC, UVC (1.0 and 1.5), and UAC (1.0, with the README truncated at that point). The stack supports USB 2.0 full and high speed, with USB 3.0 super speed listed as a TODO.

Why It's Cool

The design goals here are refreshingly honest. The README doesn't promise magic—it promises that the code is streamlined, with simple logic and no complex C syntax. That matters when you're debugging a stack at 2 a.m. and need to actually follow what's happening.

  • The data transmission interface is modeled on UART and DMA. If you're comfortable with UART TX/RX DMA, you'll recognize the pattern here. There are no length restrictions on transmission or reception—you don't have to think about USB packetization, because the porting drivers handle it. That's a genuinely useful abstraction if you've ever had to chop buffers into 64-byte chunks yourself.

  • Performance gets direct attention. The porting drivers interface directly with registers without an abstraction layer, memory is zero-copy, and DMA is used when the IP supports it. Packetization happens in the interrupt context, and the lack of length restrictions helps hardware DMA do its job. The project links to a performance page in its docs rather than just claiming speed.

  • Users can register endpoint IRQ callbacks. This is a small feature with big implications—it lets you do whatever you want in the callback rather than being boxed into the stack's assumptions.

  • The architecture is tree-structured and layered. Templates and simplified drivers for classes and porting mean there's less boilerplate to copy-paste and more to actually understand. The API is categorized clearly: device initialization, class registration, command callbacks, and data transmission on one side; host initialization, class discovery, and data transmission on the other.

How to Try It

The repository is at github.com/cherry-embedded/cherryusb. Since this is an embedded stack rather than a package you install with a single command, your starting point is the demo directory, which contains both device and host examples. The docs directory holds the documentation, and there's a Read the Docs site linked from the project (including the performance page) for deeper guidance.

A sensible path:

  1. Clone the repository and look at the demo folder to see how device and host setups are structured.
  2. Read through the port directory to understand how the dcd and hcd porting interfaces work for your USB IP.
  3. Check the class directory for the class driver closest to what you need—CDC, HID, MSC, UVC, or UAC.
  4. Consult the docs before writing your own porting layer; the standardized interface is the whole point.

There's also a Discord community linked in the project badges if you get stuck.

Final Thoughts

CherryUSB isn't trying to be everything to everyone. It's aimed at embedded developers working with USB IP who want a stack they can read, port, and reason about—and who'd rather spend their time on their application than on packetization logic. The emphasis on direct register access and zero-copy DMA suggests it's built for people who care about squeezing real bandwidth out of their hardware. If you're bringing up USB on a new chip or tired of stacks that feel like black boxes, this one's worth a look.


Follow @githubprojects for more developer tools and open source projects.

Back to Projects
Project ID: cherryusbLast updated: November 10, 2026 at 02:50 AM