2 \defgroup mpu_functions MPU Functions (ARMv7)
3 \brief Functions that relate to the Memory Protection Unit.
5 Devices based on Cortex-M processors M0+, M3, M4 and M7 optionally can contain a Memory Protection Unit.
6 If available the MPU can be used to prevent errornous memory accesses.
13 MPU_SetRegionEx(0UL, 0x08000000UL, MPU_RASR(0UL, MPU_AP_FULL, 0UL, 0UL, 1UL, 1UL, 0x00UL, MPU_REGION_SIZE_1MB));
17 // Do MPU protected stuff
28 typedef struct {} MPU_Type;
31 * \brief MPU Region Base Address Register Value
33 * This preprocessor function can be used to construct a valid \ref MPU_Type::RBAR "RBAR" value.
34 * The VALID bit is implicitly set to 1.
36 * \param Region The region to be configured, number 0 to 15.
37 * \param BaseAddress The base address for the region.
39 #define MPU_RBAR(Region, BaseAddress)
43 * \brief MPU Region Attribut and Size Register Value
45 * This preprocessor function can be used to construct a valid \ref MPU_Type::RASR "RASR" value.
46 * The ENABLE bit is implicitly set to 1.
48 * \param DisableExec Instruction access disable bit, 1= disable instruction fetches.
49 * \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. See \ref mpu_functions_access_permissions.
50 * \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral.
51 * \param IsShareable Region is shareable between multiple bus masters.
52 * \param IsCacheable Region is cacheable, i.e. its value may be kept in cache.
53 * \param IsBufferable Region is bufferable, i.e. using write-back caching. Cachable but non-bufferable regions use write-through policy.
54 * \param SubRegionDisable Sub-region disable field.
55 * \param Size Region size of the region be configured, for example 4K, 8K. See \ref mpu_functions_region_size.
57 #define MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size)
60 * \brief Struct for a single MPU Region
61 * \details An array of MPU Regions can be used to set up an MPU Table.
62 * Using a table of precompiled register values can be used at runtime to
63 * efficently update a bunch of regions at once using \ref MPU_Load.
67 * const MPU_Region_t mpuTable[3][4] = {
69 * { .RBAR = MPU_RBAR(0UL, 0x08000000UL), .RASR = MPU_RASR(0UL, MPU_AP_FULL, 0UL, 0UL, 1UL, 1UL, 0x00UL, MPU_REGION_SIZE_1MB) },
70 * { .RBAR = MPU_RBAR(1UL, 0x20000000UL), .RASR = MPU_RASR(1UL, MPU_AP_FULL, 0UL, 0UL, 1UL, 1UL, 0x00UL, MPU_REGION_SIZE_32KB) },
71 * { .RBAR = MPU_RBAR(2UL, 0x40020000UL), .RASR = MPU_RASR(1UL, MPU_AP_FULL, 2UL, 0UL, 0UL, 0UL, 0x00UL, MPU_REGION_SIZE_8KB) },
72 * { .RBAR = MPU_RBAR(3UL, 0x40022000UL), .RASR = MPU_RASR(1UL, MPU_AP_FULL, 2UL, 0UL, 0UL, 0UL, 0xC0UL, MPU_REGION_SIZE_4KB) }
75 * { .RBAR = MPU_RBAR(4UL, 0x08000000UL), .RASR = MPU_RASR(0UL, MPU_AP_FULL, 0UL, 0UL, 1UL, 1UL, 0x00UL, MPU_REGION_SIZE_1MB) },
76 * { .RBAR = MPU_RBAR(5UL, 0x20000000UL), .RASR = MPU_RASR(1UL, MPU_AP_FULL, 0UL, 0UL, 1UL, 1UL, 0x00UL, MPU_REGION_SIZE_32KB) },
77 * { .RBAR = MPU_RBAR(6UL, 0x40020000UL), .RASR = MPU_RASR(1UL, MPU_AP_FULL, 2UL, 0UL, 0UL, 0UL, 0x00UL, MPU_REGION_SIZE_8KB) },
78 * { .RBAR = MPU_RBAR(7UL, 0x40022000UL), .RASR = MPU_RASR(1UL, MPU_AP_FULL, 2UL, 0UL, 0UL, 0UL, 0xC0UL, MPU_REGION_SIZE_4KB) }
81 * { .RBAR = MPU_RBAR(4UL, 0x18000000UL), .RASR = MPU_RASR(0UL, MPU_AP_FULL, 0UL, 0UL, 1UL, 1UL, 0x00UL, MPU_REGION_SIZE_1MB) },
82 * { .RBAR = MPU_RBAR(5UL, 0x30000000UL), .RASR = MPU_RASR(1UL, MPU_AP_FULL, 0UL, 0UL, 1UL, 1UL, 0x00UL, MPU_REGION_SIZE_32KB) },
83 * { .RBAR = MPU_RBAR(6UL, 0x50020000UL), .RASR = MPU_RASR(1UL, MPU_AP_FULL, 2UL, 0UL, 0UL, 0UL, 0x00UL, MPU_REGION_SIZE_8KB) },
84 * { .RBAR = MPU_RBAR(7UL, 0x50022000UL), .RASR = MPU_RASR(1UL, MPU_AP_FULL, 2UL, 0UL, 0UL, 0UL, 0xC0UL, MPU_REGION_SIZE_4KB) }
88 * void UpdateMpu(uint32_t idx)
90 * Load_MPU(mpuTable[idx], 4u);
94 * \note As stream loading the MPU makes use of the REGION field in \ref MPU_Type::RBAR only up to 16 regions can be handled this way.
96 typedef struct _MPU_Region_t {
97 uint32_t RBAR; //!< The region base address register value (\ref MPU_Type::RBAR "RBAR")
98 uint32_t RASR; //!< The region attribute and size register value (\ref MPU_Type::RASR "RASR"), see \ref MPU_RASR.
102 * \param MPU_Control Default access permissions for unconfigured regions.
104 __STATIC_INLINE void MPU_Enable(uint32_t MPU_Control);
108 __STATIC_INLINE void MPU_Disable();
110 /** Clear and disable the given MPU region.
111 * \param rnr Region number to be cleared.
113 __STATIC_INLINE void MPU_ClrRegion(uint32_t rnr);
115 /** Configure an MPU region.
117 * The region number should be contained in the rbar value.
119 * \param rbar Value for \ref MPU_Type::RBAR "RBAR" register.
120 * \param rasr Value for \ref MPU_Type::RASR "RASR" register.
122 __STATIC_INLINE void MPU_SetRegion(uint32_t rbar, uint32_t rasr);
124 /** Configure the given MPU region.
125 * \param rnr Region number to be configured.
126 * \param rbar Value for \ref MPU_Type::RBAR "RBAR" register.
127 * \param rasr Value for \ref MPU_Type::RASR "RASR" register.
129 __STATIC_INLINE void MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr);
131 /** Load the given number of MPU regions from a table.
132 * \param table Pointer to the MPU configuration table.
133 * \param cnt Amount of regions to be configured.
135 __STATIC_INLINE void MPU_Load(MPU_Region_t const* table, uint32_t cnt);
141 \defgroup mpu_functions_region_size Defines MPU_REGION_SIZE_
142 \ingroup mpu_functions
143 \brief Defines for valid MPU region sizes.
147 /** \def MPU_REGION_SIZE_32B
148 * \brief Region size 32 Bytes.
150 #define MPU_REGION_SIZE_32B ((uint8_t)0x04U)
152 /** \def MPU_REGION_SIZE_64B
153 * \brief Region size 64 Bytes.
155 #define MPU_REGION_SIZE_64B ((uint8_t)0x05U)
157 /** \def MPU_REGION_SIZE_128B
158 * \brief Region size 128 Bytes.
160 #define MPU_REGION_SIZE_128B ((uint8_t)0x06U)
162 /** \def MPU_REGION_SIZE_256B
163 * \brief Region size 256 Bytes.
165 #define MPU_REGION_SIZE_256B ((uint8_t)0x07U)
167 /** \def MPU_REGION_SIZE_512B
168 * \brief Region size 512 Bytes.
170 #define MPU_REGION_SIZE_512B ((uint8_t)0x08U)
172 /** \def MPU_REGION_SIZE_1KB
173 * \brief Region size 1KB.
175 #define MPU_REGION_SIZE_1KB ((uint8_t)0x09U)
177 /** \def MPU_REGION_SIZE_2KB
178 * \brief Region size 2KB.
180 #define MPU_REGION_SIZE_2KB ((uint8_t)0x0AU)
182 /** \def MPU_REGION_SIZE_4KB
183 * \brief Region size 4KB.
185 #define MPU_REGION_SIZE_4KB ((uint8_t)0x0BU)
187 /** \def MPU_REGION_SIZE_8KB
188 * \brief Region size 8KB.
190 #define MPU_REGION_SIZE_8KB ((uint8_t)0x0CU)
192 /** \def MPU_REGION_SIZE_16KB
193 * \brief Region size 16KB.
195 #define MPU_REGION_SIZE_16KB ((uint8_t)0x0DU)
197 /** \def MPU_REGION_SIZE_32KB
198 * \brief Region size 32KB.
200 #define MPU_REGION_SIZE_32KB ((uint8_t)0x0EU)
202 /** \def MPU_REGION_SIZE_64KB
203 * \brief Region size 64KB.
205 #define MPU_REGION_SIZE_64KB ((uint8_t)0x0FU)
207 /** \def MPU_REGION_SIZE_128KB
208 * \brief Region size 128KB.
210 #define MPU_REGION_SIZE_128KB ((uint8_t)0x10U)
212 /** \def MPU_REGION_SIZE_256KB
213 * \brief Region size 256KB.
215 #define MPU_REGION_SIZE_256KB ((uint8_t)0x11U)
217 /** \def MPU_REGION_SIZE_512KB
218 * \brief Region size 512KB.
220 #define MPU_REGION_SIZE_512KB ((uint8_t)0x12U)
222 /** \def MPU_REGION_SIZE_1MB
223 * \brief Region size 1MB.
225 #define MPU_REGION_SIZE_1MB ((uint8_t)0x13U)
227 /** \def MPU_REGION_SIZE_2MB
228 * \brief Region size 2MB.
230 #define MPU_REGION_SIZE_2MB ((uint8_t)0x14U)
232 /** \def MPU_REGION_SIZE_4MB
233 * \brief Region size 4MB.
235 #define MPU_REGION_SIZE_4MB ((uint8_t)0x15U)
237 /** \def MPU_REGION_SIZE_8MB
238 * \brief Region size 8MB.
240 #define MPU_REGION_SIZE_8MB ((uint8_t)0x16U)
242 /** \def MPU_REGION_SIZE_16MB
243 * \brief Region size 16MB.
245 #define MPU_REGION_SIZE_16MB ((uint8_t)0x17U)
247 /** \def MPU_REGION_SIZE_32MB
248 * \brief Region size 32MB.
250 #define MPU_REGION_SIZE_32MB ((uint8_t)0x18U)
252 /** \def MPU_REGION_SIZE_64MB
253 * \brief Region size 64MB.
255 #define MPU_REGION_SIZE_64MB ((uint8_t)0x19U)
257 /** \def MPU_REGION_SIZE_128MB
258 * \brief Region size 128MB.
260 #define MPU_REGION_SIZE_128MB ((uint8_t)0x1AU)
262 /** \def MPU_REGION_SIZE_256MB
263 * \brief Region size 256MB
265 #define MPU_REGION_SIZE_256MB ((uint8_t)0x1BU)
267 /** \def MPU_REGION_SIZE_512MB
268 * \brief Region size 512MB.
270 #define MPU_REGION_SIZE_512MB ((uint8_t)0x1CU)
272 /** \def MPU_REGION_SIZE_1GB
273 * \brief Region size 1GB.
275 #define MPU_REGION_SIZE_1GB ((uint8_t)0x1DU)
277 /** \def MPU_REGION_SIZE_2GB
278 * \brief Region size 2GB.
280 #define MPU_REGION_SIZE_2GB ((uint8_t)0x1EU)
282 /** \def MPU_REGION_SIZE_4GB
283 * \brief Region size 4GB.
285 #define MPU_REGION_SIZE_4GB ((uint8_t)0x1FU)
290 \defgroup mpu_functions_access_permissions Defines MPU_AP_
291 \ingroup mpu_functions
292 \brief Defines for valid MPU region access permissions
297 * Access permissions: None.
298 * Any access generates a permission fault.
300 #define MPU_AP_NONE 0u
303 * Access permissions: Privileged Read/Write.
304 * Privileged access only. Any unprivileged access generates a permission fault.
306 #define MPU_AP_PRIV 1u
309 * Access permissions: Privileged Read/Write. Unprivileged Read-only.
310 * Any unprivileged write generates a permission fault.
312 #define MPU_AP_URO 2u
315 * Access permissions: Privileged Read/Write. Unprivileged Read/Write.
316 * Full access, permission faults are never generated.
318 #define MPU_AP_FULL 3u
321 * Access permissions: Privileged Read-only.
322 * Any unprivileged access or privileged write generates a permission fault.
324 #define MPU_AP_PRO 5u
327 * Access permissions: Privileged and Unprivileged Read-only.
328 * Any write generates a permission fault.
336 \var MPU_Region_t::RBAR
337 This value specifies the start address of the MPU protected memory region.
338 The address must be a multiple of the region size, i.e. size aligned.
340 See \ref MPU_Type::RBAR for details about field bit format.
342 \var MPU_Region_t::RASR
343 This value specifies the size of the MPU protected memory region.
345 Valid values are limited to sizes
346 - of at least 32 bytes, and
349 Use one of the \ref mpu_functions_region_size.
352 The MPU Type Register indicates how many regions the MPU support. Software can use it
353 to determine if the processor implements an MPU.
355 | Bits | Name | Function |
356 | :------ | :------------ | :------------------------------------------------------------ |
357 | [31:24] | - | Reserved. |
358 | [23:16] | IREGION | Instruction region. RAZ. ARMv7-M only supports a unified MPU. |
359 | [15:8] | DREGION | Number of regions supported by the MPU. If this field reads-as-zero the processor does not implement an MPU. |
360 | [7:1] | - | Reserved. |
361 | [0] | SEPARATE | Indicates support for separate instruction and data address maps. RAZ. ARMv7-M only supports a unified MPU. |
364 Enables the MPU, and when the MPU is enabled, controls whether the default memory map
365 is enabled as a background region for privileged accesses, and whether the MPU is enabled
366 for HardFaults, NMIs, and exception handlers when FAULTMASK is set to 1.
368 | Bits | Name | Function |
369 | :------ | :------------ | :------------------------------------------------------------ |
370 | [31:3] | - | Reserved. |
371 | [2] | PRIVDEFENA | 0 - Disables the default memory map. 1 - Enables the default memory map as a background region for privileged access. |
372 | [1] | HFNMIENA | 0 - Disables the MPU for exception handlers. 1 - Use the MPU for memory accesses by exception handlers. |
373 | [0] | ENABLE | 0 - The MPU is disabled. 1 - The MPU is enabled. |
376 Selects the region currently accessed by \ref MPU_Type::RBAR and \ref MPU_Type::RASR.
378 | Bits | Name | Function |
379 | :------ | :------------ | :------------------------------------------------------------ |
380 | [31:8] | - | Reserved. |
381 | [7:0] | REGION | Indicates the memory region accessed. |
384 Holds the base address of the region identified by MPU_RNR. On a write, can also be used
385 to update the base address of a specified region, in the range 0 to 15, updating MPU_RNR
386 with the new region number.
388 | Bits | Name | Function |
389 | :------ | :------------ | :------------------------------------------------------------ |
390 | [31:5] | ADDR | Base address of the region. |
391 | [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. |
392 | [3:0] | REGION | On writes, can specify the number of the region to update, see VALID field description. |
395 Defines the size and access behavior of the region identified by MPU_RNR, and enables
398 | Bits | Name | Function |
399 | :------ | :------------ | :------------------------------------------------------------ |
400 | [31:29] | - | Reserved. |
401 | [28] | XN | Execute Never. |
402 | [27] | - | Reserved. |
403 | [26:24] | AP | Access Permissions, see \ref mpu_functions_access_permissions. |
404 | [23:22] | - | Reserved. |
405 | [21:19] | TEX | Type Extension. |
406 | [18] | S | Shareable. |
407 | [17] | C | Cachable. |
408 | [16] | B | Bufferable. |
409 | [15:8] | SRD | Subregion Disable. For regions of 256 bytes or larger, each bit of this field controls whether ne of the eight equal subregions is enabled (0) or disabled (1).
410 | [7:6] | - | Reserved. |
411 | [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. |
412 | [0] | ENABLE | 0 - This region is disabled. 1 - This region is enabled. |
414 \var MPU_Type::RBAR_A1
415 Alias for \ref MPU_Type::RBAR.
417 \var MPU_Type::RASR_A1
418 Alias for \ref MPU_Type::RASR.
420 \var MPU_Type::RBAR_A2
421 Alias for \ref MPU_Type::RBAR.
423 \var MPU_Type::RASR_A2
424 Alias for \ref MPU_Type::RASR.
426 \var MPU_Type::RBAR_A3
427 Alias for \ref MPU_Type::RBAR.
429 \var MPU_Type::RASR_A3
430 Alias for \ref MPU_Type::RASR.