Skip to main content
  • Products
  • Software evaluation
  • Downloads
  • Free utilities
  • Purchase
  • Silicon Vendors
  • Support
  • About us
  • Blog
  • Forum
  • Search
  • Jobs
  • Newsletter
  • Blog
  • Contact
  • Shop
  • embOS
  • Example application

    embOS MPU add-on

    Example application

    Suitable for any safety-critical application, the embOS MPU add-on is available for any MCU containing a hardware MPU or MMU.

    Contact us Downloads Documentation
    SEGGER embOS-MPU

    Example application

    The MPU add-on for embOS-Classic and embOS-Ultra offers simple and straightforward runtime configuration that is easy to integrate into both new and existing products. It provides an unlimited number of privileged and unprivileged tasks 100 % sandboxed.

    The following example details how easy it is to use this feature:

    #include "RTOS.h"
    #include "BSP.h"
    #include <stdio.h>
    
    /*********************************************************************
    *
    *       Static data
    *
    **********************************************************************
    */
    //
    // Linker symbols to get section addresses.
    // embOS-MPU needs to know where RAM, ROM and the OS section is located.
    //
    extern unsigned int __FLASH_segment_start__;
    extern unsigned int __FLASH_segment_size__;
    extern unsigned int __RAM_segment_start__;
    extern unsigned int __RAM_segment_size__;
    extern unsigned int __os_start__;
    extern unsigned int __os_size__;
    //
    // Control structures for tasks and event object
    //
    static OS_EVENT HW_Event;
    static OS_TASK TCBHP;
    static OS_TASK TCBLP;
    //
    // Stack for privileged task.
    // This stack has not to be aligned because it does not affect MPU settings
    //
    static OS_STACKPTR int StackHP[128];
    //
    // Stack for unprivileged task. This will be used for MPU settings and with Cortex-M it requires alignment.
    // In most cases, the same power of 2 will work for both size and alignment
    //
    static OS_STACKPTR int StackLP[128] __attribute__ ((aligned (512)));
    //
    // List of allowed OS objects for the LPTask
    //
    static const OS_MPU_OBJ _aObjList[] = { {(OS_U32)&HW_Event, OS_MPU_OBJTYPE_EVENT},
                                            {(OS_U32)NULL,      OS_MPU_OBJTYPE_INVALID}};  // Last entry
    
    /*********************************************************************
    *
    *       Local functions
    *
    **********************************************************************
    */
    
    /*********************************************************************
    *
    *       _HPTask()
    *
    *  Function description
    *    High priority task.
    *    Periodically resumes the low priority task via an event object
    */
    static void _HPTask(void) {
      while (1) {
        BSP_ToggleLED(1);
        OS_EVENT_Set(&HW_Event);  // Signal Event to wake LP task
        OS_Delay(200);
      }
    }
    
    /*********************************************************************
    *
    *       _Recursive()
    *
    *  Function description
    *    This function produces a stack overflow.
    *    embOS detects the illegal memory access and automatically suspends
    *    the task. Additionally the error callback function is called.
    */
    static void _Recursive(unsigned int i) {
      volatile int k;
      k = i + 1;
      _Recursive(k);
    }
    
    /*********************************************************************
    *
    *       _Unpriv()
    *
    *  Function description
    *    Routine for demonstrating an illegal memory access after
    *    toggling an LED for 4 seconds.
    */
    static void _Unpriv(void) {
      unsigned int i;
    
      for (i = 0u; i < 20u; i++) {
        OS_EVENT_Wait(&HW_Event);
        BSP_SetLED(0);
        OS_Delay(20);
        BSP_ClrLED(0);
      }
      //
      // Produce illegal memory access
      //
      _Recursive(1u);
    }
    
    /*********************************************************************
    *
    *       _LPTask()
    *
    *  Function description
    *    Low priority task.
    */
    static void _LPTask(void) {
      OS_MPU_SetAllowedObjects(&TCBLP, _aObjList);
      OS_MPU_SwitchToUnprivState();
      _Unpriv();
    }
    
    /*********************************************************************
    *
    *       _ErrorCallback()
    *
    *  Function description
    *    User callback function which is called when an unprivileged task
    *    does something disallowed, e.g. tries to write to memory which
    *    does not belong to the task
    */
    static void _ErrorCallback(OS_TASK* pTask, OS_MPU_ERRORCODE ErrorCode) {
      static const char* _sErrTxt[] = {  "OS_MPU_ERROR_INVALID_REGION", "OS_MPU_ERROR_INVALID_OBJECT",
                                         "OS_MPU_ERROR_INVALID_API", "OS_MPU_ERROR_HARDFAULT",
                                         "OS_MPU_ERROR_MEMFAULT", "OS_MPU_ERROR_BUSFAULT",
                                         "OS_MPU_ERROR_USAGEFAULT", "OS_MPU_ERROR_SVC"};
      printf("Task with ID 0x%x has been stopped due to error %s\n", (OS_U32)pTask, _sErrTxt[ErrorCode]);
    }
    
    /*********************************************************************
    *
    *       Global functions
    *
    **********************************************************************
    */
    
    /*********************************************************************
    *
    *       main()
    */
    int main(void) {
      OS_InitKern();                /* Initialize OS                 */
      OS_InitHW();                  /* Initialize Hardware for OS    */
      BSP_Init();                   /* Initialize LED ports          */
      //
      // Setup memory information, must be done before first task is created
      //
      OS_MPU_ConfigMem((OS_U32)&__FLASH_segment_start__, (OS_U32)&__FLASH_segment_size__,
                       (OS_U32)&__RAM_segment_start__,   (OS_U32)&__RAM_segment_size__,
                       (OS_U32)&__os_start__,            (OS_U32)&__os_size__);
      //
      // Setup optionally error callback function
      //
      OS_MPU_SetErrorCallback(&_ErrorCallback);
      //
      // Enable embOS-MPU support
      //
      OS_MPU_Enable();
      OS_CREATETASK(&TCBHP, "HP Task", _HPTask, 100, StackHP);
      OS_CREATETASK(&TCBLP, "LP Task", _LPTask,  50, StackLP);
      OS_EVENT_Create(&HW_Event);
      OS_Start();                   /* Start multitasking            */
      return 0;
    }

    Detailed description

    The example application simulates a stack overflow and shows how the issue is handled by the MPU add-on. Easy to use, embOS-MPU needs just three additional API calls:

    • OS_MPU_ConfigMem()tells the OS where RAM, ROM and the OS is located in the memory.
    • OS_MPU_SetErrorCallback() sets an optional callback function, which is called whenever the MPU add-on detects an issue.
    • OS_MPU_Enable() actually enables the memory protection unit.

    The example application creates two tasks:

    • The HPTaskruns completely in a privileged state.
    • TheLPTask also starts in a privileged state but switches to unprivileged state with OS_MPU_SwitchToUnprivState().

    The HPTask toggles a LED and sends events to the LPTask.

    /*********************************************************************
    *
    *       main()
    */
    int main(void) {
      OS_InitKern();                /* Initialize OS                 */
      OS_InitHW();                  /* Initialize Hardware for OS    */
      BSP_Init();                   /* Initialize LED ports          */
      //
      // Setup memory information, must be done before first task is created
      //
      OS_MPU_ConfigMem((OS_U32)&__FLASH_segment_start__, (OS_U32)&__FLASH_segment_size__,
                       (OS_U32)&__RAM_segment_start__,   (OS_U32)&__RAM_segment_size__,
                       (OS_U32)&__os_start__,            (OS_U32)&__os_size__);
      //
      // Setup optionally error callback function
      //
      OS_MPU_SetErrorCallback(&_ErrorCallback);
      //
      // Enable embOS-MPU support
      //
      OS_MPU_Enable();
      OS_CREATETASK(&TCBHP, "HP Task", _HPTask, 100, StackHP);
      OS_CREATETASK(&TCBLP, "LP Task", _LPTask, 50, StackLP);
      OS_EVENT_Create(&HW_Event);
      OS_Start();                   /* Start multitasking           */
      return 0;
    }

    The HPTask toggles a LED and sends events to the LPTask.

    /*********************************************************************
    *
    *       _HPTask()
    *
    *  Function description
    *    High priority task.
    *    Periodically resumes the low priority task via an event object
    */
    static void _HPTask(void) {
      while (1) {
        BSP_ToggleLED(1);
        OS_EVENT_Set(&HW_Event); // Signal Event to wake LP task
        OS_Delay(200);
      }
    }

    The LPTask adds permission to the event object before it switches to the unprivileged state with OS_MPU_SwitchToUnprivState().

    /*********************************************************************
    *
    *       _LPTask()
    *
    *  Function description
    *    Low priority task.
    */
    static void _LPTask(void) {
      OS_MPU_SetAllowedObjects(&TCBLP, _aObjList);
      OS_MPU_SwitchToUnprivState();
      _Unpriv();
    }
    

    The _Unpriv() function runs in unprivileged state and toggles another LED for four seconds before it calls the function _Recursive().

    /*********************************************************************
    *
    *       _Unpriv()
    *
    *  Function description
    *    Routine for demonstrating an illegal memory access after
    *    toggling an LED for 4 seconds.
    */
    static void _Unpriv(void) {
      unsigned int i;
    
      for (i = 0u; i < 20u; i++) {
        OS_EVENT_Wait(&HW_Event);
        BSP_SetLED(0);
        OS_Delay(20);
        BSP_ClrLED(0);
      }
      //
      // Produce illegal memory access
      //
      _Recursive(1u);
    }

    The function _Recursive() generates the actual stack overflow.

    /*********************************************************************
    *
    *       _Recursive()
    *
    *  Function description
    *    This function produces a stack overflow.
    *    embOS detects the illegal memory access and automatically suspends
    *    the task. Additionally the error callback function is called.
    */
    static void _Recursive(unsigned int i) {
      volatile int k;
      k = i + 1;
      _Recursive(k);
    }

    The MPU add-on will terminate the LPTask as soon as the task tries to write to memory outside its task stack. Additionally the error callback function is called. The error callback function prints a message with the task id and the error cause. The HPTask and the OS are not affected and still run.

    /*********************************************************************
    *
    *       _ErrorCallback()
    *
    *  Function description
    *    User callback function which is called when an unprivileged task
    *    does something disallowed, e.g. tries to write to memory which
    *    does not belong to the task
    */
    static void _ErrorCallback(OS_TASK* pTask, OS_MPU_ERRORCODE ErrorCode) {
      static const char* _sErrTxt[] = {  "OS_MPU_ERROR_INVALID_REGION", "OS_MPU_ERROR_INVALID_OBJECT",
                                         "OS_MPU_ERROR_INVALID_API", "OS_MPU_ERROR_HARDFAULT",
                                         "OS_MPU_ERROR_MEMFAULT", "OS_MPU_ERROR_BUSFAULT",
                                         "OS_MPU_ERROR_USAGEFAULT", "OS_MPU_ERROR_SVC"};
      printf("Task with ID 0x%x has been stopped due to error %s\n", (OS_U32)pTask, _sErrTxt[ErrorCode]);
    }
    
    • User manual
    • Online documentation
    • List of downloads
    • Release notes
    • Update notification
    • Pricing
    • Support
    • Silicon vendor resources

    Headquarters

    SEGGER Microcontroller GmbH

    Ecolab-Allee 5
    40789 Monheim am Rhein, Germany
    info@segger.com
    Tel.: +49-2173-99312-0
    Fax: +49-2173-99312-28

    Locations

    USA: SEGGER Microcontroller Systems LLC

    Boston area
    101 Suffolk Lane
    Gardner, MA 01440, USA
    us-east@segger.com
    Tel.: +1-978-874-0299
    Fax: +1-978-874-0599

    Silicon Valley
    Milpitas, CA 95035, USA
    us-west@segger.com
    Tel.: +1-408-767-4068

    China: SEGGER Microcontroller China Co., Ltd.

    Room 218, Block A, Dahongqiaoguoji
    No. 133 Xiulian Road
    Minhang District, Shanghai 201199, China
    china@segger.com
    Tel.: +86-133-619-907-60

    ISO 9001
    ISO 27001
    First-class embedded software tools since 1992
    Designed and made in Germany
    • Imprint
    • Disclaimer
    • Code of Conduct
    • Privacy Policy
    © 2026 SEGGER - All rights reserved.