MKMxxZxxACxx5 Bare Metal Software Drivers  R4.1.6
Reference Manual

The ARM Cortex M0+ core provides optional privilege levels for software execution:

An unprivileged software can use the SVC_Call macro to initiate a supervisor call to transfer control to a privileged software. In addition to execution levels the ARM Cortex M0+ implements two stacks, the main stack and the process stack, with independent copies of the stack pointer. This example shows typical use of the supervisor call to switch ARM Cortex M0+ execution from thread user (unprivileged) mode to the handler (privileged) mode. The device enters the thread (privileged) execution mode after POR with main stack selected. After supervisor callback function is initialized, using SVC_InstallCallback function, the software switches execution mode to the thread user (unprivileged) and to use process stack. Then the user_function() is called from within a loop. The user_function() toggles two LEDs by initiating a supervisor call. The LEDs are toggled by the svc_callback() function executed in the handler (privileged) mode. After callback function terminates the ARM Cortex M0+ enters thread user (unprivileged) mode and the execution of the user_function() resumes.

Source code:
/******************************************************************************
* (c) Copyright 2016, Freescale Semiconductor Inc.
* ALL RIGHTS RESERVED.
******************************************************************************
* svc_test.c
******************************************************************************/
#include "drivers.h"
/* LEDs definition */
#define LED1 PIN5 /* PTE5 */
#define LED2 PIN1 /* PTF1 */
/* define supervisor service commands */
#define SVC_TGL_LED1() SVC_Call(0x01)
#define SVC_TGL_LED2() SVC_Call(0x02)
/* supervisor service callback function definition; this function executes in */
/* handler (privileged) mode and it uses main stack. Note that modification */
/* of any special registers within this mode is allowed */
static void svc_callback (uint8 imm)
{
if (imm == 0x01) { GPIO_Tgl (FGPIOE, LED1); }
if (imm == 0x02) { GPIO_Tgl (FGPIOF, LED2); }
}
/* user function definition; this function executes in the thread/user mode */
/* where all attempts to modify any special register are ignored */
static void user_function (void)
{
arch_delay(100000);
SVC_TGL_LED1(); /* LED1 toggle */
arch_delay(100000);
SVC_TGL_LED2(); /* LED2 toggle */
}
/* device enters thread/privileged execution mode after POR; main stack is */
/* selected */
void main (void)
{
/* enable clocks to all on chip peripherals */
/* initialize LEDs */
/* initialize supervisor callback function */
SVC_InstallCallback (PRI_LVL1, svc_callback);
/* switch to process stack and enter thread/user execution mode; note that */
/* process stack as well as other memory sections shall be defined in linker*/
/* file and protected by MPU on the contrary to this simple implementation */
SetPSP (0x20000000); /* setup process stack pointer */
SelPSP (); /* select process stack */
EnableInterrupts(); /* enable interrupts */
UserMode(); /* switch into thread/user mode */
/* main software loop executes in thread user mode with using process stack */
while (1) { user_function(); }
}
Toolchain support:
IAR EWARM 7.40.7KEIL uVision 5.15CrossWorks 3.6ATOLLIC TrueStudio 5.3.0Kinetis Design Studio 3.0.0