initial commit
This commit is contained in:
commit
b44ce7bd77
2716 files changed
+559005
No files matched your search
+282
@@ -0,0 +1,282 @@
|
||||
************
|
||||
Architecture
|
||||
************
|
||||
|
||||
This document explains TinyUSB's internal architecture, design principles, and how different components work together.
|
||||
|
||||
Design Principles
|
||||
=================
|
||||
|
||||
Memory Safety
|
||||
-------------
|
||||
|
||||
TinyUSB is designed for resource-constrained embedded systems with strict memory requirements:
|
||||
|
||||
TinyUSB uses **no dynamic allocation** - all memory is statically allocated at compile time for predictability. All buffers have bounded, compile-time defined sizes to prevent overflow issues. The TinyUSB core avoids heap allocation, resulting in **predictable memory usage** where consumption is fully deterministic.
|
||||
|
||||
Thread Safety
|
||||
-------------
|
||||
|
||||
TinyUSB achieves thread safety through a deferred interrupt model:
|
||||
|
||||
- **ISR deferral**: USB interrupts are captured and deferred to task context
|
||||
- **Single-threaded processing**: All USB protocol handling occurs in task context
|
||||
- **Queue-based design**: Events are queued from ISR and processed in ``tud_task()``
|
||||
- **RTOS integration**: Proper semaphore/mutex usage for shared resources
|
||||
|
||||
Portability
|
||||
-----------
|
||||
|
||||
The stack is designed to work across diverse microcontroller families:
|
||||
|
||||
- **Hardware abstraction**: MCU-specific code isolated in portable drivers
|
||||
- **OS abstraction**: RTOS dependencies isolated in OSAL layer
|
||||
- **Modular design**: Features can be enabled/disabled at compile time
|
||||
- **Standard compliance**: Strict adherence to USB specifications
|
||||
|
||||
Core Architecture
|
||||
=================
|
||||
|
||||
Layer Structure
|
||||
---------------
|
||||
|
||||
TinyUSB follows a layered architecture from hardware to application:
|
||||
|
||||
.. figure:: ../assets/stack.svg
|
||||
:width: 500px
|
||||
:align: left
|
||||
:alt: stackup
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<div class="clear-both"></div>
|
||||
|
||||
Component Overview
|
||||
------------------
|
||||
|
||||
- **Application Layer**: Your main application code that uses TinyUSB APIs.
|
||||
- **Class Drivers**: Implement specific USB device classes (CDC, HID, MSC, etc.) and handle class-specific requests.
|
||||
- **Device/Host Core**: Implements USB protocol state machines, endpoint management, and core USB functionality.
|
||||
- **OS Abstraction**: Provides threading primitives and synchronization for different RTOS environments.
|
||||
- **Device/Host Controller Driver**: drivers that interface with MCU USB peripherals. Several MCUs may share a common driver.
|
||||
|
||||
Device Stack Architecture
|
||||
=========================
|
||||
|
||||
This section is concerned with the **Device Stack**, i.e., the component of TinyUSB used in USB devices (that talk to a USB host).
|
||||
|
||||
Core Components
|
||||
---------------
|
||||
|
||||
**Device Controller Driver (DCD)**:
|
||||
- MCU-specific USB device peripheral driver
|
||||
- Handles endpoint configuration and data transfers
|
||||
- Abstracts hardware differences between MCU families
|
||||
- Located in ``src/portable/VENDOR/USBIP/``
|
||||
|
||||
**USB Device Core (USBD)**:
|
||||
- Implements USB device state machine
|
||||
- Handles standard USB requests (Chapter 9)
|
||||
- Manages device configuration and enumeration
|
||||
- Located in ``src/device/``
|
||||
|
||||
**Class Drivers**:
|
||||
- Implement USB class specifications
|
||||
- Handle class-specific requests and data transfer
|
||||
- Provide application APIs
|
||||
- Located in ``src/class/*/``
|
||||
|
||||
Data Flow
|
||||
---------
|
||||
|
||||
**Control Transfers (Setup Requests)**:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
USB Bus → DCD → USBD Core → Class Driver → Application
|
||||
↓
|
||||
Standard requests handled in core
|
||||
↓
|
||||
Class-specific requests → Class Driver
|
||||
|
||||
**Data Transfers**:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
Application → Class Driver → USBD Core → DCD → USB Bus
|
||||
USB Bus → DCD → USBD Core → Class Driver → Application
|
||||
|
||||
Event Processing
|
||||
----------------
|
||||
|
||||
TinyUSB uses a deferred interrupt model for thread safety:
|
||||
|
||||
1. **Interrupt Occurs**: USB hardware generates interrupt
|
||||
2. **ISR Handler**: ``dcd_int_handler()`` captures event, minimal processing
|
||||
3. **Event Queuing**: Events queued for later processing
|
||||
4. **Task Processing**: ``tud_task()`` (called by application code) processes queued events
|
||||
5. **Callback Execution**: Application callbacks executed in task context
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
USB IRQ → ISR → Event Queue → tud_task() → Class Callbacks → Application
|
||||
|
||||
Host Stack Architecture
|
||||
=======================
|
||||
|
||||
This section is concerned with the **Host Stack**, i.e., the component of TinyUSB used in USB hosts, managing connected USB devices.
|
||||
|
||||
Core Components
|
||||
---------------
|
||||
|
||||
**Host Controller Driver (HCD)**:
|
||||
- MCU-specific USB host peripheral driver
|
||||
- Manages USB pipes and data transfers
|
||||
- Handles host controller hardware
|
||||
- Located in ``src/portable/VENDOR/FAMILY/``
|
||||
|
||||
**USB Host Core (USBH)**:
|
||||
- Implements USB host functionality
|
||||
- Manages device enumeration and configuration
|
||||
- Handles pipe management and scheduling
|
||||
- Located in ``src/host/``
|
||||
|
||||
**Hub Driver**:
|
||||
- Manages USB hub devices
|
||||
- Handles port management and device detection
|
||||
- Supports multi-level hub topologies
|
||||
- Located in ``src/host/``
|
||||
|
||||
Device Enumeration
|
||||
------------------
|
||||
|
||||
The host stack follows USB enumeration process:
|
||||
|
||||
1. **Device Detection**: Hub or root hub detects device connection
|
||||
2. **Reset and Address**: Reset device, assign unique address
|
||||
3. **Descriptor Retrieval**: Get device, configuration, and class descriptors
|
||||
4. **Driver Matching**: Find appropriate class driver for device
|
||||
5. **Configuration**: Configure device and start communication
|
||||
6. **Class Operation**: Normal class-specific communication
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
Device Connect → Reset → Get Descriptors → Load Driver → Configure → Operate
|
||||
|
||||
Class Architecture
|
||||
==================
|
||||
|
||||
Common Class Structure
|
||||
----------------------
|
||||
|
||||
All USB classes follow a similar architecture:
|
||||
|
||||
**Device Classes**:
|
||||
- ``*_device.c``: Device-side implementation
|
||||
- ``*_device.h``: Device API definitions
|
||||
- Implement class-specific descriptors
|
||||
- Handle class requests and data transfer
|
||||
|
||||
**Host Classes**:
|
||||
- ``*_host.c``: Host-side implementation
|
||||
- ``*_host.h``: Host API definitions
|
||||
- Manage connected devices of this class
|
||||
- Provide application interface
|
||||
|
||||
Class Driver Interface
|
||||
----------------------
|
||||
|
||||
See ``usbd.c``.
|
||||
|
||||
**Required Functions**:
|
||||
- ``init()``: Initialize class driver
|
||||
- ``reset()``: Reset class state
|
||||
- ``open()``: Configure class endpoints
|
||||
- ``control_xfer_cb()``: Handle control requests
|
||||
- ``xfer_cb()``: Handle data transfer completion
|
||||
|
||||
**Optional Functions**:
|
||||
- ``close()``: Clean up class resources
|
||||
- ``deinit()``: Deinitialize class driver
|
||||
- ``sof()``: Start-of-frame processing
|
||||
- ``xfer_isr()``: Called from USB ISR context on transfer completion. Data will get queued for ``xfer_cb()`` only if this returns ``false``.
|
||||
|
||||
Descriptor Management
|
||||
---------------------
|
||||
|
||||
Each class is responsible for:
|
||||
- **Interface Descriptors**: Define class type and endpoints
|
||||
- **Class-Specific Descriptors**: Additional class requirements
|
||||
- **Endpoint Descriptors**: Define data transfer characteristics
|
||||
|
||||
Memory Management
|
||||
=================
|
||||
|
||||
Static Allocation Model
|
||||
-----------------------
|
||||
|
||||
TinyUSB uses only static memory allocation; it allocates fixed-size endpoint buffers for each configured endpoint, static buffers for class-specific data handling, a fixed buffer dedicated to control transfers, and static event queues for deferred interrupt processing.
|
||||
|
||||
Buffer Management
|
||||
-----------------
|
||||
|
||||
**Endpoint Buffers**:
|
||||
- Allocated per endpoint at compile time
|
||||
- Size defined by ``CFG_TUD_*_EP_BUFSIZE`` macros
|
||||
- Used for USB data transfers
|
||||
|
||||
**FIFO Buffers**:
|
||||
- Ring buffers for streaming data
|
||||
- Size defined by ``CFG_TUD_*_RX/TX_BUFSIZE`` macros
|
||||
- Separate read/write pointers
|
||||
|
||||
Threading Model
|
||||
===============
|
||||
|
||||
Task-Based Design
|
||||
-----------------
|
||||
|
||||
TinyUSB uses a cooperative task model; it provides main tasks - ``tud_task()`` for device and ``tuh_task()`` for host operation. These tasks must be called regularly (typically less than 1ms intervals) to ensure all USB events are processed in task context, where application callbacks also execute.
|
||||
|
||||
RTOS Integration
|
||||
----------------
|
||||
|
||||
**Bare Metal**:
|
||||
- Application calls ``tud_task()`` in main loop
|
||||
- No threading primitives needed
|
||||
- Simplest integration method
|
||||
|
||||
**FreeRTOS**:
|
||||
- USB task runs at high priority
|
||||
- Semaphores used for synchronization
|
||||
- Queue for inter-task communication
|
||||
|
||||
**Other RTOS**:
|
||||
- Similar patterns with RTOS-specific primitives
|
||||
- OSAL layer abstracts RTOS differences
|
||||
|
||||
Interrupt Handling
|
||||
------------------
|
||||
|
||||
**Interrupt Service Routine**:
|
||||
- Minimal processing in ISR
|
||||
- Event capture and queuing only
|
||||
- Quick return to avoid blocking
|
||||
|
||||
**Deferred Processing**:
|
||||
- All complex processing in task context
|
||||
- Thread-safe access to data structures
|
||||
- Application callbacks in known context
|
||||
|
||||
Memory Usage Patterns
|
||||
---------------------
|
||||
|
||||
**Flash Memory**:
|
||||
- Core stack: 8-15KB depending on features
|
||||
- Each class: 1-4KB additional
|
||||
- Portable driver: 2-8KB depending on MCU
|
||||
|
||||
**RAM Usage**:
|
||||
- Core stack: 1-2KB
|
||||
- Endpoint buffers: User configurable
|
||||
- Class buffers: Depends on configuration
|
||||
Reference in new issue
Block a user