/**
\defgroup mpu_functions MPU Functions for Armv7-M
\brief Functions that relate to the Memory Protection Unit.
\details
The following functions support the optional Memory Protection Unit (MPU) that is available on the Cortex-M0+, M3, M4 and M7 processor.
The MPU is used to prevent from illegal memory accesses that are typically caused by errors in an application software.
Example:
\code
void main()
{
// Set Region 0
ARM_MPU_SetRegionEx(0UL, 0x08000000UL, MPU_RASR(0UL, ARM_MPU_AP_FULL, 0UL, 0UL, 1UL, 1UL, 0x00UL, ARM_MPU_REGION_SIZE_1MB));
ARM_MPU_Enable(0);
// Execute application code that is access protected by the MPU
ARM_MPU_Disable();
}
\endcode
@{
*/
/**
*/
typedef struct {} MPU_Type;
/** \def ARM_MPU_RBAR
* \brief MPU Region Base Address Register Value
*
* This preprocessor function can be used to construct a valid \ref MPU_Type::RBAR "RBAR" value.
* The VALID bit is implicitly set to 1.
*
* \param Region The region to be configured, number 0 to 15.
* \param BaseAddress The base address for the region.
*/
#define ARM_MPU_RBAR(Region, BaseAddress)
/**
* \def ARM_MPU_RASR
* \brief MPU Region Attribute and Size Register Value
*
* This macro is used to construct a valid \ref MPU_Type::RASR "RASR" value.
* The ENABLE bit of the RASR value is implicitly set to 1.
*
* \param DisableExec Instruction access disable bit. 1 = disable instruction fetches.
* \param AccessPermission Data access permission configures read/write access for User and Privileged mode. Possible values see \ref ARM_MPU_AP_xxx.
* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral.
* \param IsShareable 1 = region is shareable between multiple bus masters.
* \param IsCacheable 1 = region is cacheable (values may be kept in cache).
* \param IsBufferable 1 = region is bufferable (when using write-back caching). Cacheable but non-bufferable regions use write-through policy.
* \param SubRegionDisable Sub-region disable field (8 bits).
* \param Size Region size with values defined under \ref ARM_MPU_REGION_SIZE_xxx.
*/
#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size)
/**
* \brief Setup information of a single MPU Region
* \details The typedef \ref ARM_MPU_Region_t allows to define a MPU table (array of MPU regions) with pre-compiled register values.
* Such tables enable efficient MPU setup using the function \ref ARM_MPU_Load.
*
* Example: See \ref ARM_MPU_Load
*/
typedef struct {
uint32_t RBAR; //!< The region base address register value (\ref MPU_Type::RBAR "RBAR")
uint32_t RASR; //!< The region attribute and size register value (\ref MPU_Type::RASR "RASR"), see \ref ARM_MPU_RASR.
} ARM_MPU_Region_t;
/**
\brief Enable the memory protection unit (MPU) and
\param MPU_CTRL Additional control settings that configure MPU behaviour
\details
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
(see table below) that configure the MPU behaviour. For processors that implement an MPU Fault Handler the \ref NVIC_gr "MemoryManagement_IRQn" exception is enabled by setting the bit MEMFAULTACT in register SBC->SHCSR.
The following table contains possible values for the parameter \em MPU_CTRL that set specific bits in register MPU->CTRL.
| Bit | MPU_CTRL value | When applied | When not applied
|:----|:-------------------------|:------------------------------------------------------------------------|:---------------------------------------
| 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
| 2 | MPU_CTRL_PRIVDEFENA_Pos | Enable default memory map as a background region for privileged access | Use only MPU region settings
Example:
\code
// enable MPU with all region definitions. Exceptions are not protected by MPU.
MPU_Enable (0);
// enable MPU with all region definitions and background regions for privileged access. Exceptions are protected by MPU.
MPU_Enable (MPU_CTRL_PRIVDEFENA_Pos | MPU_CTRL_HFNMIENA_Pos);
\endcode
*/
__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_CTRL);
/** Disable the MPU.
*/
__STATIC_INLINE void ARM_MPU_Disable();
/** Clear and disable the given MPU region.
* \param rnr Region number to be cleared.
*/
__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr);
/** Configure an MPU region.
*
* The region number should be contained in the rbar value.
*
* \param rbar Value for \ref MPU_Type::RBAR "RBAR" register.
* \param rasr Value for \ref MPU_Type::RASR "RASR" register.
*/
__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr);
/** Configure the given MPU region.
* \param rnr Region number to be configured.
* \param rbar Value for \ref MPU_Type::RBAR "RBAR" register.
* \param rasr Value for \ref MPU_Type::RASR "RASR" register.
*/
__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr);
/** Load the given number of MPU regions from a table.
* \param table Pointer to the MPU configuration table.
* \param cnt Number of regions to be configured.
*
* \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".
*
* Example:
* \code
* const ARM_MPU_Region_t mpuTable[3][4] = {
* {
* { .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) },
* { .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) },
* { .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) },
* { .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) }
* },
* {
* { .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) },
* { .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) },
* { .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) },
* { .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) }
* },
* {
* { .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) },
* { .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) },
* { .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) },
* { .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) }
* }
* };
*
* void UpdateMpu(uint32_t idx)
* {
* ARM_MPU_Load(mpuTable[idx], 4);
* }
* \endcode
*
*/
__STATIC_INLINE void ARM_MPU_Load(MPU_Region_t const* table, uint32_t cnt);
/**
@}
\defgroup mpu_defines Define values
\ingroup mpu_functions
\brief Define values for MPU region setup.
\details
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.
\see
ARM_MPU_Region_t, ARM_MPU_SetRegion, ARM_MPU_SetRegionEx.
@{
*/
/** \def ARM_MPU_REGION_SIZE_xxx
\brief Size values of a MPU region (in RASR field)
\details
The following define values are used to compose the size information for an MPU region:
|\#define | Value | Description |
|:-------------------------|:-----------------|:---------------------------------------------------------|
|ARM_MPU_REGION_SIZE_32B | 0x04U | Region size 32 Bytes
|ARM_MPU_REGION_SIZE_64B | 0x05U | Region size 64 Bytes
|ARM_MPU_REGION_SIZE_128B | 0x06U | Region size 128 Bytes
|ARM_MPU_REGION_SIZE_256B | 0x07U | Region size 256 Bytes
|ARM_MPU_REGION_SIZE_512B | 0x08U | Region size 512 Bytes
|ARM_MPU_REGION_SIZE_1KB | 0x09U | Region size 1 KByte
|ARM_MPU_REGION_SIZE_2KB | 0x0AU | Region size 2 KBytes
|ARM_MPU_REGION_SIZE_4KB | 0x0BU | Region size 4 KBytes
|ARM_MPU_REGION_SIZE_8KB | 0x0CU | Region size 8 KBytes
|ARM_MPU_REGION_SIZE_16KB | 0x0DU | Region size 16 KBytes
|ARM_MPU_REGION_SIZE_32KB | 0x0EU | Region size 32 KBytes
|ARM_MPU_REGION_SIZE_64KB | 0x0FU | Region size 64 KBytes
|ARM_MPU_REGION_SIZE_128KB | 0x10U | Region size 128 KBytes
|ARM_MPU_REGION_SIZE_256KB | 0x11U | Region size 256 KBytes
|ARM_MPU_REGION_SIZE_512KB | 0x12U | Region size 512 KBytes
|ARM_MPU_REGION_SIZE_1MB | 0x13U | Region size 1 MByte
|ARM_MPU_REGION_SIZE_2MB | 0x14U | Region size 2 MBytes
|ARM_MPU_REGION_SIZE_4MB | 0x15U | Region size 4 MBytes
|ARM_MPU_REGION_SIZE_8MB | 0x16U | Region size 8 MBytes
|ARM_MPU_REGION_SIZE_16MB | 0x17U | Region size 16 MBytes
|ARM_MPU_REGION_SIZE_32MB | 0x18U | Region size 32 MBytes
|ARM_MPU_REGION_SIZE_64MB | 0x19U | Region size 64 MBytes
|ARM_MPU_REGION_SIZE_128MB | 0x1AU | Region size 128 MBytes
|ARM_MPU_REGION_SIZE_256MB | 0x1BU | Region size 256 MBytes
|ARM_MPU_REGION_SIZE_512MB | 0x1CU | Region size 512 MBytes
|ARM_MPU_REGION_SIZE_1GB | 0x1DU | Region size 1 GByte
|ARM_MPU_REGION_SIZE_2GB | 0x1EU | Region size 2 GBytes
|ARM_MPU_REGION_SIZE_4GB | 0x1FU | Region size 4 GBytes
*/
#define ARM_MPU_REGION_SIZE_xxx
/** \def ARM_MPU_AP_xxx
\brief Values for MPU region access permissions (in RASR field)
\details
The following define values are used to compose the access permission for an MPU region:
|\#define | Value | Access permissions |
|:-------------------------|:-----------------|:---------------------------------------------------------|
|ARM_MPU_AP_NONE | 0x0U | None: any access generates a permission fault.
|ARM_MPU_AP_PRIV | 0x1U | Privileged Read/Write: privileged access only; any unprivileged access generates a permission fault.
|ARM_MPU_AP_URO | 0x2U | Privileged Read/Write; Unprivileged Read-only: any unprivileged write generates a permission fault.
|ARM_MPU_AP_FULL | 0x3U | Privileged Read/Write. Unprivileged Read/Write: full access, permission faults are never generated.
|ARM_MPU_AP_PRO | 0x5U | Privileged Read-only: any unprivileged access or privileged write generates a permission fault.
|ARM_MPU_AP_RO | 0x6U | Privileged and Unprivileged Read-only: any write generates a permission fault.
*/
#define ARM_MPU_AP_xxx
/** @} */
/**
\var ARM_MPU_Region_t::RBAR
This value specifies the start address of the MPU protected memory region. The address must be a multiple of the region size (size aligned).
See \ref MPU_Type::RBAR for details about field bit format.
\var ARM_MPU_Region_t::RASR
This value specifies region attributes and size. Use the \ref ARM_MPU_RASR macro to compose this value.
\var MPU_Type::TYPE
The MPU Type Register indicates how many regions the MPU support. Software can use it
to determine if the processor implements an MPU.
| Bits | Name | Function |
| :------ | :------------ | :------------------------------------------------------------ |
| [31:24] | - | Reserved. |
| [23:16] | IREGION | Instruction region. RAZ. Armv7-M only supports a unified MPU. |
| [15:8] | DREGION | Number of regions supported by the MPU. If this field reads-as-zero the processor does not implement an MPU. |
| [7:1] | - | Reserved. |
| [0] | SEPARATE | Indicates support for separate instruction and data address maps. RAZ. Armv7-M only supports a unified MPU. |
\var MPU_Type::CTRL
Enables the MPU, and when the MPU is enabled, controls whether the default memory map
is enabled as a background region for privileged accesses, and whether the MPU is enabled
for HardFaults, NMIs, and exception handlers when FAULTMASK is set to 1.
| Bits | Name | Function |
| :------ | :------------ | :------------------------------------------------------------ |
| [31:3] | - | Reserved. |
| [2] | PRIVDEFENA | 0 - Disables the default memory map. 1 - Enables the default memory map as a background region for privileged access. |
| [1] | HFNMIENA | 0 - Disables the MPU for exception handlers. 1 - Use the MPU for memory accesses by exception handlers. |
| [0] | ENABLE | 0 - The MPU is disabled. 1 - The MPU is enabled. |
\var MPU_Type::RNR
Selects the region currently accessed by \ref MPU_Type::RBAR and \ref MPU_Type::RASR.
| Bits | Name | Function |
| :------ | :------------ | :------------------------------------------------------------ |
| [31:8] | - | Reserved. |
| [7:0] | REGION | Indicates the memory region accessed. |
\var MPU_Type::RBAR
Holds the base address of the region identified by MPU_RNR. On a write, can also be used
to update the base address of a specified region, in the range 0 to 15, updating MPU_RNR
with the new region number.
| Bits | Name | Function |
| :------ | :------------ | :------------------------------------------------------------ |
| [31:5] | ADDR | Base address of the region. |
| [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. |
| [3:0] | REGION | On writes, can specify the number of the region to update, see VALID field description. |
\var MPU_Type::RASR
Defines the size and access behavior of the region identified by MPU_RNR, and enables
that region.
| Bits | Name | Function |
| :------ | :------------ | :------------------------------------------------------------ |
| [31:29] | - | Reserved. |
| [28] | XN | Execute Never. |
| [27] | - | Reserved. |
| [26:24] | AP | Access Permissions, see \ref ARM_MPU_AP_xxx. |
| [23:22] | - | Reserved. |
| [21:19] | TEX | Type Extension. |
| [18] | S | Shareable. |
| [17] | C | Cacheable. |
| [16] | B | Bufferable. |
| [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).
| [7:6] | - | Reserved. |
| [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. |
| [0] | ENABLE | 0 - This region is disabled. 1 - This region is enabled. |
\var MPU_Type::RBAR_A1
Alias for \ref MPU_Type::RBAR.
\var MPU_Type::RASR_A1
Alias for \ref MPU_Type::RASR.
\var MPU_Type::RBAR_A2
Alias for \ref MPU_Type::RBAR.
\var MPU_Type::RASR_A2
Alias for \ref MPU_Type::RASR.
\var MPU_Type::RBAR_A3
Alias for \ref MPU_Type::RBAR.
\var MPU_Type::RASR_A3
Alias for \ref MPU_Type::RASR.
*/