SoC
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
  • Arm Cortex M3
  • Contact
Reading: Cortex-M3 Memory Region Types and Attributes
SUBSCRIBE
SoCSoC
Font ResizerAa
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Search
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Have an existing account? Sign In
Follow US
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
© S-O-C.ORG, All Rights Reserved.
Arm

Cortex-M3 Memory Region Types and Attributes

Andrew Irwin
Last updated: November 2, 2023 2:19 am
Andrew Irwin 13 Min Read
Share
SHARE

The Cortex-M3 is an ARM processor core designed for microcontroller applications. It has a Von Neumann architecture with separate code and data memory regions. The memory regions are divided into different types with specific attributes defined in the Memory Protection Unit (MPU). Understanding the Cortex-M3 memory regions and their attributes is important for effective software development.

Contents
Code Memory RegionCode Region SizeExecuting Code from RAMSRAM Memory RegionSRAM Region SizeExecuting Code from SRAMPeripheral Memory RegionPeripheral Region SizeExternal Memory RegionExternal Memory Region SizeSystem Memory RegionSystem Memory Region SizeMemory Access PermissionsUnprivileged vs Privileged AccessMemory Alignment and SizeOverlapping Memory RegionsCacheability AttributesMemory Region ProgrammingDefault Memory MapMPU Region PriorityMPU Programming ExamplesCode RegionSRAM Data RegionPeripheral RegionDebugging MPU Memory FaultsMPU LimitationsUsing the MPU EffectivelyConclusion

Code Memory Region

The code memory region contains the executable program code for the Cortex-M3 processor. It is read-only memory that cannot be written to at runtime. The MPU allows configuring the code region attributes:

  • Executable – Code memory is executable
  • Non-executable – Code memory is non-executable
  • Read-only – Code memory is read-only
  • Read/write – Code memory is readable and writable

Typically, the code memory region is configured as executable and read-only. Making the code region read/write allows self-modifying code capabilities. Setting the region as non-executable protects against malicious code execution.

Code Region Size

The Cortex-M3 supports up to 1MB of code memory. The exact size depends on the target microcontroller device. Code memory is implemented as internal flash, external flash, or ROM.

Executing Code from RAM

Although uncommon, it is possible to execute code from RAM instead of flash memory on the Cortex-M3. This requires configuring a RAM region as executable and copying code from flash to RAM at runtime. Executing code from RAM has the advantage of higher performance compared to flash.

SRAM Memory Region

The SRAM memory region contains volatile data used during program execution. It is readable and writable at runtime. The MPU allows configuring the SRAM region attributes:

  • Executable – SRAM is executable
  • Non-executable – SRAM is non-executable
  • Read-only – SRAM is read-only
  • Read/write – SRAM is readable and writable (default)

Typically, SRAM is configured as non-executable and read/write data memory. Setting the region as read-only prevents accidental writes and provides some data integrity protection.

SRAM Region Size

The Cortex-M3 supports up to 64KB of SRAM data memory. The actual size available is device-specific. SRAM provides fast access for frequently used data during program execution.

Executing Code from SRAM

SRAM can be configured as executable memory to allow executing code loaded into SRAM at runtime. This provides better performance compared to executing code directly from flash. However, SRAM is more limited in size than flash memory.

Peripheral Memory Region

The peripheral memory region provides access to on-chip peripherals such as timers, GPIO, communication interfaces, etc. The region is read/write by default. The MPU allows configuring the peripheral region attributes:

  • Executable – Peripherals are executable (not applicable)
  • Non-executable – Peripherals are non-executable (default)
  • Read-only – Peripherals are read-only
  • Read/write – Peripherals are readable and writable (default)

Typically, the peripheral region is configured as non-executable and read/write. Setting the region as read-only prevents accidental writes to peripherals registers.

Peripheral Region Size

The peripheral region size depends on the specific microcontroller device and number of on-chip peripherals. The region is mapped to provide access to all peripherals. Accesses are handled via memory-mapped I/O.

External Memory Region

The external memory region provides access to off-chip memories through the external bus interface. This includes external flash, SRAM, and other memories. The MPU allows configuring the external memory region attributes:

  • Executable – External memory is executable
  • Non-executable – External memory is non-executable
  • Read-only – External memory is read-only
  • Read/write – External memory is readable and writable

The configuration depends on the type of external memory. For example, external flash could be configured as executable and read-only. External SRAM could be configured as read/write data memory.

External Memory Region Size

The Cortex-M3 supports up to 64MB of external memory. The actual size depends on the microcontroller’s external bus interface and memory devices connected. External memory provides flexibility to extend code and data storage beyond internal memory capacity.

System Memory Region

The system memory region provides access to system control registers including NVIC, SysTick, MPU registers, etc. This region is read/write by default but can be configured as read-only by the MPU for write protection.

Since the system memory region covers critical system control registers, it should always be handled with care in software. Accidental writes can put the processor into unwanted states.

System Memory Region Size

The system memory region is a small fixed size, typically a few KB, to provide access to all system control registers. The exact size depends on the Cortex-M3 implementation in the specific microcontroller device.

Memory Access Permissions

The MPU allows configuring access permissions for each defined memory region. The permissions act as memory protection when accessing each region and include:

  • No access – All accesses generate fault
  • Read-only – Reads permitted, writes generate fault
  • Write-only – Writes permitted, reads generate fault
  • Read/Write – Reads and writes permitted

Typically, code memory is read-only, SRAM data memory is read/write. Peripherals and system memory are read/write by default but can be protected with read-only access.

Unprivileged vs Privileged Access

Another aspect of the MPU access permissions is unprivileged versus privileged access modes. The Cortex-M3 Handler mode is privileged while Thread mode is unprivileged. Memory regions can be configured to allow or block access based on privilege mode.

Memory Alignment and Size

The MPU allows configuring region size and alignment down to 1KB granularity. Size ranges from 1KB to 4GB. Alignment sets the start address granularity. Together, size and alignment allow carving the 4GB memory map into defined regions.

Setting size and alignment appropriately is important to maximize utilization of memory resources. Overly coarse alignment or size configuration can lead to unused gaps in the memory map.

Overlapping Memory Regions

It is possible to define overlapping memory regions with the MPU. In that case, the region with the highest numbered MPU register takes priority and overrides attributes of other overlapping regions. This provides a memory map override mechanism.

However, overlapping regions can also lead to unexpected behavior if not configured properly. It is best to keep regions non-overlapping whenever possible for simplicity.

Cacheability Attributes

Memory regions can be configured as cacheable or non-cacheable. Cacheability indicates whether memory accesses should be cached in the processor’s memory cache. Caching provides higher performance for memory reads.

However, cache coherency must also be handled appropriately especially for memory that can be accessed by multiple bus masters. Non-cacheable attribute disables caching for a memory region.

Memory Region Programming

The MPU memory regions are defined in software at runtime during system initialization. This allows full flexibility in configuring the memory map.

To program a memory region, the following steps are performed:

  1. Disable MPU (if enabled)
  2. Configure desired attributes in MPU register for region
  3. Set valid bit in MPU register to activate region
  4. Re-enable MPU

All active memory regions should be defined before enabling the MPU. The number of available MPU registers dictates how many regions can be active concurrently.

Default Memory Map

At reset, the MPU is disabled and the default memory map is active. This provides access to all memory regions with default attributes:

  • Code region: Executable, Read-only
  • SRAM region: Non-executable, Read/Write
  • Peripheral region: Non-executable, Read/Write
  • External memory: Varies based on memory devices
  • System region: Read/Write

The default memory map provides full access functionality to all memory regions simultaneously. The MPU overrides this with user-defined regions.

MPU Region Priority

As mentioned earlier, higher numbered MPU registers have priority over lower numbered regions if there is overlap. This rule allows overriding attributes in a certain region of the memory map by defining a higher priority MPU region.

To avoid ambiguity, key memory regions like code and SRAM data should be defined in the higher priority MPU registers. Peripherals and external memory can use the lower registers.

MPU Programming Examples

Here are some examples of programming the MPU to define memory regions:

Code Region

MPU->REG[0] = 0x00000008; // 1MB code region size MPU->REG[1] = 0x00000000; // Code region base address MPU->REG[2] = 0x030C1437; // Executable, Read-only, Non-cacheable MPU->REG[3] = 0x01000000; // Code region enable

SRAM Data Region

MPU->REG[4] = 0x00000040; // 64KB SRAM size MPU->REG[5] = 0x20000000; // SRAM base MPU->REG[6] = 0x030C1417; // Non-executable, Read/Write, Non-cacheable MPU->REG[7] = 0x01000000; // SRAM region enable

Peripheral Region

MPU->REG[8] = 0x0007A120; // Peripheral region size (device specific) MPU->REG[9] = 0x40000000; // Peripheral base address MPU->REG[10] = 0x030C1417 // Non-executable, Read/Write, Non-cacheable MPU->REG[11] = 0x01000000; // Peripheral region enable

The above examples show how code, SRAM, and peripheral regions can be configured with different attributes using the MPU registers. Once enabled, the MPU will enforce these attributes on memory accesses.

Debugging MPU Memory Faults

When the MPU is enabled, any memory access that violates the configured attributes or permissions will generate a memory fault exception. This results in the following:

  • Exception entry into MemManage handler
  • HALTED debug state
  • Memory Management Fault Status Register (MMFSR) updated with violation details

Debugging MPU faults requires checking the MMFSR register to identify the violating region and memory access address. This information helps correct the MPU configuration or software memory access to eliminate the violation.

MPU Limitations

While the MPU provides memory protection, it has some limitations:

  • Finite number of regions – Up to 16 on Cortex-M3
  • 1KB minimum region size granularity
  • Protection disabled during exception handling
  • No guarantee against malware attacks

So the MPU does not provide complete memory safety. Additional mechanisms like Stack Overflow detection may be needed. Security-critical systems may utilize an MMU instead.

Using the MPU Effectively

Here are some tips for using the Cortex-M3 MPU effectively:

  • Define all key memory regions – Code, SRAM, Peripherals
  • Add read-only protection to immutable regions
  • Keep regions non-overlapping if possible
  • Set alignment and size appropriately to avoid gaps
  • Use higher priority MPU registers for critical regions
  • Enable MPU early during system startup
  • Validate all memory access during development

Proper configuration and usage of the MPU can improve software reliability and provide protection against accidental memory corruption.

Conclusion

The Cortex-M3 MPU provides configurable memory regions with definable attributes including access permissions. This allows creating a customized memory map tailored to the application requirements. Appropriately configuring MPU regions helps improve system reliability and protect memory integrity during runtime. However, care must be taken to fully validate memory access to avoid MPU faults. Overall, the Cortex-M3 MPU is an invaluable tool for creating robust and secure embedded software.

Newsletter Form (#3)

More ARM insights right in your inbox

 


Share This Article
Facebook Twitter Email Copy Link Print
Previous Article Cross-Compiling for 32-bit ARM Cortex-M4 Cores
Next Article SoCs using Cortex-A76 cores (Kirin, Exynos, Snapdragon, etc)
Leave a comment Leave a comment

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

2k Followers Like
3k Followers Follow
10.1k Followers Pin
- Sponsored-
Ad image

You Might Also Like

What is ARM Cortex M0?

The ARM Cortex-M0 is a 32-bit processor core designed by…

8 Min Read

ARM Cortex M4 vs Raspberry Pi

The ARM Cortex-M4 and Raspberry Pi are two very different…

7 Min Read

Will The Arm Architecture Replace The X86/X64 Architecture?

The short answer is that while ARM is making inroads…

6 Min Read

Cortex-M Exception Handling and Return Mechanism

The Cortex-M processor implements robust exception handling capabilities to respond…

6 Min Read
SoCSoC
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
Welcome Back!

Sign in to your account