0
0
Embedded Cprogramming~5 mins

Memory-mapped I/O concept in Embedded C

Choose your learning style9 modes available
Introduction

Memory-mapped I/O lets a program talk to hardware devices by reading and writing special memory addresses. This makes hardware control simple and fast.

When you want to control hardware like LEDs or buttons from your program.
When you need to read sensor data directly from hardware registers.
When writing embedded software for microcontrollers or processors.
When you want to send or receive data from peripherals like UART or SPI.
When you need fast access to hardware without extra communication steps.
Syntax
Embedded C
volatile uint32_t * const DEVICE_REGISTER = (volatile uint32_t *)0x40000000;

// Read value
uint32_t value = *DEVICE_REGISTER;

// Write value
*DEVICE_REGISTER = 0x12345678;

volatile tells the compiler the value can change anytime, so it must always read from memory.

The address (like 0x40000000) is the hardware register location.

Examples
Write 1 to the LED control register to turn on an LED.
Embedded C
volatile uint8_t * const LED_CONTROL = (volatile uint8_t *)0x50000000;
*LED_CONTROL = 0x01;  // Turn on LED
Read the current state of buttons from the hardware register.
Embedded C
volatile uint16_t * const BUTTON_STATUS = (volatile uint16_t *)0x50000010;
uint16_t status = *BUTTON_STATUS;  // Read button state
Send a character to UART by writing to its data register.
Embedded C
volatile uint32_t * const UART_DATA = (volatile uint32_t *)0x40001000;
*UART_DATA = 'A';  // Send character 'A' via UART
Sample Program

This program writes a value to a memory-mapped register and reads it back. It then prints the value to show how memory-mapped I/O works.

Embedded C
#include <stdint.h>
#include <stdio.h>

// Simulated hardware register address
volatile uint32_t * const SIMULATED_REGISTER = (volatile uint32_t *)0x20000000;

int main() {
    // Write a value to the hardware register
    *SIMULATED_REGISTER = 0xABCD1234;

    // Read back the value
    uint32_t val = *SIMULATED_REGISTER;

    // Print the value
    printf("Register value: 0x%X\n", val);

    return 0;
}
OutputSuccess
Important Notes

Always use volatile for memory-mapped registers to prevent compiler optimizations that skip actual memory access.

Memory addresses must match the hardware documentation exactly.

Accessing wrong addresses can cause crashes or unexpected behavior.

Summary

Memory-mapped I/O uses special memory addresses to control hardware devices.

Use pointers with volatile to read/write hardware registers safely.

This method makes hardware control simple and fast in embedded systems.