2 \defgroup mpu_functions MPU Functions for Armv6-M/v7-M
3 \brief Functions that relate to the Memory Protection Unit.
5 The following functions support the optional Memory Protection Unit (MPU) that is available on the Cortex-M0+, M3, M4 and M7 processor.
7 The MPU is used to prevent from illegal memory accesses that are typically caused by errors in an application software.
14 ARM_MPU_SetRegionEx(0UL, 0x08000000UL, ARM_MPU_RASR(0UL, ARM_MPU_AP_FULL, 0UL, 0UL, 1UL, 1UL, 0x00UL, ARM_MPU_REGION_SIZE_1MB));
18 // Execute application code that is access protected by the MPU
29 typedef struct {} MPU_Type;
33 * \brief MPU Region Base Address Register Value
35 * This preprocessor function can be used to construct a valid \ref MPU_Type::RBAR "RBAR" value.
36 * The VALID bit is implicitly set to 1.
38 * \param Region The region to be configured, number 0 to 15.
39 * \param BaseAddress The base address for the region.
41 #define ARM_MPU_RBAR(Region, BaseAddress)
45 * \brief MPU Region Attribute and Size Register Value
47 * This macro is used to construct a valid \ref MPU_Type::RASR "RASR" value.
48 * The ENABLE bit of the RASR value is implicitly set to 1.
50 * \param DisableExec Instruction access disable bit. 1 = disable instruction fetches.
51 * \param AccessPermission Data access permission configures read/write access for User and Privileged mode. Possible values see \ref ARM_MPU_AP_xxx.
52 * \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral.
53 * \param IsShareable 1 = region is shareable between multiple bus masters.
54 * \param IsCacheable 1 = region is cacheable (values may be kept in cache).
55 * \param IsBufferable 1 = region is bufferable (when using write-back caching). Cacheable but non-bufferable regions use write-through policy.
56 * \param SubRegionDisable Sub-region disable field (8 bits).
57 * \param Size Region size with values defined under \ref ARM_MPU_REGION_SIZE_xxx.
59 #define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size)
63 * \def ARM_MPU_RASR_EX
64 * \brief MPU Region Attribute and Size Register Value
66 * This macro is used to construct a valid \ref MPU_Type::RASR "RASR" value.
67 * The ENABLE bit of the RASR value is implicitly set to 1.
69 * \param DisableExec Instruction access disable bit, 1= disable instruction fetches.
70 * \param AccessPermission Data access permission configures read/write access for User and Privileged mode. Possible values see \ref ARM_MPU_AP_xxx.
71 * \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_xxx.
72 * \param SubRegionDisable Sub-region disable field (8 bits).
73 * \param Size Region size with values defined under \ref ARM_MPU_REGION_SIZE_xxx.
75 #define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size)
78 * \brief Setup information of a single MPU Region
79 * \details The typedef \ref ARM_MPU_Region_t allows to define a MPU table (array of MPU regions) with pre-compiled register values.
80 * Such tables enable efficient MPU setup using the function \ref ARM_MPU_Load.
82 * <b>Example:</b> See \ref ARM_MPU_Load
85 uint32_t RBAR; //!< The region base address register value (\ref MPU_Type::RBAR "RBAR")
86 uint32_t RASR; //!< The region attribute and size register value (\ref MPU_Type::RASR "RASR"), see \ref ARM_MPU_RASR.
90 \brief Enable the memory protection unit (MPU) and
91 \param MPU_CTRL Additional control settings that configure MPU behaviour
93 The function \ref ARM_MPU_Enable writes to the register \ref MPU_Type::CTRL "MPU->CTRL" and sets bit ENABLE. The parameter \em MPU_CTRL provides additional bit values
94 (see table below) that configure the MPU behaviour. For processors that implement an <b>MPU Fault Handler</b> the \ref NVIC_gr "MemoryManagement_IRQn" exception is enabled by setting the bit MEMFAULTACT in register SBC->SHCSR.
96 The following table contains possible values for the parameter \em MPU_CTRL that set specific bits in register MPU->CTRL.
97 | Bit | MPU_CTRL value | When applied | When not applied
98 |:----|:-------------------------|:------------------------------------------------------------------------|:---------------------------------------
99 | 1 | MPU_CTRL_HFNMIENA_Msk | Enable MPU during hard fault, NMI, and FAULTMASK handlers execution | Disable MPU during hard fault, NMI, and FAULTMASK handler execution
100 | 2 | MPU_CTRL_PRIVDEFENA_Msk | Enable default memory map as a background region for privileged access | Use only MPU region settings
105 // enable MPU with all region definitions. Exceptions are not protected by MPU.
108 // enable MPU with all region definitions and background regions for privileged access. Exceptions are protected by MPU.
109 MPU_Enable (MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_HFNMIENA_Msk);
114 __STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_CTRL);
118 __STATIC_INLINE void ARM_MPU_Disable();
120 /** Clear and disable the given MPU region.
121 * \param rnr Region number to be cleared.
123 __STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr);
125 /** Configure an MPU region.
127 * The region number should be contained in the rbar value.
129 * \param rbar Value for \ref MPU_Type::RBAR "RBAR" register.
130 * \param rasr Value for \ref MPU_Type::RASR "RASR" register.
132 __STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr);
134 /** Configure the given MPU region.
135 * \param rnr Region number to be configured.
136 * \param rbar Value for \ref MPU_Type::RBAR "RBAR" register.
137 * \param rasr Value for \ref MPU_Type::RASR "RASR" register.
139 __STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr);
141 /** Memcpy with strictly ordered memory access, e.g. used by code in \ref ARM_MPU_Load.
142 * \param dst Destination data is copied to.
143 * \param src Source data is copied from.
144 * \param len Amount of data words to be copied.
146 __STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len);
148 /** Load the given number of MPU regions from a table.
149 * \param table Pointer to the MPU configuration table.
150 * \param cnt Number of regions to be configured.
152 * \note only up to 16 regions can be handled as the function \ref ARM_MPU_Load uses the REGION field in \ref MPU_Type::RBAR "MPU->RBAR".
156 * const ARM_MPU_Region_t mpuTable[3][4] = {
158 * { .RBAR = ARM_MPU_RBAR(0UL, 0x08000000UL), .RASR = ARM_MPU_RASR(0UL, ARM_MPU_AP_FULL, 0UL, 0UL, 1UL, 1UL, 0x00UL, ARM_MPU_REGION_SIZE_1MB) },
159 * { .RBAR = ARM_MPU_RBAR(1UL, 0x20000000UL), .RASR = ARM_MPU_RASR(1UL, ARM_MPU_AP_FULL, 0UL, 0UL, 1UL, 1UL, 0x00UL, ARM_MPU_REGION_SIZE_32KB) },
160 * { .RBAR = ARM_MPU_RBAR(2UL, 0x40020000UL), .RASR = ARM_MPU_RASR(1UL, ARM_MPU_AP_FULL, 2UL, 0UL, 0UL, 0UL, 0x00UL, ARM_MPU_REGION_SIZE_8KB) },
161 * { .RBAR = ARM_MPU_RBAR(3UL, 0x40022000UL), .RASR = ARM_MPU_RASR(1UL, ARM_MPU_AP_FULL, 2UL, 0UL, 0UL, 0UL, 0xC0UL, ARM_MPU_REGION_SIZE_4KB) }
164 * { .RBAR = ARM_MPU_RBAR(4UL, 0x08000000UL), .RASR = ARM_MPU_RASR(0UL, ARM_MPU_AP_FULL, 0UL, 0UL, 1UL, 1UL, 0x00UL, ARM_MPU_REGION_SIZE_1MB) },
165 * { .RBAR = ARM_MPU_RBAR(5UL, 0x20000000UL), .RASR = ARM_MPU_RASR(1UL, ARM_MPU_AP_FULL, 0UL, 0UL, 1UL, 1UL, 0x00UL, ARM_MPU_REGION_SIZE_32KB) },
166 * { .RBAR = ARM_MPU_RBAR(6UL, 0x40020000UL), .RASR = ARM_MPU_RASR(1UL, ARM_MPU_AP_FULL, 2UL, 0UL, 0UL, 0UL, 0x00UL, ARM_MPU_REGION_SIZE_8KB) },
167 * { .RBAR = ARM_MPU_RBAR(7UL, 0x40022000UL), .RASR = ARM_MPU_RASR(1UL, ARM_MPU_AP_FULL, 2UL, 0UL, 0UL, 0UL, 0xC0UL, ARM_MPU_REGION_SIZE_4KB) }
170 * { .RBAR = ARM_MPU_RBAR(4UL, 0x18000000UL), .RASR = ARM_MPU_RASR(0UL, ARM_MPU_AP_FULL, 0UL, 0UL, 1UL, 1UL, 0x00UL, ARM_MPU_REGION_SIZE_1MB) },
171 * { .RBAR = ARM_MPU_RBAR(5UL, 0x30000000UL), .RASR = ARM_MPU_RASR(1UL, ARM_MPU_AP_FULL, 0UL, 0UL, 1UL, 1UL, 0x00UL, ARM_MPU_REGION_SIZE_32KB) },
172 * { .RBAR = ARM_MPU_RBAR(6UL, 0x50020000UL), .RASR = ARM_MPU_RASR(1UL, ARM_MPU_AP_FULL, 2UL, 0UL, 0UL, 0UL, 0x00UL, ARM_MPU_REGION_SIZE_8KB) },
173 * { .RBAR = ARM_MPU_RBAR(7UL, 0x50022000UL), .RASR = ARM_MPU_RASR(1UL, ARM_MPU_AP_FULL, 2UL, 0UL, 0UL, 0UL, 0xC0UL, ARM_MPU_REGION_SIZE_4KB) }
177 * void UpdateMpu(uint32_t idx)
179 * ARM_MPU_Load(mpuTable[idx], 4);
184 __STATIC_INLINE void ARM_MPU_Load(MPU_Region_t const* table, uint32_t cnt);
190 \defgroup mpu_defines Define values
191 \ingroup mpu_functions
192 \brief Define values for MPU region setup.
194 The following define values are used with \ref ARM_MPU_RASR to setup the \ref MPU_Type::RASR "RASR" value field in the MPU region.
197 ARM_MPU_Region_t, ARM_MPU_SetRegion, ARM_MPU_SetRegionEx.
201 /** \def ARM_MPU_REGION_SIZE_xxx
202 \brief Size values of a MPU region (in RASR field)
204 The following define values are used to compose the size information for an MPU region:
206 |\#define | Value | Description |
207 |:-------------------------|:-----------------|:---------------------------------------------------------|
208 |ARM_MPU_REGION_SIZE_32B | 0x04U | Region size 32 Bytes
209 |ARM_MPU_REGION_SIZE_64B | 0x05U | Region size 64 Bytes
210 |ARM_MPU_REGION_SIZE_128B | 0x06U | Region size 128 Bytes
211 |ARM_MPU_REGION_SIZE_256B | 0x07U | Region size 256 Bytes
212 |ARM_MPU_REGION_SIZE_512B | 0x08U | Region size 512 Bytes
213 |ARM_MPU_REGION_SIZE_1KB | 0x09U | Region size 1 KByte
214 |ARM_MPU_REGION_SIZE_2KB | 0x0AU | Region size 2 KBytes
215 |ARM_MPU_REGION_SIZE_4KB | 0x0BU | Region size 4 KBytes
216 |ARM_MPU_REGION_SIZE_8KB | 0x0CU | Region size 8 KBytes
217 |ARM_MPU_REGION_SIZE_16KB | 0x0DU | Region size 16 KBytes
218 |ARM_MPU_REGION_SIZE_32KB | 0x0EU | Region size 32 KBytes
219 |ARM_MPU_REGION_SIZE_64KB | 0x0FU | Region size 64 KBytes
220 |ARM_MPU_REGION_SIZE_128KB | 0x10U | Region size 128 KBytes
221 |ARM_MPU_REGION_SIZE_256KB | 0x11U | Region size 256 KBytes
222 |ARM_MPU_REGION_SIZE_512KB | 0x12U | Region size 512 KBytes
223 |ARM_MPU_REGION_SIZE_1MB | 0x13U | Region size 1 MByte
224 |ARM_MPU_REGION_SIZE_2MB | 0x14U | Region size 2 MBytes
225 |ARM_MPU_REGION_SIZE_4MB | 0x15U | Region size 4 MBytes
226 |ARM_MPU_REGION_SIZE_8MB | 0x16U | Region size 8 MBytes
227 |ARM_MPU_REGION_SIZE_16MB | 0x17U | Region size 16 MBytes
228 |ARM_MPU_REGION_SIZE_32MB | 0x18U | Region size 32 MBytes
229 |ARM_MPU_REGION_SIZE_64MB | 0x19U | Region size 64 MBytes
230 |ARM_MPU_REGION_SIZE_128MB | 0x1AU | Region size 128 MBytes
231 |ARM_MPU_REGION_SIZE_256MB | 0x1BU | Region size 256 MBytes
232 |ARM_MPU_REGION_SIZE_512MB | 0x1CU | Region size 512 MBytes
233 |ARM_MPU_REGION_SIZE_1GB | 0x1DU | Region size 1 GByte
234 |ARM_MPU_REGION_SIZE_2GB | 0x1EU | Region size 2 GBytes
235 |ARM_MPU_REGION_SIZE_4GB | 0x1FU | Region size 4 GBytes
237 #define ARM_MPU_REGION_SIZE_xxx
239 /** \def ARM_MPU_AP_xxx
240 \brief Values for MPU region access permissions (in RASR field)
242 The following define values are used to compose the access permission for an MPU region:
243 |\#define | Value | Access permissions |
244 |:-------------------------|:-----------------|:---------------------------------------------------------|
245 |ARM_MPU_AP_NONE | 0x0U | None: any access generates a permission fault.
246 |ARM_MPU_AP_PRIV | 0x1U | Privileged Read/Write: privileged access only; any unprivileged access generates a permission fault.
247 |ARM_MPU_AP_URO | 0x2U | Privileged Read/Write; Unprivileged Read-only: any unprivileged write generates a permission fault.
248 |ARM_MPU_AP_FULL | 0x3U | Privileged Read/Write. Unprivileged Read/Write: full access, permission faults are never generated.
249 |ARM_MPU_AP_PRO | 0x5U | Privileged Read-only: any unprivileged access or privileged write generates a permission fault.
250 |ARM_MPU_AP_RO | 0x6U | Privileged and Unprivileged Read-only: any write generates a permission fault.
252 #define ARM_MPU_AP_xxx
254 /** \def ARM_MPU_ACCESS_xxx
255 \brief Values for MPU region access attributes (in RASR field)
257 The following define values are used to compose the access attributes for an MPU region:
258 |\#define | TEX | Shareable | Cacheable | Bufferable | Description |
259 |:-----------------------------|:-----|:----------|:----------|:-----------|:------------------------|
260 | ARM_MPU_ACCESS_ORDERED | 000b | 1 | 0 | 0 | Strongly ordered memory |
261 | ARM_MPU_ACCESS_DEVICE(S) | 0s0b | S | 0 | S | Memory mapped peripheral device, shared (S=1) or non-shared (S=0) |
262 | ARM_MPU_ACCESS_NORMAL(O,I,S) | 1BBb | S | A | A | Normal memory, with outer/inner cache policy (O/I=\ref ARM_MPU_CACHEP_xxx, shared (S=1) or non-share (S=0) |
264 #define ARM_MPU_ACCESS_xxx
266 /** \def ARM_MPU_CACHEP_xxx
267 \brief Cache policy values for MPU region access attributes (in RASR field)
269 The following define values are used to compose the cacheability flags within the
270 access attributes for an MPU region:
271 |\#define | Value | Cacheability policy |
272 |:-----------------------------|:------|:------------------------|
273 | ARM_MPU_CACHEP_NOCACHE | 00b | Non-cacheable |
274 | ARM_MPU_CACHEP_WB_WRA | 01b | Write-back, write and read allocate |
275 | ARM_MPU_CACHEP_WT_NWA | 10b | Write-through, no write allocate |
276 | ARM_MPU_CACHEP_WB_NWA | 11b | Write-back, no write allocate |
278 #define ARM_MPU_CACHEP_xxx
284 \var ARM_MPU_Region_t::RBAR
285 This value specifies the start address of the MPU protected memory region. The address must be a multiple of the region size (size aligned).
287 See \ref MPU_Type::RBAR for details about field bit format.
289 \var ARM_MPU_Region_t::RASR
290 This value specifies region attributes and size. Use the \ref ARM_MPU_RASR macro to compose this value.
293 The MPU Type Register indicates how many regions the MPU support. Software can use it
294 to determine if the processor implements an MPU.
296 | Bits | Name | Function |
297 | :------ | :------------ | :------------------------------------------------------------ |
298 | [31:24] | - | Reserved. |
299 | [23:16] | IREGION | Instruction region. RAZ. Armv7-M only supports a unified MPU. |
300 | [15:8] | DREGION | Number of regions supported by the MPU. If this field reads-as-zero the processor does not implement an MPU. |
301 | [7:1] | - | Reserved. |
302 | [0] | SEPARATE | Indicates support for separate instruction and data address maps. RAZ. Armv7-M only supports a unified MPU. |
305 Enables the MPU, and when the MPU is enabled, controls whether the default memory map
306 is enabled as a background region for privileged accesses, and whether the MPU is enabled
307 for HardFaults, NMIs, and exception handlers when FAULTMASK is set to 1.
309 | Bits | Name | Function |
310 | :------ | :------------ | :------------------------------------------------------------ |
311 | [31:3] | - | Reserved. |
312 | [2] | PRIVDEFENA | 0 - Disables the default memory map. 1 - Enables the default memory map as a background region for privileged access. |
313 | [1] | HFNMIENA | 0 - Disables the MPU for exception handlers. 1 - Use the MPU for memory accesses by exception handlers. |
314 | [0] | ENABLE | 0 - The MPU is disabled. 1 - The MPU is enabled. |
317 Selects the region currently accessed by \ref MPU_Type::RBAR and \ref MPU_Type::RASR.
319 | Bits | Name | Function |
320 | :------ | :------------ | :------------------------------------------------------------ |
321 | [31:8] | - | Reserved. |
322 | [7:0] | REGION | Indicates the memory region accessed. |
325 Holds the base address of the region identified by MPU_RNR. On a write, can also be used
326 to update the base address of a specified region, in the range 0 to 15, updating MPU_RNR
327 with the new region number.
329 | Bits | Name | Function |
330 | :------ | :------------ | :------------------------------------------------------------ |
331 | [31:5] | ADDR | Base address of the region. |
332 | [4] | VALID | 1 - Update \ref MPU_Type::RNR to the value obtained by zero extending the REGION value specified in this write, and apply the base address update to this region. |
333 | [3:0] | REGION | On writes, can specify the number of the region to update, see VALID field description. |
336 Defines the size and access behavior of the region identified by MPU_RNR, and enables
339 | Bits | Name | Function |
340 | :------ | :------------ | :------------------------------------------------------------ |
341 | [31:29] | - | Reserved. |
342 | [28] | XN | Execute Never. |
343 | [27] | - | Reserved. |
344 | [26:24] | AP | Access Permissions, see \ref ARM_MPU_AP_xxx. |
345 | [23:22] | - | Reserved. |
346 | [21:19] | TEX | Type Extension. |
347 | [18] | S | Shareable. |
348 | [17] | C | Cacheable. |
349 | [16] | B | Bufferable. |
350 | [15:8] | SRD | Subregion Disable. For regions of 256 bytes or larger, each bit of this field controls whether one of the eight equal subregions is enabled (0) or disabled (1).
351 | [7:6] | - | Reserved. |
352 | [5:1] | SIZE | Indicates the region size. The region size, in bytes, is 2(SIZE+1). SIZE field values less than 4 are reserved, because the smallest supported region size is 32 bytes. |
353 | [0] | ENABLE | 0 - This region is disabled. 1 - This region is enabled. |
355 \var MPU_Type::RBAR_A1
356 Alias for \ref MPU_Type::RBAR.
358 \var MPU_Type::RASR_A1
359 Alias for \ref MPU_Type::RASR.
361 \var MPU_Type::RBAR_A2
362 Alias for \ref MPU_Type::RBAR.
364 \var MPU_Type::RASR_A2
365 Alias for \ref MPU_Type::RASR.
367 \var MPU_Type::RBAR_A3
368 Alias for \ref MPU_Type::RBAR.
370 \var MPU_Type::RASR_A3
371 Alias for \ref MPU_Type::RASR.