MKM34Z256VLx7 Bare Metal Software Drivers  R4.1.6
Reference Manual
MPU Example

The Memory Protection Unit (MPU) module includes 8 program-visible 128-bit region descriptors. The module is programmable only in privileged mode. Each region supports read, write and execute protection attributes for CM0+ and DMA masters and privileged secure and user secure/non-secure modes. It detects access protection errors if a memory reference does not hit in any memory region, or if the reference is illegal in all hit memory regions. Accesses that are not allowed generate Hard Fault.

Up to three MPU region descriptors are configured in software example below. The first, RGD1 descriptor, is configured to allow RWX supervisor and user secure/non-secure accesses and protects flash memory section. The second, RGD2 descriptor, enables RW supervisor accesses and W user accesses to the spvr_data[100] memory array. Finally, RGD3 descriptor, enables both RW supervisor and user accesses to the user_data[100] memory array. It is shown that only access that is not allowed and terminates by Hard Fault is an attempt to read from the spvr_data[100] memory array in user mode. The Hard Fault occurs due to RGD2 region descriptor hit.

Source code:
/******************************************************************************
* (c) Copyright 2010-2015, Freescale Semiconductor Inc.
* ALL RIGHTS RESERVED.
******************************************************************************
* mpu_test.c
******************************************************************************/
#include "drivers.h"
/* Imported symbols from linker */
#if defined (__ICCARM__) || defined(__GNUC__)
extern char __ICFEDIT_region_ROM_start__[];
extern char __ICFEDIT_region_ROM_end__[];
extern char __ICFEDIT_region_RAM_start__[];
extern char __ICFEDIT_region_RAM_end__[];
extern char __ICFEDIT_region_USERRAM_start__[];
extern char __ICFEDIT_region_USERRAM_end__[];
#define ROM_START_ADDR __ICFEDIT_region_ROM_start__
#define ROM_END_ADDR __ICFEDIT_region_ROM_end__
#define RAM_START_ADDR __ICFEDIT_region_RAM_start__
#define RAM_END_ADDR __ICFEDIT_region_RAM_end__
#define USERRAM_START_ADDR __ICFEDIT_region_USERRAM_start__
#define USERRAM_END_ADDR __ICFEDIT_region_USERRAM_end__
#elif defined(__CC_ARM)
#define ROM_START_ADDR 0x00000000
#define ROM_END_ADDR 0x0003ffff
#define RAM_START_ADDR 0x1fffe000
#define RAM_END_ADDR 0x20004fff
#define USERRAM_START_ADDR 0x20005000
#define USERRAM_END_ADDR 0x20005fff
#endif
#if defined (__ICCARM__)
#pragma location = "USERDATA"
static volatile uint8 user_data[100]; // data with user and supervisor R/W access
#elif defined(__GNUC__) || defined(__CC_ARM)
static volatile uint8 __attribute__((section (".USERDATA"))) user_data[100];
#endif
static volatile uint8 spvr_data[100]; // data with supervisor R/W access
void main (void)
{
register uint8 tmp=1, i=0;
/* Set bus masters attribute to be controlled internally by the core */
TRUE);
/* Initialize RGD1 = Flash; RWX supervisor mode, RWX user mode */
MPU_SPVR_USER,/* DMA */
ROM_START_ADDR,
ROM_END_ADDR));
/* Initialize RGD2 = RAM; RW supervisor mode, W user mode */
MPU_SPVR_RW, /* DMA */
RAM_START_ADDR,
RAM_END_ADDR));
/* Initialize RGD3 = RAM RW supervisor mode, RW user mode */
MPU_SPVR_RW, /* DMA */
USERRAM_START_ADDR,
USERRAM_END_ADDR));
/* Invalidate overlapping RGD0 */
/* Test supervisor access */
SpvrMode(); /* device run in supervisor mode by default */
for (i=0; i<100; i++) { user_data[i] = tmp; } /* W - passes */
for (i=0; i<100; i++) { tmp = user_data[i]; } /* R - passes */
for (i=0; i<100; i++) { spvr_data[i] = tmp; } /* W - passes */
for (i=0; i<100; i++) { tmp = spvr_data[i]; } /* R - passes */
/* Test user access */
UserMode(); /* device transitioning to user mode */
for (i=0; i<100; i++) { user_data[i] = tmp; } /* W - passes */
for (i=0; i<100; i++) { tmp = user_data[i]; } /* R - passes */
for (i=0; i<100; i++) { spvr_data[i] = tmp; } /* W - passes */
for (i=0; i<100; i++) { tmp = spvr_data[i]; } /* R - RGD2 hit */
while(1);
}
Linker configuration file:
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x00000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x00000000;
define symbol __ICFEDIT_region_ROM_end__ = 0x0003ffff;
define symbol __ICFEDIT_region_RAM_start__ = 0x1fffe000;
define symbol __ICFEDIT_region_RAM_end__ = 0x20004fff;
define symbol __ICFEDIT_region_USERRAM_start__ = 0x20005000;
define symbol __ICFEDIT_region_USERRAM_end__ = 0x20005fff;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x200;
define symbol __ICFEDIT_size_heap__ = 0x200;
/**** End of ICF editor section. ###ICF###*/
define symbol __memcfg_start__ = 0x00000400;
define symbol __mtbram_start__ = 0x1fffe000;
/* Export of symbol */
export symbol __ICFEDIT_region_ROM_start__;
export symbol __ICFEDIT_region_ROM_end__;
export symbol __ICFEDIT_region_RAM_start__;
export symbol __ICFEDIT_region_RAM_end__;
export symbol __ICFEDIT_region_USERRAM_start__;
export symbol __ICFEDIT_region_USERRAM_end__;
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define region USERRAM_region = mem:[from __ICFEDIT_region_USERRAM_start__ to __ICFEDIT_region_USERRAM_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize manually { readwrite };
initialize manually { section .data};
initialize manually { section .textrw };
initialize manually { section USERDATA };
do not initialize { zeroinit };
define block CodeRelocate { section .textrw_init };
define block CodeRelocateRam { section .textrw };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place at address mem:__memcfg_start__ { readonly section .memcfg };
place at address mem:__mtbram_start__ { readwrite section .mtbram };
place in ROM_region { readonly , block CodeRelocate };
place in RAM_region { readwrite, block CodeRelocateRam, block HEAP, block CSTACK };
place in USERRAM_region { readwrite section USERDATA };
Toolchain support:
IAR EWARM 7.40.7KEIL uVision 5.15CrossWorks 3.6ATOLLIC TrueStudio 5.3.0Kinetis Design Studio 3.0.0