AN4838 · Application noteIntroduction to memory protection unit management on STM32 MCUs
Download .pdfOpen in the full document

MPU setting example with STM32Cube HAL on Armv6 and Armv7 architectures

MPU setting example with STM32Cube HAL on Armv6 and Armv7 architectures

The table below describes an example of setting up the MPU with the following memory regions: Internal SRAM, flash memory and peripherals. The default memory map is used for privileged accesses as a background region, the MPU is not enabled for the HardFault handler and NMI.

Internal SRAM: 8 Kbytes of internal SRAM is configured as Region0.

Memory attributes: shareable and cacheable memory, write through with no write allocate, full access permission and code execution enabled.

Flash memory: the whole Flash memory is configured as Region.

Memory attributes: shareable and cacheable memory, write through with no write allocate, full access permission and code execution enabled.

Peripheral region: is configured as Region2.

Memory attributes: cached and shared device, full access permission and execute never.

Table 8. Example of setting up the MPU
ConfigurationMemory typeBase addressRegion numberMemory sizeMemory attributes
Internal SRAMNormal memory0x2000 0000Region08 KbytesShareable, write through, no write allocate

C = 1, B = 0, TEX = 0, S = 1

SRD = 0, XN = 0, AP = full access

Flash memoryNormal memory0x0800 0000Region11 MbyteNon-shareable write through, no write allocate

C = 1, B = 0, TEX = 0, S = 1

SRD = 0, XN = 0, AP = full access

FMCDevice memory0x4000 0000Region2512 MbytesShareable, write through, no write allocate

C = 1, B = 0, TEX = 0, S = 1

SRD = 0, XN = 1, AP = full access

Setting the MPU with STM32Cube HAL

void MPU_RegionConfig(void)
{
MPU_Region_InitTypeDef MPU_InitStruct;
/* Disable MPU */
HAL_MPU_Disable();
/* Configure RAM region as Region N°0, 8kB of size and R/W region */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x24000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_8KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Configure FLASH region as REGION N°1, 1MB of size and R/W region */
MPU_InitStruct.BaseAddress = 0x08000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_1MB;
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Configure FMC region as REGION N°2, 0.5GB of size, R/W region */
MPU_InitStruct.BaseAddress = 0x40000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_512MB;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enable MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

MPU setting example with STM32Cube HAL on Armv8-M architecture

The table below describes an example of setting up the MPU in Armv8-M architecture with the following memory regions: internal SRAM, internal flash memory and peripherals.

Internal SRAM

  • Region number 0 with a size of 256 KB
  • Memory attributes: normal, non-cacheable, full access permission, code execution enabled

Internal flash memory

  • Region number 1 with a size of 2 MB
  • Memory attributes: normal, write through and no write allocate, full access permission, code execution enabled

Peripherals

  • Region number 2 with a size of 512 MB
  • Memory attributes: device nGnRE, full access permission, code execution disabled
Table 9. Example of setting up the MPU with Armv8-M
ConfigurationMemory typeBase addressRegion numberMemory sizeMemory attributes
Internal SRAMNormal memory0x2000 0000Region0256 Kbytes

Memory attribute = normal, non-cacheable.

XN = 0

AP = full access

S = 0

Flash memoryNormal memory0x0800 0000Region12 Mbyte

Memory attribute = normal, write through and no write allocate.

XN = 0

AP = full access

S = 0

PeripheralsDevice 0x4000 0000Region2512 Mbytes

Memory attribute = device nGnRE

XN = 1

AP = full access

S = 0

Setting the MPU with STM32Cube HAL

void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct;
MPU_Attributes_InitTypeDef MPU_AttributesInit;

/* Disable MPU */
HAL_MPU_Disable();

/* Configure RAM region as Region Number 0, 256KB of size */
MPU_AttributesInit.Number = MPU_ATTRIBUTES_NUMBER0;
MPU_AttributesInit.Attributes = INNER_OUTER(MPU_NOT_CACHEABLE);
HAL_MPU_ConfigMemoryAttributes(&MPU_AttributesInit);

MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x20000000;
MPU_InitStruct.LimitAddress = 0x2003FFFF;
MPU_InitStruct.AccessPermission = MPU_REGION_ALL_RW;
MPU_InitStruct.AttributesIndex = MPU_ATTRIBUTES_NUMBER0;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);


/* Configure FLASH region as REGION Number 1, 2M of size */
MPU_AttributesInit.Number = MPU_ATTRIBUTES_NUMBER1;
MPU_AttributesInit.Attributes = INNER_OUTER(MPU_WRITE_THROUGH|MPU_R_ALLOCATE);
HAL_MPU_ConfigMemoryAttributes(&MPU_AttributesInit);

MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x08000000;
MPU_InitStruct.LimitAddress = 0x081FFFFF;
MPU_InitStruct.AccessPermission = MPU_REGION_ALL_RW;
MPU_InitStruct.AttributesIndex = MPU_ATTRIBUTES_NUMBER1;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);

/* Configure Peripheral region as REGION Number 2, 512MB of size, Execute Never region */
MPU_AttributesInit.Number = MPU_ATTRIBUTES_NUMBER2;
MPU_AttributesInit.Attributes = MPU_DEVICE_nGnRE;
HAL_MPU_ConfigMemoryAttributes(&MPU_AttributesInit);

MPU_InitStruct.BaseAddress = 0x40000000;
MPU_InitStruct.LimitAddress = 0x5FFFFFFF;
MPU_InitStruct.AccessPermission = MPU_REGION_ALL_RW;
MPU_InitStruct.AttributesIndex = MPU_ATTRIBUTES_NUMBER2;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;

/* Enable MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

Conclusion

Using the MPU in the STM32 microcontrollers makes them robust, reliable and in some cases more secure by preventing the application tasks from accessing or corrupting the stack and data memory used by the other tasks.

This application note describes the different memory attributes, the types, and the MPU registers. It provides also an example for setting up the MPU with the STM32Cube HAL to illustrate how to configure the MPU in the STM32 MCUs.

For more details about the MPU register, refer to the Cortex® core programming manuals.

Revision history

Table 10. Document revision history
DateRevisionChanges
24-Mar-20161Initial release.
04-May-20182

Added STM32H7 series in the whole document.

Updated Figure 1. Example of overlapping regions..

Added Section 1 General information

Added Section 3.4 Cortex-M7 constraint speculative prefetch.

17-Jul-20193Updated Introduction adding STM32G0 series, STM32G4 series, STM32L4+ series, STM32L5 series and STM32WB series.
10-Feb-20204
Added:
  • PM0214 in Section Introduction
  • Section 4 Memory types, registers and attributes of the CM33
  • Section 5 Comparison of MPU features between Cortex-M0+, Cortex-M3/M4, Cortex-M7, and Cortex-M33
Updated:
  • title of the document
  • Section Introduction
  • Section 2 Overview
  • Section 2.1 Memory model
20-Sep-20215Updated the Applicable products table.
07-Feb-20236Added the STM32C0 series and STM32H5 series in Table 1. Applicable products.

Updated the Section 6: MPU setting example with STM32Cube HAL on Armv6 and Armv7 architectures.

Updated the whole document with minor changes.

Updated the document title.

04-Mar-20247Added the STM32U0 series in Table 1. Applicable products.
04-Apr-20248Added:
  • STM32WB0 series in Table 1. Applicable products

    Section 3.2: MPU register description

15-Jan-20259Added STM32N6 series.
Updated:
  • Section 2.1: Memory model
  • Section 4.2: Attribute indirection
  • Section 4.3: MPU registers

Added Section 4.1.1: Cortex®-M55 access privilege level for device and normal memory.

25-Feb-202510

Added STM32U3 series.

Updated:

  • Section Introduction
  • Section 2: Overview
  • Section 4.3: MPU registers
  • Section 4: Cortex-M33/M55 memory types, registers and attributes
  • Section 5: MPU features comparison between Cortex® cores

Added Section 7: MPU setting example with STM32Cube HAL on Armv8-M architecture.

03-Dec-202511

Added STM32C5 series.

Updated Section 6: MPU setting example with STM32Cube HAL on Armv6 and Armv7 architectures.