0% found this document useful (0 votes)
35 views9 pages

STM32F411 Microcontroller Memory Map

This document discusses the memory map of the STM32F411 microcontroller, detailing its 4 GB addressable space divided into 8 blocks of 512 MB each. It explains the allocation of memory for code, SRAM, peripherals, and reserved areas, as well as the boot modes determined by BOOT pins. Additionally, it covers the concept of Option Bytes for security configurations and the bit-banding feature for efficient memory manipulation.

Uploaded by

Sathyan Chandran
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
35 views9 pages

STM32F411 Microcontroller Memory Map

This document discusses the memory map of the STM32F411 microcontroller, detailing its 4 GB addressable space divided into 8 blocks of 512 MB each. It explains the allocation of memory for code, SRAM, peripherals, and reserved areas, as well as the boot modes determined by BOOT pins. Additionally, it covers the concept of Option Bytes for security configurations and the bit-banding feature for efficient memory manipulation.

Uploaded by

Sathyan Chandran
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

Here’s the corrected version of your script, keeping the format intact:

---

Welcome to part 4.

In the last part, we discussed the internal architecture of the STM32F411


microcontroller. In this part, we will explore the memory map of this
microcontroller.

Using the example of a restaurant: there are several tables in a restaurant that
are serviceable. A restaurant may have 10 or 15 tables, depending on its size. If
we add more tables, it would become congested, right?

So, there is a limit to the number of addressable tables. Similarly, in the case of
a microcontroller, the CPU can service only a limited range of addresses.

We previously discussed 8-bit controllers, 16-bit controllers, and 32-bit


controllers. The controller we are using now is a 32-bit microcontroller. So, our
32-bit microcontroller can service \(2^{32}\) different addresses. \(2^{32}\)
equals a 4 GB address space.

That is **4,294,967,296** in decimal. The CPU can access any address within this
range to fetch data stored in memory. In hexadecimal, the address range is from
`0x00000000` to `0xFFFFFFFF`.

Theoretically, the CPU can access this entire 4 GB address space. If it needs to
fetch data from a particular memory location, that location must fall within this 4
GB region.

Similarly, if we need to retrieve an instruction or data from SRAM, that SRAM


region will also fall within this address range. If we are communicating with
peripherals via the system bus, the peripheral addresses will also reside within
this 4 GB space.

In the STM32F411 microcontroller, this 4 GB memory space is divided into 8 parts of


0.5 GB each. The first 512 MB belongs to Block 0, the next 512 MB to Block 1, and
so on, up to Block 7, starting from Base 0.

So, what is mapped in each block? Let’s check the details in the reference manual.

Now, turning to the STM32F411 microcontroller's datasheet, let’s look at Section 5:


**Memory Mapping**. In this section, they’ve detailed the overall memory map of the
microcontroller. Within the range from `0x00000000` to `0xFFFFFFFF`, the 4 GB
addressable memory space is divided into 8 blocks of 512 MB each, just as we
discussed earlier.

If we count here, there are 1, 2, 3, 4, 5, and 6 blocks, which total 3 GB. The
remaining 1.5 GB (3 × 512 MB blocks) is reserved. The reason for this reserved area
will be explained later.

For Block 0, the **Code Memory** is allocated 512 MB. However, our microcontroller
has only 512 KB of Flash memory, as mentioned in the datasheet.

The 512 MB allocation in the memory map is the theoretical size allowed by the ARM
CPU architecture.

---
The size of flash memory increases in the higher series of microcontrollers.
However, in this controller, only 512 KB of flash memory is used within the entire
512 MB block.

If we look closely, there is an address space that can be aliased to flash memory,
system memory, or SRAM, depending on the **BOOT pins** configuration. When you
resolve these numbers, you’ll find that 512 KB of memory is aliased to flash memory
or SRAM based on the state of the BOOT pins.

This entire table corresponds to the 512 MB Code block. The alias to flash memory
means that the flash memory starts at address `0x08000000` and extends up to 512
KB. Beyond that, there is **system memory**, which we’ll discuss shortly, followed
by **option bytes**—we will also cover those. Additionally, there are regions of
reserved memory at various locations.

When we resolve all these, it becomes clear that the flash memory starts at
`0x08000000`. However, this memory is aliased by the memory regions shown below,
meaning they are **virtual addresses**.

When you power on the microcontroller, it needs to boot up. It can boot from one of
three different memory regions, determined by the BOOT pins. The microcontroller
has two BOOT pins: **BOOT0** and **BOOT1**. These pins decide the boot
configuration.

If we refer to the datasheet again, in Section 3.13: **Boot Modes**, we see that
the boot modes allow the selection of one out of three options:
1. Boot from flash memory
2. Boot from system memory
3. Boot from embedded SRAM

So now you know about boot modes. What are BOOT pins?

STM32F4 microcontrollers include a special mechanism to enable booting from other


memories, such as the internal SRAM.

---

STM32F4 microcontrollers implement a special mechanism to boot from other memories,


such as internal SRAM.

On this board, there are two pins called **BOOT0** and **BOOT1**. By configuring
these pins as high or low, you can select the boot mode.

- If you want to boot from the main flash memory, simply set the BOOT0 pin to
**Low**. The state of BOOT1 does not matter in this case. As soon as the
microcontroller starts up, it will execute code from the flash memory.
- If the BOOT0 pin is set to **High**, the microcontroller will boot from **system
memory**.
- If both BOOT0 and BOOT1 are set to **High**, the microcontroller will boot from
**SRAM**.

By default, microcontrollers typically boot from flash memory. On our development


board, as per the schematics, the BOOT0 pin is configured as Low, so the system
boots from the main flash memory.

### What is system memory?


System memory is a special region that contains the **bootloader**.

According to the datasheet, the size of the system memory is **30 KB**, while the
flash memory is **512 KB**.

### What are the advantages of booting from system memory?


System memory holds the bootloader, which plays a critical role in firmware
upgrades. For example, in devices like set-top boxes or DVD players, there is often
a USB port that allows you to update the firmware.

The bootloader enables this special mode, allowing the firmware of the
microcontroller to be updated securely and safely.

In normal operation, when the application code is running from flash memory,
upgrading the firmware is nearly impossible due to the risk of overwriting the
active code.

However, by jumping to the bootloader, the microcontroller enters a special mode


designed specifically for firmware upgrades, ensuring the process is both safe and
secure.

The bootloader includes security features to authenticate the firmware and verify
its integrity.

Using the bootloader, you can safely replace the old firmware with a new version.
While there are many other functionalities the bootloader offers, we won’t dive
into those details today.

Earlier, I mentioned USB as an example for updating firmware. However, according to


the datasheet, there are several methods available for reprogramming or upgrading
the firmware. These include **USART**, **USB**, **I2C**, and **SPI**. Multiple
options are provided to ensure flexibility in firmware updates.
---
Here’s the revised version of your script:

---

The system memory is essential for updating firmware.

Next, we have **reserved memory** with a size of 125 MB. Any read or write
operation in this region will have no effect.

This reserved memory exists because, while the CPU architecture allows these
addresses to be used, the microcontroller vendor, ST, didn’t physically realize
this memory. Therefore, it is marked as reserved.

After the reserved memory, we have **Flash memory**, which is 512 KB in size.
Beyond that, there’s another **300 MB of reserved memory**. Then, we have **System
memory** with a size of 30 KB, along with some space reserved for future expansion.
Finally, there are the **Option Bytes**.

This completes the description of the entire 512 MB block. We’ve covered everything
except Option Bytes. So, what are Option Bytes?

You can find information about Option Bytes in the datasheet. These are special
configurations set by the end user depending on application requirements. They
enable different modes, including protection levels, to be configured.

One of the modes is **Level 0 – No Protection**.


In this mode:
- You can write code to the flash, debug it, and erase the flash.
- Anyone can read the flash memory and decompile your code.
- The microcontroller doesn’t offer any protection for your application.

If you sell a product with **No Protection** enabled, your flash memory can be read
and your proprietary code exposed. This is why Level 0 is not recommended for
commercial products.

By setting the protection level to **Level 1**, you can enable some security.
- In Level 1:
- Code execution from flash works as expected, but debugging is disabled.
- Although flash memory cannot be read, it can still be erased and reprogrammed.

The highest level of protection is **Level 2 – Chip Protection**.


- In Level 2:
- Debugging is entirely disabled.
- Booting from SRAM is also disabled.
- This ensures the highest level of security for your application.

Option Bytes occupy a small memory region from `0xC000` to `0xC007`, a total of **8
bytes**. Based on the values configured in this region, protection levels are set,
and additional features, like the watchdog timer, can be enabled.

Let’s not go into further details about the other features today.

---
Here’s the revised version of the script:

---

So, **Option Bytes** are optional protection features that can be enabled as
needed.

Next, let’s move on to **Block 1 Memory**, which is dedicated to SRAM. Like the
previous block, this block is 512 MB in size. However, just as with flash memory,
the entire block isn’t utilized. The SRAM size for this microcontroller is **128
KB**, starting at address `0x20000000`. If you add 128 KB to this address, the
remaining portion of the 512 MB block is marked as **reserved**.

Why is it mentioned as **aliased by bit-banding**?

Bit-banding is an interesting feature, and I’ll explain it in detail at the end of


this video. For now, just know that this feature allows efficient manipulation of
individual bits in SRAM and peripheral regions.

Now, let’s move on to **Block 2 Memory**, another 512 MB block, which is dedicated
to **Peripherals**. This block starts at address `0x40000000` and spans up to 512
MB.

There is a small mistake in the document here: it shows both **Peripherals** and
**CPU Internal Peripherals** within this block. For now, we’ll focus only on the
**Block 2 Peripherals**.

In this block, the **APB** and **AHB peripherals** are mapped. This includes:
- **APB1 peripherals**
- **APB2 peripherals**
- **AHB1 peripherals**
- **AHB2 peripherals**

### Example:
For instance, the address range starting from `0x40000000` is mapped to the **Timer
2 Peripheral**.
- The addressable range for Timer 2 is from `0x40000000` to `0x400003FF`, which is
1 KB.
- To interact with Timer 2, you can access its registers within this address range.
- Similarly, to manipulate the **Timer 3 Peripheral**, you would interact with its
registers in its dedicated address range.

Every peripheral in this block is assigned a specific memory range for interaction.

We’ll discuss peripherals in greater detail in a separate video.

Now, within this block:


- **APB2 peripherals** include components like USART.
- **AHB1 peripherals** include **GPIO ports** (GPIOA, GPIOB, GPIOC, GPIOD, GPIOE,
and others). These peripherals are connected to the AHB1 bus.
- **AHB2 peripherals** include components like USB, which you can access using
addresses within this range.

For example, if you want to interact with GPIOA, you will use its specific address
range within the **AHB1 bus**. GPIOA itself contains many registers that you’ll
need to manipulate for various functionalities. We’ll cover GPIOs in detail in a
dedicated video.

Up to now, we’ve discussed how peripherals are mapped within the **Block 2
addressable memory**.

### Memory-Mapped I/O


The concept of addressing a peripheral to read from or write to it—just like
addressing memory—is called **Memory-Mapped I/O**.

---
Here’s the revised version with improved clarity while keeping the structure
intact:

---

Next, there is a Reserved section of size 1.5 GB. Along with an additional 0.5 GB,
the total comes to 2 GB. According to the Programmer’s Manual of the STM32F4
family, 1 GB is allocated for external devices and another 1 GB for external RAM.

Our memory map states that 1.5 GB cannot be used. This suggests that 0.5 GB of
space might be available for addressing an external device. However, the datasheet
indicates that this block is not utilized. So, while it is not technically
reserved, it remains unused. In theory, you could connect external memory to this
address, but there are several limitations, which we won’t discuss in this series.

What we need to focus on is understanding how to use the peripheral section, SRAM
section, and flash memory section.

As I mentioned at the beginning of the video, let's now talk about **bit banding**.

Referring to the Programmer’s Manual, each **word (32-bit)** in the **bit-band


alias region** maps to a specific bit in the **bit-band region**.

The alias region is virtual memory, whereas the bit-band region is actual physical
memory.

Here’s an example:
The SRAM region starts from **0x20000000** and increments by **1 byte**. Since a
byte consists of **8 bits**, address **0x20000000** contains 8 individual bits (0
to 7). A **word** (4 bytes) consists of **32 bits**.

Now, let's assume that **32 LEDs** are connected to these 32 bits.

If you need to turn **only one LED on or off**, you would typically:
1. Read the entire byte from memory.
2. Modify the required bit.
3. Write the updated byte back to the register.

This read-modify-write cycle introduces a problem: it can be interrupted by a


higher-priority event, such as an **interrupt**. If an interrupt occurs in the
middle of modifying data, it could lead to unintended behavior. I’ll discuss these
issues in more detail when we cover **OS concepts and ISRs (Interrupt Service
Routines).**

By default, the smallest unit we can read from memory is **1 byte (8 bits)**.
However, what if there were a way to **set or clear just a single bit in one
instruction?** Wouldn’t that be more efficient? This is where **bit-banding** comes
in—it allows **atomic operations**, preventing higher-priority interrupts from
interfering.

For example:
At address **0x20000000** (which is in the bit-band region), if we want to modify
bit 0, we can write to its alias address in the **bit-band alias region**, which
starts at **0x22000000** in virtual memory.

The alias address follows a pattern:


- **0x22000000** corresponds to bit **0** of **0x20000000**.
- The next alias address is **0x22000004**, which maps to bit **1** of
**0x20000000**.
- Each bit’s alias address increments by **4 bytes**.

So, instead of modifying the entire byte, we can directly write **0 or 1** to the
corresponding alias address, and the bit in the bit-band region will be updated.

This is the concept of **bit-banding**, and we can explore it further in future


videos.

Now, in the LED example, I mentioned **GPIO** as an application. However, that’s


not entirely accurate. GPIO has a dedicated **bit set/reset register (GPIOx_BSRR)**
that can manipulate individual bits even faster than the bit-banding method.

We will discuss GPIO in a separate video, but for today, just remember that bit-
banding works using a **virtual address that lets you set or clear a bit in actual
physical memory.**

---

### Block 7: Cortex-M4 CPU Internal Peripherals

The final **512 MB block (Block 7)** is reserved for the **Cortex-M4 CPU’s internal
peripherals**. This address space is managed by the CPU to handle its internal
operations. Like other blocks, many sections are **reserved**, while specific areas
are mapped to **internal peripherals**.

You can see these **internal CPU peripherals** in the block diagram. Some examples
include:
- **Nested Vector Interrupt Controller (NVIC)**
- **Memory Protection Unit (MPU)**
- **DSP Unit**
- **Floating Point Unit (FPU)**
- **Serial Wire Debugger (SWD)**

These peripherals help manage various CPU functions.

---
Next, there is a Reserved section of size 1.5 GB. Along with an additional 0.5 GB,
the total comes to 2 GB. According to the Programmer’s Manual of the STM32F4
family, 1 GB is allocated for external devices and another 1 GB for external RAM.

Our memory map states that 1.5 GB cannot be used. This suggests that 0.5 GB of
space might be available for addressing an external device. However, the datasheet
indicates that this block is not utilized. So, while it is not technically
reserved, it remains unused. In theory, you could connect external memory to this
address, but there are several limitations, which we won’t discuss in this series.

What we need to focus on is understanding how to use the peripheral section, SRAM
section, and flash memory section.

As I mentioned at the beginning of the video, let's now talk about bit banding.

Referring to the Programmer’s Manual, each word (32-bit) in the bit-band alias
region maps to a specific bit in the bit-band region.

The alias region is virtual memory, whereas the bit-band region is actual physical
memory.

Here’s an example:
The SRAM region starts from 0x20000000 and increments by 1 byte. Since a byte
consists of 8 bits, address 0x20000000 contains 8 individual bits (0 to 7). A word
(4 bytes) consists of 32 bits.

Now, let's assume that 32 LEDs are connected to these 32 bits.

If you need to turn only one LED on or off, you would typically:

Read the entire byte from memory.


Modify the required bit.
Write the updated byte back to the register.
This read-modify-write cycle introduces a problem: it can be interrupted by a
higher-priority event, such as an interrupt. If an interrupt occurs in the middle
of modifying data, it could lead to unintended behavior. I’ll discuss these issues
in more detail when we cover OS concepts and ISRs (Interrupt Service Routines).

By default, the smallest unit we can read from memory is 1 byte (8 bits). However,
what if there were a way to set or clear just a single bit in one instruction?
Wouldn’t that be more efficient? This is where bit-banding comes in—it allows
atomic operations, preventing higher-priority interrupts from interfering.

For example:
At address 0x20000000 (which is in the bit-band region), if we want to modify bit
0, we can write to its alias address in the bit-band alias region, which starts at
0x22000000 in virtual memory.

The alias address follows a pattern:

0x22000000 corresponds to bit 0 of 0x20000000.


The next alias address is 0x22000004, which maps to bit 1 of 0x20000000.
Each bit’s alias address increments by 4 bytes.
So, instead of modifying the entire byte, we can directly write 0 or 1 to the
corresponding alias address, and the bit in the bit-band region will be updated.

This is the concept of bit-banding, and we can explore it further in future videos.

Now, in the LED example, I mentioned GPIO as an application. However, that’s not
entirely accurate. GPIO has a dedicated bit set/reset register (GPIOx_BSRR) that
can manipulate individual bits even faster than the bit-banding method.

We will discuss GPIO in a separate video, but for today, just remember that bit-
banding works using a virtual address that lets you set or clear a bit in actual
physical memory.

Block 7: Cortex-M4 CPU Internal Peripherals


The final 512 MB block (Block 7) is reserved for the Cortex-M4 CPU’s internal
peripherals. This address space is managed by the CPU to handle its internal
operations. Like other blocks, many sections are reserved, while specific areas are
mapped to internal peripherals.

You can see these internal CPU peripherals in the block diagram. Some examples
include:

Nested Vector Interrupt Controller (NVIC)


Memory Protection Unit (MPU)
DSP Unit
Floating Point Unit (FPU)
Serial Wire Debugger (SWD)
These peripherals help manage various CPU functions.

### Memory Endianness

Before we conclude, let’s cover one last important concept: **Memory Endianness.**

What is **Endianness**?

Let’s take an example:


Assume an address **0x08000000**. Since our ARM CPU is **byte-addressable**, the
next addresses will be:
- **0x08000001**
- **0x08000002**
- **0x08000003**, and so on.

Now, suppose we store the 4-byte **hexadecimal number 0x12345678** at


**0x08000000**.

How will these bytes be stored?


That depends on whether the CPU follows **Little Endian** or **Big Endian** format.

Our STM32F411 microcontroller, based on the **ARM Cortex-M4**, follows the **Little
Endian** format.
- The **Least Significant Byte (LSB) → 0x78** is stored at **0x08000000**.
- The next byte **0x56** is stored at **0x08000001**.
- The byte **0x34** is stored at **0x08000002**.
- The **Most Significant Byte (MSB) → 0x12** is stored at **0x08000003**.

If the processor were **Big Endian**, the order would be reversed:


- **0x12** at **0x08000000**
- **0x34** at **0x08000001**
- **0x56** at **0x08000002**
- **0x78** at **0x08000003**

This **Endianness** concept is particularly important when communicating with


**external devices**. Some devices send data in **Big Endian** format, while our
processor uses **Little Endian**.

Endianness also plays a role in **networking protocols**, where data needs to be


interpreted correctly regardless of the system architecture.

---

### Conclusion

Alright, that brings us to the end of this video! We covered:


✅ The STM32F411 memory map
✅ Bit-banding and its advantages
✅ Cortex-M4 internal peripherals
✅ Memory endianness and its significance

Thanks for watching! See you in the next video! 🎯🔧🚀

Common questions

Powered by AI

Bit-banding in microcontrollers is a technique that allows single-bit manipulation through alias memory addresses, enabling atomic operations that prevent interruptions. By mapping a specific bit in physical memory to an alias address in virtual memory, direct bit setting or clearing without affecting other bits in the same word is possible. This eliminates the read-modify-write cycle's vulnerability to higher-priority interrupts, enhancing operational efficiency and reliability in real-time applications, such as LED control or other GPIO operations .

Booting from system memory offers significant benefits for microcontrollers, primarily because it contains the bootloader necessary for secure firmware upgrades. This is crucial in devices like set-top boxes, allowing firmware updates via various interfaces (USART, USB, I2C, SPI) without risking overwriting active application code in flash memory. The bootloader's role ensures safe transitions from one version of firmware to another while incorporating integrity-checking procedures, making it an essential component for maintaining a device's operability and security .

In STM32F411 microcontrollers, reserved memory spaces are part of a strategic design choice where the CPU architecture theoretically allows the memory addresses to be used, but these spaces aren't physically implemented by the vendor. This reservation allows flexibility for future expansions or additional functionalities without redesigning the hardware architecture. It indicates areas where peripherals or external devices could be theoretically connected, providing insights into potential upgrades or optimizations .

The STM32F411 memory map divides the 4 GB address space into 8 blocks, each 512 MB. These include code memory, system memory, and reserved regions, with a detailed structure supporting flash, SRAM, and peripheral interfaces. Only a fraction of these theoretically addressable blocks is physically realized due to cost and design considerations. This organization allows flexible interfacing with multiple peripherals and memory types, enabling diverse functionalities while ensuring efficient use of resources through strategic allocation of address space .

Memory-mapped I/O is crucial for interfacing peripherals because it treats peripherals like memory, using standard read and write operations to control them. This allows for efficient integration of peripherals (e.g., GPIO and USART) into the processor's existing architecture, simplifying command and data exchange. Consequently, programming becomes more intuitive, and operations such as data acquisition and peripheral control are streamlined, which is essential in the performance maximization of embedded systems .

The 4 GB address space in the STM32F411 microcontroller is critical because it defines the range of addresses that the CPU can service, which is essential for accessing data stored in memory. This address space is divided into 8 blocks of 512 MB each, allowing for organized mapping of various memory types and peripheral interfaces. Despite the microcontroller itself having only 512 KB of flash memory, the theoretical addressability highlights potential flexibility in memory expansion and peripheral interfacing .

In STM32F4 microcontrollers, the BOOT pins (BOOT0 and BOOT1) determine the boot configuration by selecting from three different boot modes: boot from flash memory, system memory, or embedded SRAM. BOOT0 being Low defaults the system to boot from flash memory, while setting BOOT0 High allows booting from system memory. Both pins set High enables booting from SRAM. This mechanism is crucial for selecting initial operating conditions and is particularly useful for firmware updates or debugging .

Option Bytes in STM32F4 microcontrollers play a key role in operational security by enabling user-set configurations such as protection levels. For example, Level 0 offers no protection, allowing free access to flash memory but exposing proprietary code. In contrast, Level 1 disables debugging and makes the flash memory unreadable while still executing code. These settings are integral for safeguarding sensitive information and ensuring that commercial products remain secure from unauthorized access or tampering, crucial for maintaining intellectual property confidentiality .

Memory aliasing to flash memory in STM32F411 microcontrollers is significant because it allows flexible mapping of the same physical memory across different address ranges, depending on the state of the BOOT pins. This aliasing facilitates boot-time decision-making and enhances the capability of the microcontroller to switch between different memory configurations without physically changing the circuit layout, enabling efficient memory resource management and versatility in application .

The Cortex-M4 CPU's internal peripherals in STM32F411 microcontrollers support crucial functions such as interrupt management, memory protection, and debugging. Internal peripherals, like the Nested Vector Interrupt Controller (NVIC), Memory Protection Unit (MPU), and the DSP and Floating Point units, enhance the microcontroller's performance by efficiently managing processing tasks and optimizing resource allocation. This integration of peripherals within the CPU enables robust handling of complex applications, contributing to the STM32F411's versatility across various embedded systems .

You might also like