Hello! Welcome to the second module of our course.
In our last lesson, we concluded our deep dive into the ARM core by mastering assembly-level debugging with a JTAG debugger. You learned how to step through instructions, inspect registers, and set advanced watchpoints on specific memory addresses. This raised a crucial question: what do these raw memory addresses actually represent?
Today's lesson answers that question. We begin Module 2, "Embedded C and Memory-Mapped Peripherals," by tackling our first learning outcome: Explain the memory map architecture in ARM-based microcontrollers, including code, SRAM, and peripheral regions.
Think of this as moving from looking at a single street corner (a memory address) to studying the entire city map. Understanding this map is the absolute foundation for low-level driver development, as it tells you where everything in the system lives—your code, your data, and the hardware peripherals you need to control.
1. The Big Picture: A Unified Address Space
From the CPU's perspective, the world is a simple, linear sequence of addresses. On a 32-bit ARM Cortex-M processor, this means the CPU can address 232 bytes, creating a 4 Gigabyte (4GB) address space. Every component—internal flash, internal RAM, GPIO ports, timers, and even the CPU's own control registers—is assigned a unique address range within this single, unified space.
However, the logical view seen by the CPU is an abstraction. Physically, these components are distinct hardware blocks, some inside the microcontroller System-on-Chip (SoC) and some potentially external. The memory map is the architectural blueprint that defines how these physically separate components are mapped into the CPU's single address space.
Introduction to Cortex M0+ - Memory Map
To start, let's watch a segment from the 'Introduction to Cortex M0+ - Memory Map' video. It does an excellent job of explaining this concept of a single 4GB address space and the distinction between the processor's logical view and the physical hardware.
Watch the video from the beginning to 02:25 and then from 09:37 to 11:19. Focus on these key ideas: The processor sees a continuous 4GB block of memory locations. Physically, these memory locations correspond to different types of memory (Flash, RAM) and peripherals, which are located in different places on the chip.
2. The Key Regions of the Memory Map
While the specific layout is determined by the microcontroller vendor (like ST, NXP, or TI), ARM provides a standardized template for Cortex-M processors that divides the 4GB address space into several major regions. Let's explore the most important ones for a driver developer.

For our purposes, we will focus on three primary regions:
a. Code Region (Flash Memory)
- Address Range (Typical): Starts near the bottom, often at
0x00000000or0x08000000. - Purpose: This region is mapped to non-volatile memory, almost always the on-chip Flash memory. It stores your executable program instructions. It also holds any read-only data, such as
constvariables and string literals. - Key Feature: When you compile your project, the linker places the
.text(code) and.rodata(read-only data) sections here. At the very beginning of this region is the vector table, which contains the initial stack pointer value and the address of the Reset Handler—the first code the CPU executes after a reset.
b. SRAM Region (RAM)
- Address Range (Typical): Often starts at
0x20000000. - Purpose: This is mapped to the on-chip Static RAM (SRAM), which is volatile read/write memory. It's used for all of your runtime data.
- Key Contents:
- The Stack: Used for function call frames, storing return addresses, and local variables. It typically grows downwards from the top of SRAM.
- The Heap: Used for dynamic memory allocation (e.g., with
malloc). - Global and Static Variables: The linker script places the
.data(initialized non-zero variables) and.bss(zero-initialized variables) sections here.
c. Peripheral Region
- Address Range (Typical): Often starts at
0x40000000. - Purpose: This is arguably the most important region for a driver developer. Addresses in this range do not map to conventional memory. Instead, they map directly to the control, status, and data registers of the hardware peripherals on the microcontroller.
- Mechanism: This is called Memory-Mapped I/O (MMIO). When your code writes a value to a specific address in this region, you are not storing data in RAM; you are directly configuring a hardware peripheral. For example, writing to a GPIO "Output Data Register" address changes the voltage on a physical pin.
The concept of Memory-Mapped I/O is fundamental. This video provides a concise explanation and gives a concrete example of how GPIO peripheral registers are mapped into memory.
Please watch the entire video. It first explains what Memory-Mapped I/O is and then walks through the standard ARM memory regions, finishing with a practical example showing the register map for a GPIO port on an STM32 microcontroller.
Test your understanding!
Consider the following C code snippet intended for an ARM microcontroller:
const int CALIBRATION_VALUE = 100;
int g_sensor_reading = 0;
void process_data(int input) {
char local_buffer[32];
// ... function logic ...
}
In which memory region (Code, SRAM, or Peripheral) would each of the following typically reside at runtime?
- The machine code for the
process_datafunction. - The
CALIBRATION_VALUEconstant. - The global variable
g_sensor_reading. - The
local_bufferarray.
Show answer
- Code Region: The executable instructions for
process_dataare part of the program's code, stored in Flash. - Code Region: Because
CALIBRATION_VALUEis declaredconst, the compiler will place it in a read-only data section (.rodata), which resides in Flash. - SRAM Region:
g_sensor_readingis a modifiable global variable, so it will be placed in either the.dataor.bsssection within SRAM. - SRAM Region:
local_bufferis a local variable. Space for it is allocated on the stack each timeprocess_datais called. The stack resides in SRAM.
3. From Architecture to Implementation: The Datasheet
The memory map provides the essential addresses you need to interact with the hardware. But where do you find this map? The definitive source is always the microcontroller's reference manual or datasheet.
Your experience with AUTOSAR involves analyzing ARXML files to understand system configuration. For a bare-metal or MCAL developer, the reference manual is the equivalent source of truth for the hardware's configuration. It provides the exact base addresses for every peripheral and the offset and bit-layout for every register within that peripheral.
A bare metal programming guide - Memory and registers
Let's see how this works in practice. This section from a bare-metal programming guide demonstrates how to use an STM32F429 datasheet to find the memory map and the specific addresses for Flash, RAM, and a GPIO peripheral.
Read the sections 'Introduction' and 'Memory and registers'. Focus on how the author refers to the datasheet (sections 2.3.1, 2.4) to find the starting addresses and sizes of RAM and Flash, and the base address of the 'GPIOA' peripheral region. This is the exact process you will follow in your work.
This practical step of cross-referencing the architectural concept (memory map) with the vendor's documentation (datasheet) is a core skill for the role you are preparing for.
Interview Preparation
Understanding the memory map is a frequent topic in interviews for embedded roles. Be ready to articulate these concepts clearly.
-
Question: "Could you describe the typical memory map of an ARM Cortex-M microcontroller and the purpose of its main regions?"
- Answer: "An ARM Cortex-M has a 32-bit, 4GB unified address space. This space is partitioned into standard regions. The Code region, typically mapped to on-chip Flash, stores the program instructions and read-only data. The SRAM region is volatile memory used for runtime data, including the stack, heap, and global variables. The Peripheral region is crucial for driver development; it uses Memory-Mapped I/O, where addresses don't point to memory but to hardware registers of peripherals like GPIO, UART, and timers, allowing software to control the hardware by reading from and writing to these addresses."
-
Question: "You need to toggle a pin using a GPIO peripheral. What's your process for finding the correct memory address to write to?"
- Answer: "My first step is to consult the microcontroller's reference manual. First, I'd look at the main memory map to find the base address for the specific GPIO peripheral I need, for example, 'GPIOB'. Then, I'd go to the chapter detailing the GPIOB peripheral itself. That chapter will contain a register map, which lists all of the peripheral's registers—like the Mode Register (MODER) and Output Data Register (ODR)—along with their offsets from the peripheral's base address. The final address is the peripheral base address plus the register's offset."
-
Question: "What is Memory-Mapped I/O, and what is its main advantage?"
- Answer: "Memory-Mapped I/O is a method where hardware peripheral registers are mapped into the processor's main memory address space. The main advantage, especially in a RISC architecture like ARM, is that no special I/O instructions are needed. The processor can use its standard load and store instructions (
LDR,STR) to interact with peripherals, just as it would with regular memory. This simplifies the instruction set and allows the full power of the C language, particularly pointers, to be used for hardware manipulation."
- Answer: "Memory-Mapped I/O is a method where hardware peripheral registers are mapped into the processor's main memory address space. The main advantage, especially in a RISC architecture like ARM, is that no special I/O instructions are needed. The processor can use its standard load and store instructions (
Conclusion
Today, we've put a map to the territory. You now understand the fundamental architecture that governs how software interacts with hardware at the lowest level. This knowledge is the bedrock upon which all driver development is built.
Key Takeaways:
- An ARM Cortex-M processor has a unified 4GB address space.
- This space is divided into regions: Code (Flash) for instructions, SRAM for runtime data, and Peripherals for hardware control.
- Interaction with peripherals happens via Memory-Mapped I/O (MMIO), where reads and writes to specific addresses manipulate hardware registers directly.
- The microcontroller reference manual is the authoritative source for the exact addresses and layouts for a specific chip.
Next Lesson Preview:
Now that we know where the peripheral registers are located in the memory map, our next lesson will focus on how to access them safely and efficiently from C code. We will cover the crucial volatile keyword and the use of pointers to read and write directly to these hardware addresses, bringing us one step closer to writing our first driver.