Memory Protection Unit (MPU)
Introduction
The Memory Protection Unit (MPU) is a component provided by Arm Cortex-M series MCU and is used to provide hardware protection by software definition. The number of MPU entries varies for each CPU, as shown in the table below:
CPU |
MPU entry count |
---|---|
KM0 |
4 |
KM4 |
|
CPU |
MPU entry count |
---|---|
KR4 |
Not supported, config by PMP |
KM4 |
|
CPU |
MPU entry count |
---|---|
KR4 |
Not supported, config by PMP |
KM4 |
|
DSP |
Not supported, Configurable with arrays in sdk, up to 16 groups |
CPU |
MPU entry count |
---|---|
KM0 |
4 |
KM4 |
|
CA32 |
Not supported, config by MMU |
MPU APIs
The SDK provides the mpu_region_config struct to set the region memory attribute of MPU. The following table lists the member variables of the mpu_region_config struct.
Member variable name |
Type |
Description |
---|---|---|
region_base |
uint32_t |
MPU region base address, 32 bytes aligned |
region_size |
uint32_t |
MPU region size, 32 bytes aligned |
xn |
uint8_t |
Execute Never attribute
|
ap |
uint8_t |
Access permissions
|
sh |
uint8_t |
Shareability of Normal memory
|
attr_idx |
uint8_t |
Memory attribute indirect index This parameter can be a value of 0 ~ 7, with detailed attributes defined in mpu_init() and customizable. The typical definition is as follows:
|
mpu_init
void mpu_init(void)
Initialize MPU region memory attribute to typical value
Parameters: None
Return value: None
mpu_set_mem_attr
void mpu_set_mem_attr(uint8_t attr_idx, uint8_t mem_attr)
Change MPU region memory attribute
Parameters:
attr_idx
: Memory attribute indirect index, which can be 0 ~ 7.mem_attr
: region memory attributes, customizable as well.
Return value: None
mpu_region_cfg
void mpu_region_cfg(uint8_t region_num, mpu_region_config *pmpu_cfg)
Configure MPU region memory attributes based on the given parameters.
Parameters:
region_num
: MPU entry idxpmpu_cfg
: point to the mpu_region_config struct which has been configured
Return value: None
mpu_entry_free
void mpu_entry_free(u32 entry_index)
Release the software tag corresponding to the MPU entry, at which point the MPU entry will be marked as available.
Parameters:
entry_index
: MPU entry idx
Return value: None
mpu_entry_alloc
char mpu_entry_alloc(void)
Allocate a free MPU entry.
Parameters: None
Return value: MPU entry idx, Return -1 if allocation fails.
Usage
During system boot, in the app_start()
function of ameba_app_start.c
, the mpu_init()
function is called to initialize the MPU.
Once the MPU initialization is complete, the app_mpu_nocache_init()
function configures the non-cacheable data buffer based on the predefined non-cacheable data buffer .
Note
Neither the I-Cache nor the D-Cache will cache the addresses in the MCU’s internal ROM.
During execution, if the code or data is mistakenly accessed, and the MPU region’s read-only attribute is to be used to assist in analysis, the MPU region can be set up by following these steps:
Define new variable and struct
Define a variable
char mpu_entry;
to store MPU entry index;Define a struct
mpu_region_config mpu_cfg;
to store the region memory attribute
Call
mpu_entry = mpu_entry_alloc();
to allocate a free MPU entry, where -1 indicates allocation failure.Set the struct for region’s memory attribute
mpu_cfg.region_base = start_addr; // The starting address to protect, aligned to 32 bytes. mpu_cfg.region_size = size_bytes; // The size to protect, aligned to 32 bytes. mpu_cfg.xn = MPU_EXEC_ALLOW; mpu_cfg.ap = MPU_UN_PRIV_RO; // The read-only attribute can help prevent accidental access. mpu_cfg.sh = MPU_NON_SHAREABLE; mpu_cfg.attr_idx = MPU_MEM_ATTR_IDX_WT_T_RA;
Call
mpu_region_cfg(mpu_entry, &mpu_cfg);
to configure MPU region memory attribute.