ARM cortex-M : protected memory system (MPU)

ARM : about MPU


- memory 屬性 先設定到 MAIR (memory attribute indication register)
  再將 index 值設定到各 MPU region

- 當非法 access 時, MPU 會發出 memory management fault

   memory management fault enable



CM7 MPU control register


[2]PRIVDEFENA
Enables privileged software access to the default memory map:
0
If the MPU is enabled, disables use of the default memory map. Any memory access to a location not covered by any enabled region causes a fault.
1
If the MPU is enabled, enables use of the default memory map as a background region for privileged software accesses.
When enabled, the background region acts as if it is region number -1. Any region that is defined and enabled has priority over this default map.
If the MPU is disabled, the processor ignores this bit.
[1]HFNMIENA
Enables the operation of MPU during hard fault, NMI, and FAULTMASK handlers.
When the MPU is enabled:
0
MPU is disabled during hard fault, NMI, and FAULTMASK handlers, regardless of the value of the ENABLE bit.
1
The MPU is enabled during hard fault, NMI, and FAULTMASK handlers.
When the MPU is disabled, if this bit is set to 1 the behavior is Unpredictable.
[0]ENABLE
Enables the MPU:
0
MPU disabled.
1
MPU enabled.


範例 可參考  CMSIS-Core

The following settings are used to initialize the MPU in CMSIS:
__DMB(); /* Force any outstanding transfers to complete before disabling MPU */

/* Disable MPU */
MPU->CTRL = 0;

/* Configure memory types */

/* MPU_MAIR0 index 0: Normal-Outer-Non-cacheable-Inner-Non-cacheable */
MPU->MAIR0 |= (NORMAL_O_NC | NORMAL_I_NC);

/* MPU_MAIR0 index 1: Device-nGnRnE */
MPU->MAIR0 |= (DEVICE_NG_NR_NE << MPU_MAIR0_Attr1_Pos);

/* Configure region 0: Normal, Non-Shareable, RO, Any Privilege Level)*/
/* Region start = 0x0 Region end = 0x007FFFFF */
MPU->RNR = 0;
MPU->RBAR = (0x00000000 & MPU_RBAR_ADDR_Msk) | NON_SHAREABLE | RO_P_U;
MPU->RLAR = (0x007FFFFF & MPU_RLAR_LIMIT_Msk) | ((0 << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | REGION_ENABLE;

/* Configure region 1: Device-nGnRnE, RW, Any Privilege Level, XN) */
/* Region start = 0x40010000 Region end = 0x40013FFF */
MPU->RNR = 1;
MPU->RBAR = (0x40010000 & MPU_RBAR_ADDR_Msk) | RW_P_U | EXEC_NEVER;
MPU->RLAR = (0x40013FFF & MPU_RLAR_LIMIT_Msk) | ((1 << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | REGION_ENABLE;

MPU->CTRL |= 1; /* Enable the MPU */

__DSB(); /* Force memory writes before continuing */
__ISB(); /* Flush and refill pipeline with updated permissions */

留言

熱門文章