5 Memory-Mapped I/O, Register Abstractions, and Low-Level Control on Cortex-M
- Memory-mapped I/O on Cortex-M: 4 GB map, core/system blocks, and where peripherals live.
- Memory types & ordering: Device vs Normal, volatile access, and
DMB/DSB barriers.
- From raw pointers to
embedded-hal: a progression through volatile access, PACs, and HALs.
- Data layout & placement:
repr©, repr(align), packed pitfalls, cache-line alignment, #[link_section], and vector table placement.
- Low-level intrinsics:
cortex_m::asm for barriers, sleep/wake (wfe/sev), debug (bkpt).
- Assembly integration:
asm!/global_asm!, operand constraints, clobbers and linking external .S files.
5.1 What are memory-mapped I/Os in a microcontroller?
5.1.1 The memory map
5.1.2 What is memory-mapped?
5.1.3 From the CPU’s perspective
5.2 Rust’s Embedded ecosystem: Abstractions and unsafe code
5.2.1 Unsafe code: A necessary evil
5.2.2 Accessing registers via raw pointers
5.2.3 Using read_volatile and write_volatile
5.2.4 Safer MMIO with the volatile-register crate
5.2.5 Real-World examples
5.3 Working with Peripheral Access Crates (PACs) & Hardware Abstraction Layers (HALs)
5.3.1 From Unsafe Code to Safe Wrappers
5.3.2 Introducing svd2rust and auto-generated PACs
5.3.3 Using a PAC: stm32f1xx GPIO example
5.3.4 Moving up to the HALs
5.3.5 The Role of embedded-hal
5.4 Memory & data placement considerations
5.4.1 Understanding data alignment and layout
5.4.2 Struct layout
5.4.3 Packed layout and alignment
5.4.4 Section placement with #[link_section]
5.6 Summary