Memory-Mapped IO: How C Talks to Hardware
No drivers.
No APIs.
Just addresses that control silicon.
1. The Illusion of Memory
In embedded systems, not all memory is RAM.
Some addresses are wired directly to hardware registers. Reading or writing to these addresses does not access memory — it controls hardware.
The CPU does not distinguish between RAM and peripherals. It simply executes load/store instructions. The meaning of the address is defined by the hardware.
Some addresses are wired directly to hardware registers. Reading or writing to these addresses does not access memory — it controls hardware.
The CPU does not distinguish between RAM and peripherals. It simply executes load/store instructions. The meaning of the address is defined by the hardware.
2. Registers Behind Addresses
Peripherals expose control registers at fixed addresses in the memory map.
For example:
From the perspective of C, this is just pointer dereferencing.
From the perspective of hardware, it is control signals on a bus.
For example:
- writing to an address may enable a peripheral
- reading from an address may return a hardware status
- setting a bit may trigger a physical action
From the perspective of C, this is just pointer dereferencing.
From the perspective of hardware, it is control signals on a bus.
3. Every Access Has a Side Effect
Unlike normal memory, MMIO is not passive.
This means memory operations are no longer just data access — they are operations with physical consequences.
- A read may clear a status flag
- A write may start a transmission
- Repeated access may produce different values
This means memory operations are no longer just data access — they are operations with physical consequences.
4. The Compiler Is Not Aware
The compiler assumes memory behaves like RAM unless told otherwise.
Without proper constraints, it may:
For hardware, this is incorrect behavior.
This is why MMIO access must be treated carefully — the compiler must be forced to respect every access exactly as written (often via the
Without proper constraints, it may:
- remove repeated reads
- cache values in registers
- reorder instructions
For hardware, this is incorrect behavior.
This is why MMIO access must be treated carefully — the compiler must be forced to respect every access exactly as written (often via the
volatile keyword).
5. Where It Breaks
MMIO bugs are often subtle and hardware-dependent.
Common failure patterns:
These issues do not always fail immediately. They often appear as intermittent hardware misbehavior.
Common failure patterns:
- reading a register once and reusing stale data
- writing in the wrong order, breaking hardware timing
- missing required delays between operations
- incorrect bit manipulation affecting unrelated hardware states
These issues do not always fail immediately. They often appear as intermittent hardware misbehavior.
6. Firmware Reality
Memory-mapped I/O is the foundation of:
At this level, firmware is no longer just software — it is direct interaction with electronic circuits.
Understanding MMIO means understanding how software becomes hardware behavior.
Next
→ The volatile Keyword
- GPIO control
- peripheral drivers
- interrupt systems
- hardware initialization
At this level, firmware is no longer just software — it is direct interaction with electronic circuits.
Understanding MMIO means understanding how software becomes hardware behavior.