ARM Technical Support Knowledge Articles

What happens when the base address of an MPU region is not aligned with the region's size in PMSAv6 and PMSAv7?

Applies to: Cortex-M0Plus, Cortex-M3, Cortex-M4, Cortex-M7

Answer

A Memory Protection Unit (MPU) implements the Protected Memory System Architecture and is a de facto standard system peripheral found in many popular Cortex-M based devices, such as STM32 and LPC series MCUs. For a PMSAv6 or PMSAv7 compliant MPU, the region base address must be aligned with the region size. The region size has the value 2n bytes (4 < n ≤ 32), and is in the range 32 bytes to 4GB.  For example, if a region is 256KB in size, its base address must be a multiple of 256KB, that is 218 bytes. In other words, the address bits [17:0] must be zero. 

You can write any value to the ADDR field of the MPU Region Base Address Register, MPU_RBAR[31:5]. However, only the MPU_RBAR[31:(n+1)] bits are taken into consideration and the remaining bits are Read-As-Zero, Writes Ignored (RAZ/WI).

The following CMSIS-compliant example unsuccessfully attempts to set the region 0 to the range 0x20010000-0x2004FFFF:

-------------------------8<-------------------------

/* Force any outstanding transfers to complete before disabling MPU */
__DMB();

/* Disable MPU */
MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;

/* Configure region 0 to start at 0x2001000 and cover 256KB memory (Normal, Not shareable, Non-cacheable, User Read-only) */
MPU->RBAR = 0x20010000 | REGION_VALID | 0x0; 
MPU->RASR = NORMAL_OUTER_NON_CACHEABLE_NON_SHAREABLE | REGION_256K | P_RW_U_RO | REGION_ENABLED;

/* Enable MPU and the default memory map as a background region (acts as region number -1) for privileged access only (MPU_CTRL.PRIVDEFENA). */
MPU->CTRL = MPU_CTRL_ENABLE_Msk | MPU_CTRL_PRIVDEFENA_Msk ;

/* Make sure the configuration takes effect before continuing */
__DSB(); /* Ensure all settings are visible */
__ISB(); /* Flush pipeline and pre-fetch buffer */

------------------------->8-------------------------

The size of region 0 is 256KB but the desired base address, 0x20010000, is not a multiple of 256KB. The MPU_RASR.SIZE field has the value 17 (REGION_256K) so only MPU_RBAR[31:18] will be taken into consideration. This results in the base address being treated as 0x20000000, meaning the example actually selects the range 0x20000000-0x2003FFFF.

To achieve the desired 256KB memory range:

  1. Create an MPU region with a size of 512KB and a base address of 0x20000000.
  2. Disable sub-regions 0 and 5-7 by configuring the SRD field in the MPU Region Attribute and Size Register.

See CMSIS-compliant (pseudo) code below:

-------------------------8<-------------------------

/* Force any outstanding transfers to complete before disabling MPU */
__DMB();

/* Disable MPU */
MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;

/* Configure region 0 to start at address 0x20000000 and cover 512KB Flash (Normal, Not shareable, Non-cacheable, User Read-only)
   Disable sub-regions 0, 5, 6 and 7 to effectively create a region spanning 0x20010000-0x2004FFFF */

MPU->RBAR = 0x20000000  | REGION_VALID | 0x0; 
MPU->RASR = NORMAL_OUTER_NON_CACHEABLE_NON_SHAREABLE | REGION_512K | P_RW_U_RO | 
            SUB_REGION_0_DISABLED |   /* Disable 0x20000000-0x2000FFFF */
            SUB_REGION_5_DISABLED |   /* Disable 0x20050000-0x2005FFFF */
            SUB_REGION_6_DISABLED |   /* Disable 0x20060000-0x2006FFFF */
            SUB_REGION_7_DISABLED |   /* Disable 0x20070000-0x2007FFFF */
            REGION_ENABLED;


/* Enable MPU and the default memory map as a background region (acts as region number -1) for privileged access only (MPU_CTRL.PRIVDEFENA). */
MPU->CTRL = MPU_CTRL_ENABLE_Msk | MPU_CTRL_PRIVDEFENA_Msk ;

/* Make sure the configuration takes effect before any access  */
__DSB();                /* Ensure all settings are visible     */
__ISB();                /* Flush pipeline and pre-fetch buffer */

------------------------->8-------------------------

Related Information:

Attachments: mpu.h

Article last edited on: 2016-07-05 16:47:13

Rate this article

[Bad]
|
|
[Good]
Disagree? Move your mouse over the bar and click

Did you find this article helpful? Yes No

How can we improve this article?

Link to this article
Copyright © 2011 ARM Limited. All rights reserved. External (Open), Non-Confidential