MSP432E4 DriverLib API Guide  1.11.00.03
Functions
Mpu_api

Functions

void MPUEnable (uint32_t ui32MPUConfig)
 
void MPUDisable (void)
 
uint32_t MPURegionCountGet (void)
 
void MPURegionEnable (uint32_t ui32Region)
 
void MPURegionDisable (uint32_t ui32Region)
 
void MPURegionSet (uint32_t ui32Region, uint32_t ui32Addr, uint32_t ui32Flags)
 
void MPURegionGet (uint32_t ui32Region, uint32_t *pui32Addr, uint32_t *pui32Flags)
 
void MPUIntRegister (void(*pfnHandler)(void))
 
void MPUIntUnregister (void)
 

Detailed Description

Introduction

The Memory Protection Unit (MPU) API provides functions to configure the MPU. The MPU is tightly coupled to the Cortex-M processor core and provides a means to establish access permissions on regions of memory.

Up to eight memory regions can be defined. Each region has a base address and a size. The size is specified as a power of 2 between 32 bytes and 4 GB, inclusive. The region's base address must be aligned to the size of the region. Each region also has access permissions. Code execution can be allowed or disallowed for a region. A region can be configured for read-only access, read/write access, or no access for both privileged and user modes. Access permissions can be used to create an environment where only kernel or system code can access certain hardware registers or sections of code.

The MPU creates 8 sub-regions within each region. Any sub-region or combination of sub-regions can be disabled, allowing creation of ``holes'' or complex overlaying regions with different permissions. The sub-regions can also be used to create an unaligned beginning or ending of a region by disabling one or more of the leading or trailing sub-regions.

Once the regions are defined and the MPU is enabled, any access violation of a region causes a memory management fault, and the fault handler is activated.

API Functions

The MPU APIs provide a means to enable and configure the MPU and memory protection regions.

Generally, the memory protection regions should be defined before enabling the MPU. The regions can be configured by calling MPURegionSet() once for each region to be configured.

A region that is defined by MPURegionSet() can be initially enabled or disabled. If the region is not initially enabled, it can be enabled later by calling MPURegionEnable(). An enabled region can be disabled by calling MPURegionDisable(). When a region is disabled, its configuration is preserved as long as it is not overwritten. In this case, it can be enabled again with MPURegionEnable() without the need to reconfigure the region.

Care must be taken when setting up a protection region using MPURegionSet(). The function writes to multiple registers and is not protected from interrupts. Therefore, it is possible that an interrupt which accesses a region may occur while that region is in the process of being changed. The safest way to protect against this is to make sure that a region is always disabled before making any changes. Otherwise, it is up to the caller to ensure that MPURegionSet() is always called from within code that cannot be interrupted, or from code that is not be affected if an interrupt occurs while the region attributes are being changed.

The attributes of a region that have already been programmed can be retrieved and saved using the MPURegionGet() function. This function is intended to save the attributes in a format that can be used later to reload the region using the MPURegionSet() function. Note that the enable state of the region is saved with the attributes and takes effect when the region is reloaded.

When one or more regions are defined, the MPU can be enabled by calling MPUEnable(). This function turns on the MPU and also defines the behavior in privileged mode and in the Hard Fault and NMI fault handlers. The MPU can be configured so that when in privileged mode and no regions are enabled, a default memory map is applied. If this feature is not enabled, then a memory management fault is generated if the MPU is enabled and no regions are configured and enabled. The MPU can also be set to use a default memory map when in the Hard Fault or NMI handlers, instead of using the configured regions. All of these features are selected when calling MPUEnable(). When the MPU is enabled, it can be disabled by calling MPUDisable().

Finally, if the application is using run-time interrupt registration (see IntRegister()), then the function MPUIntRegister() can be used to install the fault handler which is called whenever a memory protection violation occurs. This function also enables the fault handler. If compile-time interrupt registration is used, then the IntEnable() function with the parameter FAULT_MPU must be used to enable the memory management fault handler. When the memory management fault handler has been installed with MPUIntRegister(), it can be removed by calling MPUIntUnregister().

Programming Example

The following example sets up a basic set of protection regions to provide the following:

//
// Define a 28-KB region of flash from 0x00000000 to 0x00007000. The
// region is executable, and read-only for both privileged and user
// modes. To set up the region, a 32-KB region (#0) is defined
// starting at address 0, and then a 4 KB hole removed at the end by
// disabling the last sub-region. The region is initially enabled.
//
//
// Define a 32-KB region (#1) of RAM from 0x20000000 to 0x20008000. The
// region is not executable, and is read/write access for
// privileged and user modes.
//
MPURegionSet(1, 0x20000000,
//
// Define an additional 8-KB region (#2) in RAM from 0x20008000 to
// 0x2000A000 that is read/write accessible only from privileged
// mode. This region is initially disabled, to be enabled later.
//
MPURegionSet(2, 0x20008000,
//
// Define a region (#3) in peripheral space from 0x40000000 to 0x40100000
// (1 MB). This region is accessible only in privileged mode. There is
// an area from 0x40020000 to 0x40040000 that has no peripherals and is not
// accessible at all. This inaccessible region is created by disabling the
// second sub-region(1) and creating a hole. Further, there is an area
// from 0x40080000 to 0x400A0000 that should be accessible from user mode
// as well. This area is created by disabling the fifth sub-region (4),
// and overlaying an additional region (#4) in that space with the
// appropriate permissions.
//
MPURegionSet(3, 0x40000000,
MPURegionSet(4, 0x40080000,
//
// In this example, compile-time registration of interrupts is used, so the
// handler does not have to be registered. However, it must be enabled.
//
//
// When setting up the regions, region 2 was initially disabled for some
// reason. At some point it must be enabled.
//
//
// Now the MPU is enabled. It is configured so that a default
// map is available in privileged mode if no regions are defined. The MPU
// is not enabled for the hard fault and NMI handlers, meaning that a
// default is not used whenever these handlers are active, effectively
// giving the fault handlers access to all of memory without any
// protection.
//
//
// At this point, the MPU is configured and enabled and if any code causes
// an access violation, the memory management fault occurs.
//

The following example shows how to save and restore region configurations.

//
// The following arrays provide space for saving the address and
// attributes for 4 region configurations.
//
uint32_t ui32RegionAddr[4];
uint32_t ui32RegionAttr[4];
...
//
// At some point in the system code, we want to save the state of 4 regions
// (0-3).
//
for(ui8Idx = 0; ui8Idx < 4; ui8Idx++)
{
MPURegionGet(ui8Idx, &ui32RegionAddr[ui8Idx], &ui32RegionAttr[ui8Idx]);
}
...
//
// At some other point, the previously saved regions should be restored.
//
for(ui8Idx = 0; ui8Idx < 4; ui8Idx++)
{
MPURegionSet(ui8Idx, ui32RegionAddr[ui8Idx], ui32RegionAttr[ui8Idx]);
}

Function Documentation

§ MPUEnable()

void MPUEnable ( uint32_t  ui32MPUConfig)

Enables and configures the MPU for use.

Parameters
ui32MPUConfigis the logical OR of the possible configurations.

This function enables the Cortex-M memory protection unit. It also configures the default behavior when in privileged mode and while handling a hard fault or NMI. Prior to enabling the MPU, at least one region must be set by calling MPURegionSet() or else by enabling the default region for privileged mode by passing the MPU_CONFIG_PRIV_DEFAULT flag to MPUEnable(). Once the MPU is enabled, a memory management fault is generated for memory access violations.

The ui32MPUConfig parameter should be the logical OR of any of the following:

  • MPU_CONFIG_PRIV_DEFAULT enables the default memory map when in privileged mode and when no other regions are defined. If this option is not enabled, then there must be at least one valid region already defined when the MPU is enabled.
  • MPU_CONFIG_HARDFLT_NMI enables the MPU while in a hard fault or NMI exception handler. If this option is not enabled, then the MPU is disabled while in one of these exception handlers and the default memory map is applied.
  • MPU_CONFIG_NONE chooses none of the above options. In this case, no default memory map is provided in privileged mode, and the MPU is not enabled in the fault handlers.
Returns
None.

References ASSERT, HWREG, MPU_CONFIG_HARDFLT_NMI, MPU_CONFIG_PRIV_DEFAULT, NVIC_MPU_CTRL, and NVIC_MPU_CTRL_ENABLE.

§ MPUDisable()

void MPUDisable ( void  )

Disables the MPU for use.

This function disables the Cortex-M memory protection unit. When the MPU is disabled, the default memory map is used and memory management faults are not generated.

Returns
None.

References HWREG, NVIC_MPU_CTRL, and NVIC_MPU_CTRL_ENABLE.

§ MPURegionCountGet()

uint32_t MPURegionCountGet ( void  )

Gets the count of regions supported by the MPU.

This function is used to get the total number of regions that are supported by the MPU, including regions that are already programmed.

Returns
The number of memory protection regions that are available for programming using MPURegionSet().

References HWREG, NVIC_MPU_TYPE, NVIC_MPU_TYPE_DREGION_M, and NVIC_MPU_TYPE_DREGION_S.

§ MPURegionEnable()

void MPURegionEnable ( uint32_t  ui32Region)

Enables a specific region.

Parameters
ui32Regionis the region number to enable.

This function is used to enable a memory protection region. The region should already be configured with the MPURegionSet() function. Once enabled, the memory protection rules of the region are applied and access violations cause a memory management fault.

Returns
None.

References ASSERT, HWREG, NVIC_MPU_ATTR, NVIC_MPU_ATTR_ENABLE, and NVIC_MPU_NUMBER.

§ MPURegionDisable()

void MPURegionDisable ( uint32_t  ui32Region)

Disables a specific region.

Parameters
ui32Regionis the region number to disable.

This function is used to disable a previously enabled memory protection region. The region remains configured if it is not overwritten with another call to MPURegionSet(), and can be enabled again by calling MPURegionEnable().

Returns
None.

References ASSERT, HWREG, NVIC_MPU_ATTR, NVIC_MPU_ATTR_ENABLE, and NVIC_MPU_NUMBER.

§ MPURegionSet()

void MPURegionSet ( uint32_t  ui32Region,
uint32_t  ui32Addr,
uint32_t  ui32Flags 
)

Sets up the access rules for a specific region.

Parameters
ui32Regionis the region number to set up.
ui32Addris the base address of the region. It must be aligned according to the size of the region specified in ui32Flags.
ui32Flagsis a set of flags to define the attributes of the region.

This function sets up the protection rules for a region. The region has a base address and a set of attributes including the size. The base address parameter, ui32Addr, must be aligned according to the size, and the size must be a power of 2.

The ui32Flags parameter is the logical OR of all of the attributes of the region. It is a combination of choices for region size, execute permission, read/write permissions, disabled sub-regions, and a flag to determine if the region is enabled.

The size flag determines the size of a region and must be one of the following:

  • MPU_RGN_SIZE_32B
  • MPU_RGN_SIZE_64B
  • MPU_RGN_SIZE_128B
  • MPU_RGN_SIZE_256B
  • MPU_RGN_SIZE_512B
  • MPU_RGN_SIZE_1K
  • MPU_RGN_SIZE_2K
  • MPU_RGN_SIZE_4K
  • MPU_RGN_SIZE_8K
  • MPU_RGN_SIZE_16K
  • MPU_RGN_SIZE_32K
  • MPU_RGN_SIZE_64K
  • MPU_RGN_SIZE_128K
  • MPU_RGN_SIZE_256K
  • MPU_RGN_SIZE_512K
  • MPU_RGN_SIZE_1M
  • MPU_RGN_SIZE_2M
  • MPU_RGN_SIZE_4M
  • MPU_RGN_SIZE_8M
  • MPU_RGN_SIZE_16M
  • MPU_RGN_SIZE_32M
  • MPU_RGN_SIZE_64M
  • MPU_RGN_SIZE_128M
  • MPU_RGN_SIZE_256M
  • MPU_RGN_SIZE_512M
  • MPU_RGN_SIZE_1G
  • MPU_RGN_SIZE_2G
  • MPU_RGN_SIZE_4G

The execute permission flag must be one of the following:

  • MPU_RGN_PERM_EXEC enables the region for execution of code
  • MPU_RGN_PERM_NOEXEC disables the region for execution of code

The read/write access permissions are applied separately for the privileged and user modes. The read/write access flags must be one of the following:

  • MPU_RGN_PERM_PRV_NO_USR_NO - no access in privileged or user mode
  • MPU_RGN_PERM_PRV_RW_USR_NO - privileged read/write, user no access
  • MPU_RGN_PERM_PRV_RW_USR_RO - privileged read/write, user read-only
  • MPU_RGN_PERM_PRV_RW_USR_RW - privileged read/write, user read/write
  • MPU_RGN_PERM_PRV_RO_USR_NO - privileged read-only, user no access
  • MPU_RGN_PERM_PRV_RO_USR_RO - privileged read-only, user read-only

The region is automatically divided into 8 equally-sized sub-regions by the MPU. Sub-regions can only be used in regions of size 256 bytes or larger. Any of these 8 sub-regions can be disabled, allowing for creation of ``holes'' in a region which can be left open, or overlaid by another region with different attributes. Any of the 8 sub-regions can be disabled with a logical OR of any of the following flags:

  • MPU_SUB_RGN_DISABLE_0
  • MPU_SUB_RGN_DISABLE_1
  • MPU_SUB_RGN_DISABLE_2
  • MPU_SUB_RGN_DISABLE_3
  • MPU_SUB_RGN_DISABLE_4
  • MPU_SUB_RGN_DISABLE_5
  • MPU_SUB_RGN_DISABLE_6
  • MPU_SUB_RGN_DISABLE_7

Finally, the region can be initially enabled or disabled with one of the following flags:

  • MPU_RGN_ENABLE
  • MPU_RGN_DISABLE

As an example, to set a region with the following attributes: size of 32 KB, execution enabled, read-only for both privileged and user, one sub-region disabled, and initially enabled; the ui32Flags parameter would have the following value:

(MPU_RGN_SIZE_32K | MPU_RGN_PERM_EXEC | MPU_RGN_PERM_PRV_RO_USR_RO | MPU_SUB_RGN_DISABLE_2 | MPU_RGN_ENABLE)

Note
This function writes to multiple registers and is not protected from interrupts. It is possible that an interrupt which accesses a region may occur while that region is in the process of being changed. The safest way to handle this is to disable a region before changing it. Refer to the discussion of this in the API Detailed Description section.
Returns
None.

References ASSERT, HWREG, NVIC_MPU_ATTR, NVIC_MPU_ATTR_BUFFRABLE, NVIC_MPU_ATTR_CACHEABLE, NVIC_MPU_ATTR_SHAREABLE, NVIC_MPU_ATTR_SIZE_M, NVIC_MPU_ATTR_TEX_M, NVIC_MPU_BASE, and NVIC_MPU_BASE_VALID.

§ MPURegionGet()

void MPURegionGet ( uint32_t  ui32Region,
uint32_t *  pui32Addr,
uint32_t *  pui32Flags 
)

Gets the current settings for a specific region.

Parameters
ui32Regionis the region number to get.
pui32Addrpoints to storage for the base address of the region.
pui32Flagspoints to the attribute flags for the region.

This function retrieves the configuration of a specific region. The meanings and format of the parameters is the same as that of the MPURegionSet() function.

This function can be used to save the configuration of a region for later use with the MPURegionSet() function. The region's enable state is preserved in the attributes that are saved.

Returns
None.

References ASSERT, HWREG, NVIC_MPU_ATTR, NVIC_MPU_BASE, NVIC_MPU_BASE_ADDR_M, and NVIC_MPU_NUMBER.

§ MPUIntRegister()

void MPUIntRegister ( void(*)(void)  pfnHandler)

Registers an interrupt handler for the memory management fault.

Parameters
pfnHandleris a pointer to the function to be called when the memory management fault occurs.

This function sets and enables the handler to be called when the MPU generates a memory management fault due to a protection region access violation.

See also
IntRegister() for important information about registering interrupt handlers.
Returns
None.

References ASSERT, FAULT_MPU, IntEnable(), and IntRegister().

§ MPUIntUnregister()

void MPUIntUnregister ( void  )

Unregisters an interrupt handler for the memory management fault.

This function disables and clears the handler to be called when a memory management fault occurs.

See also
IntRegister() for important information about registering interrupt handlers.
Returns
None.

References FAULT_MPU, IntDisable(), and IntUnregister().

© Copyright 1995-2019, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale