CPU–Peripheral I/O Communication: Approaches and Trade-offs
🟠 Data Transmission Between CPU and Peripheral Devices via I/O Methods
Method | Description | Usage Frequency | ✅ Advantages | ❌ Disadvantages | 🛠️ Tools / Crates |
---|---|---|---|---|---|
MMIO (Memory-Mapped I/O) | Peripherals are mapped into the memory space; accessed via standard load/store instructions. | ~90% in microcontrollers (`ARM`, `RISC-V`, etc.) |
- Simple programming model - Works on most architectures (`ARM`, `RISC-V`, `x86`, `MIPS`) - High performance - Unified memory and peripheral addressing - Easy access via standard Rust code (`unsafe` with `volatile`) |
- CPU can be busy polling - Requires memory protection (`MPU`/`MMU`) in complex systems - Needs care with caching (often regions marked as `non-cacheable`) - Address layout can get complex in large SoCs |
cortex-m , riscv , volatile-register , peripheral
|
PMIO (Port-Mapped I/O) | Uses a separate `I/O` address space and dedicated instructions like in / out . |
Primarily x86 |
- Strict separation of memory and I/O - Supported by legacy PC hardware |
- Non-portable (requires special instructions) - Not supported on modern microcontrollers |
Not **applicable in Rust** embedded; mostly C/ASM for x86 |
PIO (Programmed I/O) | CPU directly polls the peripheral registers status (via `MMIO` or `PMIO`) in a loop. | Very common in simple or early-stage systems |
- Easy to implement - Works without `interrupts` or `DMA` |
- Very inefficient (CPU is fully occupied) - Poor scalability and power consumption |
Any HAL (e.g. embedded-hal ) with polling read/write
|
DMA (Direct Memory Access) | Data transfer between peripheral and memory handled by a dedicated DMA controller, not CPU. | Widely used in **high-throughput** peripherals |
- Offloads CPU - High-speed data transfer (e.g. `SPI`, `SDIO`, `Ethernet`) - Enables low-power, autonomous operation |
- Setup complexity - Requires compatible hardware - Needs careful buffer and interrupt handling |
stm32-dma , esp-hal , nrf-dma , manual register config
|
Interrupt-driven I/O | Peripherals signal the CPU via hardware interrupts to trigger event-driven processing. | Very common in `RTOS` and multitasking environments |
- Reactive and efficient - Good for low-latency responses (e.g. buttons, timers) - Frees CPU from busy-waiting - Integrates with task scheduling / `RTOS` |
- Requires careful handling of race conditions and priority - May introduce complexity in shared-state management |
#[interrupt] , cortex-m-rt , riscv-rt RTIC , embassy , freertos-rust , tock
|
Message-based I/O (mailbox, queues) | Communication via message passing (mailboxes, channels) typically in multicore `SoCs` or `OS-based systems`. | Used in SMP systems, OS kernels, Linux SoCs |
- Decouples processing from hardware - Highly scalable - Enables safe inter-core or inter-process communication |
- Requires advanced OS or firmware - Increased system complexity |
heapless::spsc , embassy-channel , tock IPC, RTOS queues
|
Read other posts?