Embedded USB Host Stack
TrueTask USB is used by Microsoft as the USB stack for Windows 10 IoT Core for Raspberry Pi 2 and 3. A fully functional evaluation version is also available for Windows 10 ARM64 on the Raspberry Pi 3 through pi64.win.
What is a USB platform?
The notion of a software platform is familiar: it’s a design environment that allows code to be written that is subsequently unaffected by changes to the operating system, CPU, compiler, and so forth. In the embedded system world, Linux is a good example of a platform for application programs.
For reasons of efficiency, USB system code (the host and device stacks, the class and protocol drivers, and the management code) normally resides in the operating system kernel. Unfortunately, most operating systems that serve as application platforms do not serve as good system software platforms. In Linux, for example, the kernel APIs are not stable, and may change from kernel version to kernel version (18.104.22.168 may be different than 22.214.171.124, for example). Products based on embedded systems have similar differences between major versions. For a system vendor, this is very inconvenient, because multiple source versions must be maintained; bug fixes and system-specific adaptations cannot be automatically applied to any given environment, but must be scrutinized for correctness.
This is particularly a problem when it comes to USB host stacks. By its nature, USB is an open standard. No matter how well tested and supported a stack is, patches may be required to support a new and popular device that deviates from USB standards (but just happens to work with Windows or OS X). This presents problems. If the stack is from a commercial RTOS vendor, often you must update to the latest version of the RTOS to get all the corrections. However, if the stack is not designed to be a platform, you will have to modify your application code; and you may have to re-port the stack onto your platform. This may not be practical, because extensive testing is generally required.
If working with Linux, the problem can be even more difficult. Because of changes in kernel APIs, it is usually not practical to port the entire USB stack back to an earlier kernel version. Instead bug fixes must be identified, and then back ported. However, fixes may depend on other corrections made to the stack; so they may not work by themselves. Furthermore, fixes in the enumeration code may cause other devices to stop working.
How TrueTask USB provides a USB platform
TrueTask USB offers all the basic features one expects from an embedded USB host stack: extensive SoC support, small memory footprint, efficient run-time operation, and a variety of class drivers. TrueTask USB is different than a traditional embedded USB host stack, in that it’s based on a foundation of stable APIs. Stable APIs allow seamless reuse of your investment in code based on TrueTask USB. These APIs are designed portably, so that the C code using them is portable across CPUs, operating systems, and host/device controller register models. They are also designed to be stable over time, so that code written with one version of TrueTask USB will be reusable with subsequent versions. Furthermore, they’re internally stable as well. This means that a change, for example, in the host controller driver will not affect TrueTask USB code in any other layer; only minimal retesting is needed.
MCCI’s commitment to stable APIs protects our customers’ investments in USB software, and enables our customers to continue reusing their applications and class drivers from previous projects. For example, customers who upgrade a product using TrueTask USB to a new SoC will be able to reuse their legacy USB software applications and USB class drivers seamlessly. This allows customers to maximize the return on their investment of development time, testing, and field experience with prior products.
How TrueTask USB enables stable APIs across so many platforms
MCCI has been creating stable APIs for USB for twenty years. Several distinctive design practices have resulted.
- We explicitly version API functions that are called by name. If a function changes, we write a new version, and express the old version in terms of the new version. Our library-oriented, one-function-per-file source base for API implementations means that the wrapper code for the older versions is only used if required.
- MCCI avoids conditional compiles in our C code. In addition to other benefits, this makes the important configuration and run-time parameters visible early in development.
- We prohibit use of OS header files except in the wrapper modules that bridge between TrueTask USB APIs and the local platform APIs. In addition to greatly simplifying compile-time configuration management, these practices force our code to depend on the inter-module APIs for managing all CPU, OS and hardware variations, rather than using “#if” and compile-time variables.
- We use macros to initialize API data structures, and then explicitly version those macros. This makes client source code insensitive to data structure order, naming, or layout.
- MCCI code is coded without static or global variables. This again makes certain design assumptions explicit that would otherwise be explicit, and forces us to make relationships between system-wide objects clear at design time.
MCCI is able to evolve APIs as the USB standards evolve; by maintaining the older, stable APIs, we isolate our customer’s legacy code from changes in the stack.
How TrueTask USB enables reuse of USB software investments
Customers switching from existing USB stack implementations to TrueTask USB can still reuse their existing software investment. TrueTask USB includes local operation system USB host stack emulations. These emulations are fast and highly compatible, allowing TrueTask USB to support “in-box” class drivers shipped with the local operating system or developed by our customers. Whatever USB applications customers have running on the existing USB host stack implementation will seamlessly work over the TrueTask USB host, and will be able to access the additional features provided by TrueTask USB: SuperSpeed support, composite device support, role switching, and so forth.
Embedded systems benefit from TrueTask USB’s Windows deployment
TrueTask USB includes a production-quality Windows stack emulation. This allows direct test and validation of new USB controller designs on Windows, with a minimum of effort, and allowing test with an enormous variety of class drivers and device applications. The TrueTask USB host controller driver (HCD) API is a platform API, and allows direct test of non-EHCI/xHCI architectures such as the Synopsys DesignWare OTG USB 2.0 core, using the full variety of Windows devices.
When developing an embedded system, you therefore can first test the system components on Windows. This exercises the HCD, the hub drivers, the enumeration logic. Customers can also code to our generic APIs, and test large portions of their applications on Windows. When the software is moved to the embedded system, any variations are systematic and easy to track down.
How TrueTask USB Host is optimized to support real-world USB devices
Other embedded USB host stacks implement class drivers according to the USB-IF specifications. Why does it so often happen that these embedded host stacks fail to support certain USB devices, despite the user’s claim “but it works with Windows”?
The answer is found in the gap between the class driver specifications of USB-IF and what real-world device manufacturers produce.
Simply put, other embedded USB host stacks implement class drivers by their interpretation of the USB-IF specification – while USB device makers test and verify against the Windows USB host stack. The result is a mismatch between device and host implementation.
It is no secret that consumer device makers with USB connectivity mostly target the PC market, and use standards only for reference. Product test consists of interop test with Windows and OS X. As a result, these devices work perfectly with Windows or OS X; but there is no real guarantee that they are in fact standard compliant, so there’s no guarantee that they will work with an embedded USB stack.
TrueTask USB is not just compatible with Windows; it is shipped in mass production as the USB host stack with multiple PC and laptop brands as the sole USB host stack on Windows. The USB enumeration logic, the handling of suspend/resume, the timing and sequencing of USB operations have all been tested and proven by customer experience to be compatible with what CE device makers test against. All this “USB business logic” is embedded in the portable portion of the TrueTask USB stack, so all users benefit from this experience.
Dual Role Host/Device Support
It is increasingly common to multiplex a single physical USB connector to operate it either as a host or device. To support this, TrueTask Dual-Role USB has complete support for dual-role USB Type C, dual-role USB 3.2/2.0, and USB 2.0 On The Go, combining the TrueTask USB host stack with the MCCI USB DataPump device stack.
TrueTask USB Features
- Supported USB standards
- USB 1.1, USB 2.0, HSIC USB, USB 3.2, SSIC USB, USB Type C
- Supported speeds
- Low speed, full speed, high speed, USB 3.2 Gen 1 and Gen 2 (SuperSpeed and SuperSpeed Plus).
- USB endpoint support
- Control, interrupt, bulk, isochronous, USB 3 bulk streams
- Supported hubs
- USB 1.1, USB 2.0 (including transaction translators), USB 3.2
- Supported operating systems
- Embedded RTOS (Green Hills INTEGRITY OS, Nucleus, ThreadX, µITRON, MQX, QNX, Windows CE, eCos, FreeRTOS, LynxOS, VxWorks)
- Windows 10, 8.1, 8, 7, 32 and 64 bit, desktop, server, and embedded editions
- Windows 10 on ARM and ARM64
- Linux and Android (x86, Arm, PowerPC, SH)
- Non-OS / pre-boot / post-crash environments using MCCI’s “os/none” (any supported CPU architecture)
- For support of additional RTOS, please contact email@example.com
- Supported CPU architectures
- ARC, ARM, ARM64, FT32, MIPS, PowerPC, RISC-V, SH family, Tensilica, x86 (32 bit and 64 bit)
- Supported compilers
- Any compiler with ANSI C-99 support.
- Operation Modes
- TrueTask USB can be integrated into the target system to operate in one of two modes, kernel mode or user mode. Kernel mode: USBD and the HCD run as part of the local operating system kernel, and access hardware directly. User mode: USBD and the HCD run as unprivileged applications, using low-level proxy services provided by the kernel to access hardware and program DMA. Depending on the strength of the local operating system’s abstraction mechanisms, this can isolate the rest of the system from failures in the USB host stack and class drivers.
- Supported USB Host Controllers
- xHCI 0.96, 1.0, 1.1 (Renesas, ASMedia, TI, Marvell, Synopsys, etc.) for USB 2.0 and 3.2.
- Synopsys xHCI combined with Synopsys USB 3.2 device controller.
- Synopsys DesignWare USB 2.0 host/device controller (versions 1.6 and later), including support for transaction translators and high-bandwidth isochronous.
- Renesas R8A66587 USB 2.0 host/device controller (either standalone or embedded in Renesas ARM, SH, or RX processors).
- Renesas RZ1 and RCar-3 SoCs.
- EHCI-compatible controllers (Synopsys, Faraday, custom USB 2 IP blocks; SoCs including NXP’s i.MX family of application processors, NXP’s LPC family of USB MCUs, NXP’s QorIQ family of communication processors, and NXP’s S32 family of automotive processors. We also support NVidia Tegra family; and a variety of Microchip/Atmel processors.
- TrueTask USB Host Class Drivers (see Class Driver page for details)
Hub, Composite, Local OS bridge, Ethernet Control Model (ECM), Ethernet Emulation Model (EEM), Network Control Model (NCM), Mass Storage (BOT), Human Interface Device (HID) keyboard and mouse, ASIX Ethernet over USB adapters, MediaTek (Ralink) RT3530-based USB Wi-Fi adapters, MediaTek (Ralink) RT5730 USB Wi-Fi adapters, generic class driver, custom class drivers. Support for local OS USB class driver API emulation to enable any pre-existing class driver.
For additional class drivers, please contact firstname.lastname@example.org.
- Runtime memory architecture
- TrueTask USB is completely reentrant, and allocates memory dynamically at run time. The architecture supports arbitrarily many instances of TrueTask USB, host and device controllers, class drivers, and protocol instances. TrueTask USB has no global or static variables.
- Runtime memory allocation policy
- Selected at design time. TrueTask USB can pre-allocate all needed RAM at boot time, dynamically allocate from a fixed pool, or dynamically allocate from system pool. Pre-allocating at boot time allows for deterministic behavior for a given USB tree size, and for graceful failure if the pre-determined maximum tree size is exceeded. Dynamic allocation results in more efficient memory allocation at the sacrifice of determinism. The two dynamic variants differ in their impact on remaining system memory; the fixed pool reserves a constant amount of memory, increasing predictability.
- Synchronization and concurrency control
- TrueTask USB makes minimal assumptions about the underlying OS. TrueTask USB uses event driven processing, with the assumption that two events are not dispatched concurrently. On multi-core systems with multiple host/device controllers, typically one instance is created per independent controller. The synchronization model is portable from the simplest pre-boot / post-crash case (“os/none”), through classic RTOS models to highly concurrent multi-CPU models such as the Windows kernel. Although the model is simple, testing on Windows shows that TrueTask USB is as fast as, or faster than, stacks that are coded using the native Windows synchronization APIs.
- Business Model
- TrueTask USB is an OEM product, so pricing normally includes the rights to distribute in conjunction with another product. Pricing for distribution rights is negotiated based on volume. MCCI supports royalty, annual subscription, or one-time fee per project. Support is available based on annual contracts.