2 \defgroup mpu_functions MPU Functions for ARMv7-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, 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)
62 * \brief Setup information of a single MPU Region
63 * \details The typedef \ref ARM_MPU_Region_t allows to define a MPU table (array of MPU regions) with pre-compiled register values.
64 * Such tables enable efficient MPU setup using the function \ref ARM_MPU_Load.
66 * <b>Example:</b> See \ref ARM_MPU_Load
69 uint32_t RBAR; //!< The region base address register value (\ref MPU_Type::RBAR "RBAR")
70 uint32_t RASR; //!< The region attribute and size register value (\ref MPU_Type::RASR "RASR"), see \ref ARM_MPU_RASR.
74 \brief Enable the memory protection unit (MPU) and
75 \param MPU_CTRL Additional control settings that configure MPU behaviour
77 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
78 (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.
80 The following table contains possible values for the parameter \em MPU_CTRL that set specific bits in register MPU->CTRL.
81 | Bit | MPU_CTRL value | When applied | When not applied
82 |:----|:-------------------------|:------------------------------------------------------------------------|:---------------------------------------
83 | 1 | MPU_CTRL_HFNMIENA_Pos | Enable MPU during hard fault, NMI, and FAULTMASK handlers execution | Disable MPU during hard fault, NMI, and FAULTMASK handler execution
84 | 2 | MPU_CTRL_PRIVDEFENA_Pos | Enable default memory map as a background region for privileged access | Use only MPU region settings
89 // enable MPU with all region definitions. Exceptions are not protected by MPU.
92 // enable MPU with all region definitions and background regions for privileged access. Exceptions are protected by MPU.
93 MPU_Enable (MPU_CTRL_PRIVDEFENA_Pos | MPU_CTRL_HFNMIENA_Pos);
98 __STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_CTRL);
102 __STATIC_INLINE void ARM_MPU_Disable();
104 /** Clear and disable the given MPU region.
105 * \param rnr Region number to be cleared.
107 __STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr);
109 /** Configure an MPU region.
111 * The region number should be contained in the rbar value.
113 * \param rbar Value for \ref MPU_Type::RBAR "RBAR" register.
114 * \param rasr Value for \ref MPU_Type::RASR "RASR" register.
116 __STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr);
118 /** Configure the given MPU region.
119 * \param rnr Region number to be configured.
120 * \param rbar Value for \ref MPU_Type::RBAR "RBAR" register.
121 * \param rasr Value for \ref MPU_Type::RASR "RASR" register.
123 __STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr);
125 /** Load the given number of MPU regions from a table.
126 * \param table Pointer to the MPU configuration table.
127 * \param cnt Number of regions to be configured.
129 * \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".
133 * const ARM_MPU_Region_t mpuTable[3][4] = {
135 * { .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) },
136 * { .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) },
137 * { .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) },
138 * { .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) }
141 * { .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) },
142 * { .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) },
143 * { .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) },
144 * { .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) }
147 * { .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) },
148 * { .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) },
149 * { .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) },
150 * { .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) }
154 * void UpdateMpu(uint32_t idx)
156 * ARM_MPU_Load(mpuTable[idx], 4);
161 __STATIC_INLINE void ARM_MPU_Load(MPU_Region_t const* table, uint32_t cnt);
167 \defgroup mpu_defines Define values
168 \ingroup mpu_functions
169 \brief Define values for MPU region setup.
171 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.
174 ARM_MPU_Region_t, ARM_MPU_SetRegion, ARM_MPU_SetRegionEx.
178 /** \def ARM_MPU_REGION_SIZE_xxx
179 \brief Size values of a MPU region (in RASR field)
181 The following define values are used to compose the size information for an MPU region:
183 |\#define | Value | Description |
184 |:-------------------------|:-----------------|:---------------------------------------------------------|
185 |ARM_MPU_REGION_SIZE_32B | 0x04U | Region size 32 Bytes
186 |ARM_MPU_REGION_SIZE_64B | 0x05U | Region size 64 Bytes
187 |ARM_MPU_REGION_SIZE_128B | 0x06U | Region size 128 Bytes
188 |ARM_MPU_REGION_SIZE_256B | 0x07U | Region size 256 Bytes
189 |ARM_MPU_REGION_SIZE_512B | 0x08U | Region size 512 Bytes
190 |ARM_MPU_REGION_SIZE_1KB | 0x09U | Region size 1 KByte
191 |ARM_MPU_REGION_SIZE_2KB | 0x0AU | Region size 2 KBytes
192 |ARM_MPU_REGION_SIZE_4KB | 0x0BU | Region size 4 KBytes
193 |ARM_MPU_REGION_SIZE_8KB | 0x0CU | Region size 8 KBytes
194 |ARM_MPU_REGION_SIZE_16KB | 0x0DU | Region size 16 KBytes
195 |ARM_MPU_REGION_SIZE_32KB | 0x0EU | Region size 32 KBytes
196 |ARM_MPU_REGION_SIZE_64KB | 0x0FU | Region size 64 KBytes
197 |ARM_MPU_REGION_SIZE_128KB | 0x10U | Region size 128 KBytes
198 |ARM_MPU_REGION_SIZE_256KB | 0x11U | Region size 256 KBytes
199 |ARM_MPU_REGION_SIZE_512KB | 0x12U | Region size 512 KBytes
200 |ARM_MPU_REGION_SIZE_1MB | 0x13U | Region size 1 MByte
201 |ARM_MPU_REGION_SIZE_2MB | 0x14U | Region size 2 MBytes
202 |ARM_MPU_REGION_SIZE_4MB | 0x15U | Region size 4 MBytes
203 |ARM_MPU_REGION_SIZE_8MB | 0x16U | Region size 8 MBytes
204 |ARM_MPU_REGION_SIZE_16MB | 0x17U | Region size 16 MBytes
205 |ARM_MPU_REGION_SIZE_32MB | 0x18U | Region size 32 MBytes
206 |ARM_MPU_REGION_SIZE_64MB | 0x19U | Region size 64 MBytes
207 |ARM_MPU_REGION_SIZE_128MB | 0x1AU | Region size 128 MBytes
208 |ARM_MPU_REGION_SIZE_256MB | 0x1BU | Region size 256 MBytes
209 |ARM_MPU_REGION_SIZE_512MB | 0x1CU | Region size 512 MBytes
210 |ARM_MPU_REGION_SIZE_1GB | 0x1DU | Region size 1 GByte
211 |ARM_MPU_REGION_SIZE_2GB | 0x1EU | Region size 2 GBytes
212 |ARM_MPU_REGION_SIZE_4GB | 0x1FU | Region size 4 GBytes
214 #define ARM_MPU_REGION_SIZE_xxx
216 /** \def ARM_MPU_AP_xxx
217 \brief Values for MPU region access permissions (in RASR field)
219 The following define values are used to compose the access permission for an MPU region:
220 |\#define | Value | Access permissions |
221 |:-------------------------|:-----------------|:---------------------------------------------------------|
222 |ARM_MPU_AP_NONE | 0x0U | None: any access generates a permission fault.
223 |ARM_MPU_AP_PRIV | 0x1U | Privileged Read/Write: privileged access only; any unprivileged access generates a permission fault.
224 |ARM_MPU_AP_URO | 0x2U | Privileged Read/Write; Unprivileged Read-only: any unprivileged write generates a permission fault.
225 |ARM_MPU_AP_FULL | 0x3U | Privileged Read/Write. Unprivileged Read/Write: full access, permission faults are never generated.
226 |ARM_MPU_AP_PRO | 0x5U | Privileged Read-only: any unprivileged access or privileged write generates a permission fault.
227 |ARM_MPU_AP_RO | 0x6U | Privileged and Unprivileged Read-only: any write generates a permission fault.
229 #define ARM_MPU_AP_xxx
235 \var ARM_MPU_Region_t::RBAR
236 This value specifies the start address of the MPU protected memory region. The address must be a multiple of the region size (size aligned).
238 See \ref MPU_Type::RBAR for details about field bit format.
240 \var ARM_MPU_Region_t::RASR
241 This value specifies region attributes and size. Use the \ref ARM_MPU_RASR macro to compose this value.
244 The MPU Type Register indicates how many regions the MPU support. Software can use it
245 to determine if the processor implements an MPU.
247 | Bits | Name | Function |
248 | :------ | :------------ | :------------------------------------------------------------ |
249 | [31:24] | - | Reserved. |
250 | [23:16] | IREGION | Instruction region. RAZ. ARMv7-M only supports a unified MPU. |
251 | [15:8] | DREGION | Number of regions supported by the MPU. If this field reads-as-zero the processor does not implement an MPU. |
252 | [7:1] | - | Reserved. |
253 | [0] | SEPARATE | Indicates support for separate instruction and data address maps. RAZ. ARMv7-M only supports a unified MPU. |
256 Enables the MPU, and when the MPU is enabled, controls whether the default memory map
257 is enabled as a background region for privileged accesses, and whether the MPU is enabled
258 for HardFaults, NMIs, and exception handlers when FAULTMASK is set to 1.
260 | Bits | Name | Function |
261 | :------ | :------------ | :------------------------------------------------------------ |
262 | [31:3] | - | Reserved. |
263 | [2] | PRIVDEFENA | 0 - Disables the default memory map. 1 - Enables the default memory map as a background region for privileged access. |
264 | [1] | HFNMIENA | 0 - Disables the MPU for exception handlers. 1 - Use the MPU for memory accesses by exception handlers. |
265 | [0] | ENABLE | 0 - The MPU is disabled. 1 - The MPU is enabled. |
268 Selects the region currently accessed by \ref MPU_Type::RBAR and \ref MPU_Type::RASR.
270 | Bits | Name | Function |
271 | :------ | :------------ | :------------------------------------------------------------ |
272 | [31:8] | - | Reserved. |
273 | [7:0] | REGION | Indicates the memory region accessed. |
276 Holds the base address of the region identified by MPU_RNR. On a write, can also be used
277 to update the base address of a specified region, in the range 0 to 15, updating MPU_RNR
278 with the new region number.
280 | Bits | Name | Function |
281 | :------ | :------------ | :------------------------------------------------------------ |
282 | [31:5] | ADDR | Base address of the region. |
283 | [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. |
284 | [3:0] | REGION | On writes, can specify the number of the region to update, see VALID field description. |
287 Defines the size and access behavior of the region identified by MPU_RNR, and enables
290 | Bits | Name | Function |
291 | :------ | :------------ | :------------------------------------------------------------ |
292 | [31:29] | - | Reserved. |
293 | [28] | XN | Execute Never. |
294 | [27] | - | Reserved. |
295 | [26:24] | AP | Access Permissions, see \ref ARM_MPU_AP_xxx. |
296 | [23:22] | - | Reserved. |
297 | [21:19] | TEX | Type Extension. |
298 | [18] | S | Shareable. |
299 | [17] | C | Cacheable. |
300 | [16] | B | Bufferable. |
301 | [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).
302 | [7:6] | - | Reserved. |
303 | [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. |
304 | [0] | ENABLE | 0 - This region is disabled. 1 - This region is enabled. |
306 \var MPU_Type::RBAR_A1
307 Alias for \ref MPU_Type::RBAR.
309 \var MPU_Type::RASR_A1
310 Alias for \ref MPU_Type::RASR.
312 \var MPU_Type::RBAR_A2
313 Alias for \ref MPU_Type::RBAR.
315 \var MPU_Type::RASR_A2
316 Alias for \ref MPU_Type::RASR.
318 \var MPU_Type::RBAR_A3
319 Alias for \ref MPU_Type::RBAR.
321 \var MPU_Type::RASR_A3
322 Alias for \ref MPU_Type::RASR.