Error with mpu_wrappers_v2.c

Hello,
I am using MPU mode of FreeRTOS with mpu_wrappers_v2.c . I create an event group with xEventGroupCreateStatic and this function call MPU_xEventGroupCreateStatic which use MPU_GetFreeIndexInKernelObjectPool to determine the index at which it can place the object in the table xKernelObjectPool. But the table is always full even when I give a size of 100 and I don’t know why it is full and which function has fill it (the first action in the main is the creation of this event group). Can you help me please?

Note that the creation works when I use mpu_wrappers.c (the v1 version)
This is the code of the function:

/**
 * @brief Kernel object pool.
 */
    PRIVILEGED_DATA static KernelObject_t xKernelObjectPool[ configPROTECTED_KERNEL_OBJECT_POOL_SIZE ] = { 0 };
/*-----------------------------------------------------------*/

    static int32_t MPU_GetFreeIndexInKernelObjectPool( void ) /* PRIVILEGED_FUNCTION */
    {
        int32_t i, lFreeIndex = -1;

        /* This function is called only from resource create APIs
         * which are not supposed to be called from ISRs. Therefore,
         * we only need to suspend the scheduler and do not require
         * critical section. */
        vTaskSuspendAll();
        {
            for( i = 0; i < configPROTECTED_KERNEL_OBJECT_POOL_SIZE; i++ )
            {
                //uart_dma_write(uart_dma, "Test tableau ", sizeof(char)*14);
                if( xKernelObjectPool[ i ].xInternalObjectHandle == NULL )
                {
                    /* Mark this index as not free. */
                    xKernelObjectPool[ i ].xInternalObjectHandle = ( OpaqueObjectHandle_t ) ( ~0U );
                    lFreeIndex = i;
                    break;
                }
            }
        }
        ( void ) xTaskResumeAll();

        return lFreeIndex;
    }
/*-----------------------------------------------------------*/

This is where the object pool is created and should be initialized to zero. Can you check at the time of startup if the memory has been initialized to 0?

No it is not initialized to zero at the start and I don’t know why.

Can you share your complete project? I think the startup code is not initializing it correctly.

All the files of the project? Or just the main.c and the startup file?

Will be good if you can share all the files.

I am a new user of the forum so I can not attach files to my message. How can I share the project?

Can the problem come from the linker script? I am using atmel samg55j19 mcu and I have customized the linker script to use the MPU mode as following:

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
SEARCH_DIR(.)
SEARCH_DIR(common/linker_scripts/)

/* Memory Spaces Definitions */
MEMORY
{
  flash (rx)  : ORIGIN = 0x00400000, LENGTH = 256K - 2 /* -2 for CRC16 */
  /*rom (rx)  : ORIGIN = 0x00410000, LENGTH = 64K -- reserved for bootloader upgrade*/
  ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
}

/* Initial 64K Flash is used to store kernel functions and
 * initial 512 bytes of RAM is used to store kernel data. */
__privileged_functions_region_size__  = 64K;
__privileged_data_region_size__       = 32K;

__FLASH_segment_start__               = ORIGIN( flash );
__FLASH_segment_end__                 = __FLASH_segment_start__ + 256K;

__SRAM_segment_start__                = ORIGIN( ram );
__SRAM_segment_end__                  = __SRAM_segment_start__ + 64K - 4;

__privileged_functions_start__        = __FLASH_segment_start__;
__privileged_functions_end__          = __FLASH_segment_start__ + __privileged_functions_region_size__;

__privileged_data_start__             = __SRAM_segment_start__;
__privileged_data_end__               = __SRAM_segment_start__ + __privileged_data_region_size__;


/* The stack size used by the application. NOTE: you need to adjust according to your application. */
__stack_size__ = DEFINED(__stack_size__) ? __stack_size__ : 0x4000; /* 16ko*/
__ram_end__ = ORIGIN(ram) + LENGTH(ram) - 4;

/* Section Definitions */
SECTIONS
{
    /* The startup code and FreeRTOS kernel code are placed into privileged
     * flash. */
    .privileged_functions :
    {
        . = ALIGN(4);
        _sfixed = .;
        KEEP(*(.vectors .vectors.*))
        KEEP(*(.fw_infos_section))
        . = ALIGN(4);
        *(privileged_functions)
        . = ALIGN(4);
        /* FILL(0xDEAD); Petit doute ici*/
        /* Ensure that un-privileged code is placed after the region reserved
         * for privileged kernel code. */
        /* Note that dot (.) actually refers to the byte offset from the start
         * of the current section (.privileged_functions in this case). As a
         * result, setting dot (.) to a value sets the size of the section. */
        . = __privileged_functions_region_size__;
    } >flash

    .text :
    {
        . = ALIGN(4);
        __syscalls_flash_start__ = .;
        *(freertos_system_calls)
        __syscalls_flash_end__ = .;
        . = ALIGN(4);
        *(.text .text.* .gnu.linkonce.t.*)
        *(.glue_7t) *(.glue_7)
        *(.rodata .rodata* .gnu.linkonce.r.*)
        *(.ARM.extab* .gnu.linkonce.armextab.*)

        KEEP(*(.fill_release_revM))

        /* Support C constructors, and C destructors in both user code
           and the C library. This also provides support for C++ code. */
        . = ALIGN(4);
        KEEP(*(.init))
        . = ALIGN(4);
        __preinit_array_start = .;
        KEEP (*(.preinit_array))
        __preinit_array_end = .;

        . = ALIGN(4);
        __init_array_start = .;
        KEEP (*(SORT(.init_array.*)))
        KEEP (*(.init_array))
        __init_array_end = .;

        . = ALIGN(0x4);
        KEEP (*crtbegin.o(.ctors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
        KEEP (*(SORT(.ctors.*)))
        KEEP (*crtend.o(.ctors))

        . = ALIGN(4);
        KEEP(*(.fini))

        . = ALIGN(4);
        __fini_array_start = .;
        KEEP (*(.fini_array))
        KEEP (*(SORT(.fini_array.*)))
        __fini_array_end = .;

        KEEP (*crtbegin.o(.dtors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
        KEEP (*(SORT(.dtors.*)))
        KEEP (*crtend.o(.dtors))

        . = ALIGN(4);
        _efixed = .;            /* End of text section */
    } > flash

    /* .ARM.exidx is sorted, so has to go in its own output section.  */
    PROVIDE_HIDDEN (__exidx_start = .);
    .ARM.exidx :
    {
      *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > flash
    PROVIDE_HIDDEN (__exidx_end = .);

    . = ALIGN(4);
    _etext = .;

    .relocate : 
    {
        . = ALIGN(4);
        _srelocate = .;
        *(.ramfunc .ramfunc.*);
        *(.data .data.*);
        . = ALIGN(4);
        _erelocate = .;
    } > ram AT> flash
	_edata = LOADADDR(.relocate) + SIZEOF(.relocate);

    /* Used by the startup to initialize data. */
    _sidata = LOADADDR(.privileged_data);

    /* FreeRTOS kernel data. */
    .privileged_data :
    {
        . = ALIGN(4);
        _sdata = .;        /* Create a global symbol at data start. */
        *(privileged_data)
        . = ALIGN(4);
        /* FILL(0xDEAD); */
        /* Ensure that un-privileged data is placed after the region reserved
         * for privileged kernel data. */
        /* Note that dot (.) actually refers to the byte offset from the start
         * of the current section (.privileged_data in this case). As a result,
         * setting dot (.) to a value sets the size of the section. */
        . = __privileged_data_region_size__;
    } >ram AT> flash


    /* .bss section which is used for uninitialized data */
    .bss (NOLOAD) :
    {
        . = ALIGN(4);
        _sbss = . ;
        _szero = .;
        *(.bss .bss.*)
        *(COMMON)
        . = ALIGN(4);
        _ebss = . ;
        _ezero = .;
    } > ram

    /* stack section */
    .stack (NOLOAD):
    {
        . = ALIGN(8);
        _sstack = .;
        . = . + __stack_size__;
        . = ALIGN(8);
        _estack = .;
    } > ram

    . = ALIGN(4);
    _end = . ;
}

Is it okay?

Try the following:

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
SEARCH_DIR(.)
SEARCH_DIR(common/linker_scripts/)

/* Memory Spaces Definitions */
MEMORY
{
  flash (rx)  : ORIGIN = 0x00400000, LENGTH = 256K - 2 /* -2 for CRC16 */
  /*rom (rx)  : ORIGIN = 0x00410000, LENGTH = 64K -- reserved for bootloader upgrade*/
  ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
}

/* Initial 64K Flash is used to store kernel functions and
 * initial 512 bytes of RAM is used to store kernel data. */
__privileged_functions_region_size__  = 64K;
__privileged_data_region_size__       = 32K;

__FLASH_segment_start__               = ORIGIN( flash );
__FLASH_segment_end__                 = __FLASH_segment_start__ + 256K;

__SRAM_segment_start__                = ORIGIN( ram );
__SRAM_segment_end__                  = __SRAM_segment_start__ + 64K - 4;

__privileged_functions_start__        = __FLASH_segment_start__;
__privileged_functions_end__          = __FLASH_segment_start__ + __privileged_functions_region_size__;

__privileged_data_start__             = __SRAM_segment_start__;
__privileged_data_end__               = __SRAM_segment_start__ + __privileged_data_region_size__;


/* The stack size used by the application. NOTE: you need to adjust according to your application. */
__stack_size__ = DEFINED(__stack_size__) ? __stack_size__ : 0x4000; /* 16ko*/
__ram_end__ = ORIGIN(ram) + LENGTH(ram) - 4;

/* Section Definitions */
SECTIONS
{
    /* The startup code and FreeRTOS kernel code are placed into privileged
     * flash. */
    .privileged_functions :
    {
        . = ALIGN(4);
        _sfixed = .;
        KEEP(*(.vectors .vectors.*))
        KEEP(*(.fw_infos_section))
        . = ALIGN(4);
        *(privileged_functions)
        . = ALIGN(4);
        /* FILL(0xDEAD); Petit doute ici*/
        /* Ensure that un-privileged code is placed after the region reserved
         * for privileged kernel code. */
        /* Note that dot (.) actually refers to the byte offset from the start
         * of the current section (.privileged_functions in this case). As a
         * result, setting dot (.) to a value sets the size of the section. */
        . = __privileged_functions_region_size__;
    } >flash

    .text :
    {
        . = ALIGN(4);
        __syscalls_flash_start__ = .;
        *(freertos_system_calls)
        __syscalls_flash_end__ = .;
        . = ALIGN(4);
        *(.text .text.* .gnu.linkonce.t.*)
        *(.glue_7t) *(.glue_7)
        *(.rodata .rodata* .gnu.linkonce.r.*)
        *(.ARM.extab* .gnu.linkonce.armextab.*)

        KEEP(*(.fill_release_revM))

        /* Support C constructors, and C destructors in both user code
           and the C library. This also provides support for C++ code. */
        . = ALIGN(4);
        KEEP(*(.init))
        . = ALIGN(4);
        __preinit_array_start = .;
        KEEP (*(.preinit_array))
        __preinit_array_end = .;

        . = ALIGN(4);
        __init_array_start = .;
        KEEP (*(SORT(.init_array.*)))
        KEEP (*(.init_array))
        __init_array_end = .;

        . = ALIGN(0x4);
        KEEP (*crtbegin.o(.ctors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
        KEEP (*(SORT(.ctors.*)))
        KEEP (*crtend.o(.ctors))

        . = ALIGN(4);
        KEEP(*(.fini))

        . = ALIGN(4);
        __fini_array_start = .;
        KEEP (*(.fini_array))
        KEEP (*(SORT(.fini_array.*)))
        __fini_array_end = .;

        KEEP (*crtbegin.o(.dtors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
        KEEP (*(SORT(.dtors.*)))
        KEEP (*crtend.o(.dtors))

        . = ALIGN(4);
        _efixed = .;            /* End of text section */
    } > flash

    /* .ARM.exidx is sorted, so has to go in its own output section.  */
    PROVIDE_HIDDEN (__exidx_start = .);
    .ARM.exidx :
    {
      *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > flash
    PROVIDE_HIDDEN (__exidx_end = .);

    . = ALIGN(4);
    _etext = .;

    .relocate : 
    {
        . = ALIGN(4);
        _srelocate = .;
        *(.ramfunc .ramfunc.*);
        *(.data .data.*);
        . = ALIGN(4);
        _erelocate = .;
    } > ram AT> flash


    /* FreeRTOS kernel data. */
    .privileged_data :
    {
        . = ALIGN(4);
        _sdata = .;        /* Create a global symbol at data start. */
        *(privileged_data)
        . = ALIGN(4);
        /* FILL(0xDEAD); */
        /* Ensure that un-privileged data is placed after the region reserved
         * for privileged kernel data. */
        /* Note that dot (.) actually refers to the byte offset from the start
         * of the current section (.privileged_data in this case). As a result,
         * setting dot (.) to a value sets the size of the section. */
        . = __privileged_data_region_size__;
    } >ram AT> flash


    _edata = LOADADDR(.privileged_data) + SIZEOF(.privileged_data);

    /* Used by the startup to initialize data. */
    _sidata = LOADADDR(.bss);

    /* .bss section which is used for uninitialized data */
    .bss (NOLOAD) :
    {
        . = ALIGN(4);
        _sbss = . ;
        _szero = .;
        *(.bss .bss.*)
        *(COMMON)
        . = ALIGN(4);
        _ebss = . ;
        _ezero = .;
    } > ram

    /* stack section */
    .stack (NOLOAD):
    {
        . = ALIGN(8);
        _sstack = .;
        . = . + __stack_size__;
        . = ALIGN(8);
        _estack = .;
    } > ram

    . = ALIGN(4);
    _end = . ;
}

If it does not work, please share the whole project. You should now be able to upload files.

This is what I have when I try to upload files:

This is the main.c file:

/*
 * FreeRTOS V202212.00
 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 *
 */

/******************************************************************************
 * This project provides two demo applications.  A simple blinky style project,
 * and a more comprehensive test and demo application.  The
 * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting (defined in this file) is used to
 * select between the two.  The simply blinky demo is implemented and described
 * in main_blinky.c.  The more comprehensive test and demo application is
 * implemented and described in main_full.c.
 *
 * This file implements the code that is not demo specific, including the
 * hardware setup and FreeRTOS hook functions.
 *
 */

/* Standard includes. */
#include <stdio.h>

#include <ioport.h>

#include <ioport_pio.h>

#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "semphr.h"
#include "portmacro.h"
#include "event_groups.h"


#include "uart_dma.h"
#include "conf_board.h"
#include "rb_uint8_256.h"
#include "usart.h"
#include "rb_tx_dbg_uart.h"
#include "power.h"
#include "core_cm4.h"
#include "wdt.h"
#include "string.h"
#include "compiler.h"

#include <pio/pio.h>
#include <pio_handler.h>

#define POWER_BUTTON        MCU_PB_PWR_MASK
#define TRIGGER_BUTTON      MCU_PB_USR_MASK

#define PWR_BUT_INT_PRESS   PIO_IT_RISE_EDGE
#define PWR_BUT_INT_REAL    PIO_IT_FALL_EDGE
#define TRI_BUT_INT_PRESS   PIO_IT_FALL_EDGE
#define TRI_BUT_INT_REAL    PIO_IT_RISE_EDGE

#define BIT_0 (1 << 0)
#define BIT_1 (1 << 1)

#define mainREAD_ONLY_ALIGN_SIZE 512

/* Declare a variable to hold the handle of the created event group. */
EventGroupHandle_t xEventGroupHandle;

/* Declare a variable to hold the data associated with the created
event group. */
StaticEventGroup_t xCreatedEventGroup;



SemaphoreHandle_t xSemaphore = NULL;
StaticSemaphore_t xSemaphoreBuffer;


static const uart_dma_t     uart_dma         = UART_DMA__UART2;
static void tx_callback_from_IRQ(void);

static rb_tx_dbg_uart_t tx_ring_buffer = {};

// ------------------ TX -------------------
static void try_to_pop_ring_buffer_to_uart_dma(void) {
    // can be call from IRQ or main context -> must be protected with ctritical section
    cpu_irq_enter_critical();  //-------------------------
    uart_dma_frame_t* tx_frame = uart_dma_tx_get_frame_buffer(uart_dma);
    if (tx_frame != NULL) {
        // pop from ring buffer to tx frame
        const uint32_t nb_popped = rb_tx_dbg_uart_pop_multi(&tx_ring_buffer, &tx_frame->data[tx_frame->len], tx_frame->max_len - tx_frame->len);
        tx_frame->len += nb_popped;
        uart_dma_tx_send_frame(uart_dma);
    }
    cpu_irq_leave_critical();  //-------------------------
}

// call when uart_dma has finished to send a frame
static void tx_callback_from_IRQ(void) {
    try_to_pop_ring_buffer_to_uart_dma();
}

#if 0
TaskHandle_t xTaskTestOverflow;

void fun(int x);
void fun (int x){
    UBaseType_t uxHighWaterMark;
    char ch[4];

    if (x==1){
        uart_dma_write(uart_dma, "Fin de l'exécution", sizeof(char)*19);
    }
    else {
        //uart_dma_write(uart_dma, "Exécution en cours", sizeof(char)*19);
        x=6;
        /* Inspect our own high water mark on entering the task. */
        uxHighWaterMark = uxTaskGetStackHighWaterMark(xTaskTestOverflow);

        sprintf(ch, "%lu", uxHighWaterMark);
        while (uart_dma_tx_get_frame_buffer(uart_dma)==NULL) {
            vTaskDelay(1000/portTICK_PERIOD_MS);
        }

        uart_dma_write(uart_dma, ch, sizeof(char)*4);
        fun(x);
    }
}

static void taskTestOverflow( void * pvParameters) {
    UNUSED(pvParameters);

    int x = 5;

    for (;;)
    {
        fun(x);
    }
}

#endif

StaticTask_t xTaskBufferuart;
TaskHandle_t xTaskuart;
static void taskuart( void * pvParameters) {
    UNUSED(pvParameters);

    portTickType xLastWakeTime;

    xLastWakeTime = xTaskGetTickCount();

    vTaskDelayUntil(&xLastWakeTime, 100/portTICK_PERIOD_MS);

    char p[9] ="Bonjour ";

    for (;;)
    {
        while (uart_dma_tx_get_frame_buffer(uart_dma)==NULL) {
            vTaskDelay(1000/portTICK_PERIOD_MS);
        }
        uart_dma_write(uart_dma, p, sizeof(char)*9);
        vTaskSuspend(NULL);
        //vTaskDelayUntil(&xLastWakeTime, 9000); //correspond à une périodicité de 9s
    }
}

#if 0
TaskHandle_t xTaskCStack;
static void taskCStack( void * pvParameters) {

    UNUSED(pvParameters);

    UBaseType_t uxHighWaterMark;

    char ch[4];

    

    for (;;)
    {
        /* Inspect our own high water mark on entering the task. */
        uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL);

        sprintf(ch, "%lu", uxHighWaterMark);
        while (uart_dma_tx_get_frame_buffer(uart_dma)==NULL) {
            vTaskDelay(1000/portTICK_PERIOD_MS);
        }

        //strcat(ch, " ");
        //vTaskDelay(3000/portTICK_PERIOD_MS);
        uart_dma_write(uart_dma, ch, sizeof(char)*4);
        //vTaskDelay(3000/portTICK_PERIOD_MS); //correspond à une périodicité de 3s
    }
}

#endif


StaticTask_t xTaskBuffer1;
TaskHandle_t xTask1;
static void task1( void * pvParameters ){
    UNUSED(pvParameters);

    portTickType xLastWakeTime;
    
    #if 0
    uint8_t buf = 49;
    #endif

    UBaseType_t uxHighWaterMark;
    char ch[3];
    //Allume led camera en rouge
    ioport_pin_t led_pin = 23;

    

    arch_ioport_set_pin_dir(led_pin, IOPORT_DIR_OUTPUT);

    xLastWakeTime =xTaskGetTickCount();

    vTaskDelayUntil(&xLastWakeTime, 100/portTICK_PERIOD_MS);
    
    

    /* Worker task Loop. */
    for(;;)
    {   
        /*for (uint32_t i =0; i<100; i++){
            buf = buf +i;
        }*/
        arch_ioport_set_pin_level(led_pin, true);
        vTaskDelay(1000/portTICK_PERIOD_MS);
        //uart_dma_write(uart_dma, &buf, sizeof(uint8_t));
        //printf("%u", buf);
        while (uart_dma_tx_get_frame_buffer(uart_dma)==NULL) {
            vTaskDelay(1000/portTICK_PERIOD_MS);
        }
        uart_dma_write(uart_dma, "Tache 1 ", sizeof(char)*9);
        
        arch_ioport_set_pin_level(led_pin, false);
        //vTaskDelay(2000/portTICK_PERIOD_MS);

        //vTaskDelay(1000/portTICK_PERIOD_MS);

        /* Inspect our own high water mark on entering the task. */
        uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL);

        sprintf(ch, "%lu", uxHighWaterMark);
        while (uart_dma_tx_get_frame_buffer(uart_dma)==NULL) {
            vTaskDelay(1000/portTICK_PERIOD_MS);
        }

        //vTaskDelay(3000/portTICK_PERIOD_MS);
        uart_dma_write(uart_dma, ch, sizeof(char)*3);

        /*Calling the function will have used some stack space, we would therefore now expect uxTaskGetStackHighWaterMark()
        to return a value lower than when it was called on entering the task. */
        
        vTaskSuspend(NULL);
        //vTaskDelayUntil(&xLastWakeTime, 9000/portTICK_PERIOD_MS); //correspond à une périodicité de 9s
    }
}

StaticTask_t xTaskBuffer2;
TaskHandle_t xTask2;
static void task2( void * pvParameters ){
    UNUSED(pvParameters);

    portTickType xLastWakeTime;

    UBaseType_t uxHighWaterMark;
    char ch[3];
    
    //Allume led camera en vert
    ioport_pin_t led_pin = 21;
    arch_ioport_set_pin_dir(led_pin, IOPORT_DIR_OUTPUT);

    xLastWakeTime =xTaskGetTickCount();

    vTaskDelayUntil(&xLastWakeTime, 100/portTICK_PERIOD_MS);

    /* Worker task Loop. */
    for(;;)
    {
        arch_ioport_set_pin_level(led_pin, true);
        vTaskDelay(1000/portTICK_PERIOD_MS);
        while (uart_dma_tx_get_frame_buffer(uart_dma)==NULL) {
            vTaskDelay(1000/portTICK_PERIOD_MS);
        }
        uart_dma_write(uart_dma, "Tache 2 ", sizeof(char)*9);
        arch_ioport_set_pin_level(led_pin, false);

        uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL);

        uxHighWaterMark = 160 - uxHighWaterMark;

        sprintf(ch, "%lu", uxHighWaterMark);
        while (uart_dma_tx_get_frame_buffer(uart_dma)==NULL) {
            vTaskDelay(1000/portTICK_PERIOD_MS);
        }
        uart_dma_write(uart_dma, ch, sizeof(char)*3);

        vTaskSuspend(NULL);
        //vTaskDelayUntil(&xLastWakeTime, 4000/portTICK_PERIOD_MS);
    }
}

TaskHandle_t xTaskSender;
static void taskSender(void *pvParameters){
    UNUSED(pvParameters);

     for (;;)
    {
        vTaskDelay(pdMS_TO_TICKS(1000)); 

        xEventGroupSetBits(xEventGroupHandle, BIT_0);
        
        //printf("Event BIT_0 sent\n");

        while (uart_dma_tx_get_frame_buffer(uart_dma)==NULL) {
            vTaskDelay(1000/portTICK_PERIOD_MS);
        }
        uart_dma_write(uart_dma, "BIT_0 sent ", sizeof(char)*11);

        vTaskDelay(pdMS_TO_TICKS(2000));

        xEventGroupSetBits(xEventGroupHandle, BIT_1);

        while (uart_dma_tx_get_frame_buffer(uart_dma)==NULL) {
            vTaskDelay(1000/portTICK_PERIOD_MS);
        }
        uart_dma_write(uart_dma, "BIT_1 sent ", sizeof(char)*11);

    }

}

TaskHandle_t xTaskReceiver;
static void taskReceiver(void *pvParameters)
{
    UNUSED(pvParameters);
    EventBits_t uxBits;

    //Allume led camera en bleu
    ioport_pin_t led_pin_0 = 22;
    ioport_pin_t led_pin_cam = 23;


    //Allume led power en rouge
    ioport_pin_t led_pin_1 = 0;
    ioport_pin_t led_pin_pow = 21;

    arch_ioport_set_pin_dir(led_pin_0, IOPORT_DIR_OUTPUT);
    arch_ioport_set_pin_dir(led_pin_1, IOPORT_DIR_OUTPUT);

    for (;;)
    {
        uxBits = xEventGroupWaitBits(
            xEventGroupHandle,  // Le groupe d'événements à surveiller
            BIT_0 | BIT_1, // Les bits à surveiller
            pdTRUE,        // Effacer les bits après réception
            pdFALSE,       // Attendre tous les bits ou n'importe lequel
            portMAX_DELAY  // Attendre indéfiniment
        );
        
        if ((uxBits & BIT_0) != 0)
        {
            //arch_ioport_set_pin_level(led_pin_cam, false);
            arch_ioport_set_pin_level(led_pin_0, true);
            vTaskDelay(1000/portTICK_PERIOD_MS);
            arch_ioport_set_pin_level(led_pin_0, false);
            //printf("Received BIT_0\n");

            while (uart_dma_tx_get_frame_buffer(uart_dma)==NULL) {
                vTaskDelay(1000/portTICK_PERIOD_MS);
            }
            uart_dma_write(uart_dma, "BIT_0 receive ", sizeof(char)*14);
        }

        if ((uxBits & BIT_1) != 0)
        {
            //arch_ioport_set_pin_level(led_pin_pow, false);
            arch_ioport_set_pin_level(led_pin_1, true);
            vTaskDelay(1000/portTICK_PERIOD_MS);
            arch_ioport_set_pin_level(led_pin_1, false);

            while (uart_dma_tx_get_frame_buffer(uart_dma)==NULL) {
                vTaskDelay(1000/portTICK_PERIOD_MS);
            }
            uart_dma_write(uart_dma, "BIT_1 receive ", sizeof(char)*14);
            //printf("Received BIT_1\n");
        }
        //vTaskResume(xTaskSender);
    }
}


StaticTimer_t xTimerBuffer;
TimerHandle_t Timer_id;
static void TimerCallback ( TimerHandle_t pxtimer){
    UNUSED(pxtimer);
    #if 0
    uart_dma_write(uart_dma, "I am the timer ", sizeof(char)*16);
    #endif
    vTaskResume(xTaskuart);
    vTaskResume(xTask1); 
    vTaskResume(xTask2);
}

StaticTimer_t xTimerBufferwdt;
TimerHandle_t Timer_idwdt;
static void TimerCallbackwdt ( TimerHandle_t pxtimer){
    /* Reload watchdog */
    UNUSED(pxtimer);
    uart_dma_write(uart_dma, "Watchdog reset ", sizeof(char)*16);
    WDT->WDT_CR = WDT_CR_KEY_PASSWD | WDT_CR_WDRSTT;
}

extern const char _sfixed[];

static uint8_t tx_buffer[128] = {};

const uart_dma_config_t config = {
    .baudrate                 = 115200,
    .handshaking              = false,
    .rx_callback_from_IRQ     = NULL,
    .tx_end_callback_from_IRQ = tx_callback_from_IRQ,
    .tx_buffer                = tx_buffer,
    .tx_buffer_size           = sizeof(tx_buffer),
};

StaticTask_t xTaskBufferled;
TaskHandle_t xStartLedTask;
static void StartLedTask(void *pvParameters)
{
    uint32_t ulNotifiedValue;
    //Allume led power en rouge
    ioport_pin_t led_pin_1 = 0;
    arch_ioport_set_pin_dir(led_pin_1, IOPORT_DIR_OUTPUT);

    xSemaphore = xSemaphoreCreateBinaryStatic(&xSemaphoreBuffer);

    UNUSED(pvParameters);
    for(;;)
    {
        //ulNotifiedValue = ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
        
        if(xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE)
        {
            arch_ioport_set_pin_level(led_pin_1, true);
            vTaskDelay(1000/portTICK_PERIOD_MS);
            arch_ioport_set_pin_level(led_pin_1, false);
            uart_dma_write(uart_dma, "success\n", sizeof(char)*8);
            
        }
        else
        {
            uart_dma_write(uart_dma, "failure ", sizeof(char)*8);
        }
    }
}

void userButtonPressedHandler( uint32_t ul_id, uint32_t ul_mask) {  
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    
    //vTaskNotifyGiveFromISR(xStartLedTask, &xHigherPriorityTaskWoken);
    xSemaphoreGiveFromISR(xSemaphore, &xHigherPriorityTaskWoken);

    /* portYIELD_FROM_ISR() will request a context switch if executing this
	interrupt handler caused a task to leave the blocked state, and the task
	that left the blocked state has a higher priority than the currently running
	task (the task this interrupt interrupted).*/
    portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}

//Paramètres de création de la tâche 1

/* Declare the stack that will be used by the task.  The stack alignment must
    match its size and be a power of 2, so if 128 words are reserved for the stack
    then it must be aligned to ( 128 * 4 ) bytes.  This example used GCC syntax. */
    static portSTACK_TYPE xTaskStack1[ 256 ] __attribute__((aligned(256*4)));

    /* Declare an array that will be accessed by the task.  The task should only
    be able to read from the array, and not write to it. */
    char cReadOnlyArray1[ 512 ] __attribute__((aligned(512)));

    /* Fill in a TaskParameters_t structure to define the task - this is the
    structure passed to the xTaskCreateRestricted() function. */
    static const TaskParameters_t xTaskDefinition1 =
    {
        task1,   /* pvTaskCode */
        "Task 1",        /* pcName */
        140,             /* usStackDepth - defined in words, not bytes. */
        NULL,            /* pvParameters */
        5,               /* uxPriority - priority 1, start in User mode. */
        xTaskStack1,      /* puxStackBuffer - the array to use as the task stack. */

        /* xRegions - In this case only one of the three user definable regions is
        actually used.  The parameters are used to set the region to read only. */
        {
            /* Base address   Length                    Parameters */
            { cReadOnlyArray1, mainREAD_ONLY_ALIGN_SIZE, portMPU_REGION_READ_ONLY },
            { 0,	          0,                        0                        },
            { 0,	          0,                        0                        },
        },
        &xTaskBuffer1
    };

//Paramètres de création de la tâche 2

    /* Declare the stack that will be used by the task.  The stack alignment must
    match its size and be a power of 2, so if 128 words are reserved for the stack
    then it must be aligned to ( 128 * 4 ) bytes.  This example used GCC syntax. */
    static portSTACK_TYPE xTaskStack2[ 256 ] __attribute__((aligned(256*4)));

    /* Declare an array that will be accessed by the task.  The task should only
    be able to read from the array, and not write to it. */
    char cReadOnlyArray2[ 512 ] __attribute__((aligned(512)));

    /* Fill in a TaskParameters_t structure to define the task - this is the
    structure passed to the xTaskCreateRestricted() function. */
    static const TaskParameters_t xTaskDefinition2 =
    {
        task2,   /* pvTaskCode */
        "Task 2",        /* pcName */
        140,             /* usStackDepth - defined in words, not bytes. */
        NULL,            /* pvParameters */
        4,               /* uxPriority - priority 1, start in User mode. */
        xTaskStack2,      /* puxStackBuffer - the array to use as the task stack. */

        /* xRegions - In this case only one of the three user definable regions is
        actually used.  The parameters are used to set the region to read only. */
        {
            /* Base address   Length                    Parameters */
            { cReadOnlyArray2, mainREAD_ONLY_ALIGN_SIZE, portMPU_REGION_READ_ONLY },
            { 0,	          0,                        0                        },
            { 0,	          0,                        0                        },
        },
        &xTaskBuffer2
    };


//Paramètres de création de la tâche Uart

    /* Declare the stack that will be used by the task.  The stack alignment must
    match its size and be a power of 2, so if 128 words are reserved for the stack
    then it must be aligned to ( 128 * 4 ) bytes.  This example used GCC syntax. */
    static portSTACK_TYPE xTaskStackUart[ 128 ] __attribute__((aligned(128*4)));

    /* Declare an array that will be accessed by the task.  The task should only
    be able to read from the array, and not write to it. */
    char cReadOnlyArrayUart[ 512 ] __attribute__((aligned(512)));

    /* Fill in a TaskParameters_t structure to define the task - this is the
    structure passed to the xTaskCreateRestricted() function. */
    static const TaskParameters_t xTaskDefinitionUart =
    {
        taskuart,   /* pvTaskCode */
        "Task Uart",        /* pcName */
        128,             /* usStackDepth - defined in words, not bytes. */
        NULL,            /* pvParameters */
        2,               /* uxPriority - priority 1, start in User mode. */
        xTaskStackUart,      /* puxStackBuffer - the array to use as the task stack. */

        /* xRegions - In this case only one of the three user definable regions is
        actually used.  The parameters are used to set the region to read only. */
        {
            /* Base address   Length                    Parameters */
            { cReadOnlyArrayUart, mainREAD_ONLY_ALIGN_SIZE, portMPU_REGION_READ_ONLY },
            { 0,	          0,                        0                        },
            { 0,	          0,                        0                        },
        },
        &xTaskBufferuart
    };

//Paramètres de création de la tâche Led

    /* Declare the stack that will be used by the task.  The stack alignment must
    match its size and be a power of 2, so if 128 words are reserved for the stack
    then it must be aligned to ( 128 * 4 ) bytes.  This example used GCC syntax. */
    static portSTACK_TYPE xTaskStackled[ 128 ] __attribute__((aligned(128*4)));

    /* Declare an array that will be accessed by the task.  The task should only
    be able to read from the array, and not write to it. */
    char cReadOnlyArrayled[ 512 ] __attribute__((aligned(512)));

    /* Fill in a TaskParameters_t structure to define the task - this is the
    structure passed to the xTaskCreateRestricted() function. */
    static const TaskParameters_t xTaskDefinitionled =
    {
        StartLedTask,   /* pvTaskCode */
        "Task interrupt handler",        /* pcName */
        128,             /* usStackDepth - defined in words, not bytes. */
        NULL,            /* pvParameters */
        4,               /* uxPriority - priority 1, start in User mode. */
        xTaskStackled,      /* puxStackBuffer - the array to use as the task stack. */

        /* xRegions - In this case only one of the three user definable regions is
        actually used.  The parameters are used to set the region to read only. */
        {
            /* Base address   Length                    Parameters */
            { cReadOnlyArrayled, mainREAD_ONLY_ALIGN_SIZE, portMPU_REGION_READ_ONLY },
            { 0,	          0,                        0                        },
            { 0,	          0,                        0                        },
        },
        &xTaskBufferled
    };



int main( void )
{

    SCB->VTOR = (unsigned long)_sfixed;

    sysclk_init();

    BRD_clk_init();
    
    BRD_default_io_init();
   

    BRD_init_bus_ios_DBG_UART();

    uart_dma_init(uart_dma, config);

    PW_enable_maintain_power();

    //ioport_set_pin_peripheral_mode(PIO_PA5_IDX, IOPORT_MODE_MUX_A); // DEBUG_UART_RXD
    ioport_set_pin_mode(PIO_PA5_IDX, IOPORT_MODE_MUX_A);
    ioport_disable_pin(PIO_PA5_IDX);

    //ioport_set_pin_peripheral_mode(PIO_PA6_IDX, IOPORT_MODE_MUX_A); // DEBUG_UART_TXD
    ioport_set_pin_mode(PIO_PA6_IDX, IOPORT_MODE_MUX_A);
    ioport_disable_pin(PIO_PA6_IDX);

    arch_ioport_init();

    /* Set input OPEN_DRAIN */
	pio_set_input(PB_PIN_PIO, POWER_BUTTON, PIO_OPENDRAIN | PIO_DEBOUNCE);
	//pio_set_input(PB_PIN_PIO, TRIGGER_BUTTON, PIO_OPENDRAIN | PIO_DEBOUNCE);
    	
    /* Set GPIOs interruption */
	pio_handler_set(PB_PIN_PIO, PB_PIN_ID, POWER_BUTTON, PIO_OPENDRAIN | PWR_BUT_INT_PRESS, userButtonPressedHandler);
    //pio_handler_set(PB_PIN_PIO, PB_PIN_ID, TRIGGER_BUTTON, PIO_OPENDRAIN | TRI_BUT_INT_PRESS, BUT_trigger_press);
	
    //portENABLE_INTERRUPTS();

	/* Configure & Enable PIO line interrupts. */	
	pio_enable_interrupt(PB_PIN_PIO, POWER_BUTTON);
	//pio_enable_interrupt(PB_PIN_PIO, TRIGGER_BUTTON);

    //Les priorités autorisés sont définies dans FreeRTOSConfig.h et vont de 10 à 15
    NVIC_SetPriority((IRQn_Type)PB_PIN_ID, 15);
	
	/* Enable PIO controller IRQs. */
   	NVIC_EnableIRQ((IRQn_Type)PB_PIN_ID);

    

    uart_dma_tx_blocking_flush(uart_dma);
    
    xEventGroupHandle = xEventGroupCreateStatic(&xCreatedEventGroup);

    if( xEventGroupHandle == NULL ){
        uart_dma_write(uart_dma, "Echec Creation Groupe S ", sizeof(char)*24);
    }
    else {
        uart_dma_write(uart_dma, "Succes creation groupe S ", sizeof(char)*25);
    }
    
    /*Création des tâches*/

    /* Create the task defined by xTaskDefinition.  NULL is used as the second
    parameter as a task handle is not required. */
    xTaskCreateRestrictedStatic( &xTaskDefinition1, &xTask1 );

    xTaskCreateRestrictedStatic( &xTaskDefinition2, &xTask2 );

    xTaskCreateRestrictedStatic( &xTaskDefinitionUart, &xTaskuart );

    xTaskCreateRestrictedStatic( &xTaskDefinitionled, &xStartLedTask );

    Timer_idwdt = xTimerCreateStatic("Timer watchdog", (11000/portTICK_PERIOD_MS), pdTRUE, NULL, TimerCallbackwdt, &xTimerBufferwdt );
    Timer_id = xTimerCreateStatic("Timer",(8000/portTICK_PERIOD_MS), pdTRUE, NULL, TimerCallback, &xTimerBuffer);

    /*Timer_idwdt = xTimerCreate("Timer", (11000/portTICK_PERIOD_MS), pdTRUE, NULL, TimerCallbackwdt);
    Timer_id = xTimerCreate("Timer", (8000/portTICK_PERIOD_MS), pdTRUE, NULL, TimerCallback);*/
    xTimerStart (Timer_id, 0);
    xTimerStart (Timer_idwdt, 0);
    //xTaskCreate( taskuart, "Task Uart", configMINIMAL_STACK_SIZE, NULL, 4, &xTaskuart);
   
    /*if( Timer_id == NULL )
        {
            uart_dma_write(uart_dma, "Timer null ", sizeof(char)*12);
        }

    vTimerSetTimerID( Timer_id, ( void * ) 0 );
	

    /* Start the scheduler itself. */
    vTaskStartScheduler();

    return 0;
}



/* configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer,
StackType_t **ppxIdleTaskStackBuffer,
configSTACK_DEPTH_TYPE *puxIdleTaskStackSize )
{
/* If the buffers to be provided to the Idle task are declared inside this
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];

/* Pass out a pointer to the StaticTask_t structure in which the Idle task's
state will be stored. */
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;

/* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack;

/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*puxIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
/*-----------------------------------------------------------*/

/* configSUPPORT_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer,
StackType_t **ppxTimerTaskStackBuffer,
configSTACK_DEPTH_TYPE *puxTimerTaskStackSize )
{
/* If the buffers to be provided to the Timer task are declared inside this
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];

/* Pass out a pointer to the StaticTask_t structure in which the Timer
task's state will be stored. */
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB;

/* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack;

/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configTIMER_TASK_STACK_DEPTH is specified in words, not bytes. */
*puxTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}


void vApplicationMallocFailedHook( void )
{
	/* vApplicationMallocFailedHook() will only be called if
	configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h.  It is a hook
	function that will get called if a call to pvPortMalloc() fails.
	pvPortMalloc() is called internally by the kernel whenever a task, queue,
	timer or semaphore is created.  It is also called by various parts of the
	demo application.  If heap_1.c or heap_2.c are used, then the size of the
	heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
	FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
	to query the size of free heap space that remains (although it does not
	provide information on how the remaining heap might be fragmented). */
	taskDISABLE_INTERRUPTS();
	for( ;; );
}
/*-----------------------------------------------------------*/

void vApplicationIdleHook( void )
{
	/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
	to 1 in FreeRTOSConfig.h.  It will be called on each iteration of the idle
	task.  It is essential that code added to this hook function never attempts
	to block in any way (for example, call xQueueReceive() with a block time
	specified, or call vTaskDelay()).  If the application makes use of the
	vTaskDelete() API function (as this demo application does) then it is also
	important that vApplicationIdleHook() is permitted to return to its calling
	function, because it is the responsibility of the idle task to clean up
	memory allocated by the kernel to any task that has since been deleted. */

    //uart_dma_write(uart_dma, "I am the idle ", sizeof(char)*15);
	
}
/*-----------------------------------------------------------*/

void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
{
	( void ) pcTaskName;
	( void ) pxTask;

    while (uart_dma_tx_get_frame_buffer(uart_dma)==NULL) {
        vTaskDelay(1000/portTICK_PERIOD_MS);
    }
    uart_dma_write(uart_dma, "Stack overflow détecté ", sizeof(char)*26);
	/* Run time stack overflow checking is performed if
	configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2.  This hook
	function is called if a stack overflow is detected. */
	taskDISABLE_INTERRUPTS();
    vApplicationIdleHook();
	for( ;; );
}
/*-----------------------------------------------------------*/

void vApplicationTickHook( void )
{
	/* This function will be called by each tick interrupt if
	configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h.  User code can be
	added here, but the tick hook is called from an interrupt context, so
	code must not attempt to block, and only the interrupt safe FreeRTOS API
	functions can be used (those that end in FromISR()).  */

}
/*-----------------------------------------------------------*/

//=============== syscall redirection =============//
// STDOUT/STDERR are linked to DEBUG_UART

extern int _write(int file, const char* ptr, int len);
extern int _write(int file, const char* ptr, int len) {
    if ((file != 1) && (file != 2) && (file != 3)) {
        return -1;
    }


    // copy input buffer to tx ring buffer
    //! use critical section to keep message sentence ordered (not fragmented) when 'log' called from IRQ
    cpu_irq_enter_critical();  //-------------------------
    for (int i = 0; i < len; i++) {
        uint8_t c = ptr[i];
        const bool pushed = rb_tx_dbg_uart_push(&tx_ring_buffer, &c);
        if (false == pushed) {
            // ring buffer full -> do not push end buffer -> bytes are 'lost'
            break;
        }
    }
    cpu_irq_leave_critical();  //-------------------------

    try_to_pop_ring_buffer_to_uart_dma();
#if 0  // 1 : flush mode -> wait dma and ring buffer are sent // for used for debug
    uart_dma_tx_blocking_flush(uart_dma);
#endif

    return len;
}

//=============== syscall redirection =============//
extern int _read(int file, char* ptr, int len);
extern int _read(int file, char* ptr, int len) {
    (void)file;
    (void)ptr;
    (void)len;
    return 0;
}

Also, can we use portSUPPRESS_TICKS_AND_SLEEP with MPU mode on cortex-M4? I didn’t found the implementation.
Here is the file port.c that I am using:

#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE

/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "mpu_syscall_numbers.h"

#ifndef __VFP_FP__
    #error This port can only be used when the project options are configured to enable hardware floating point support.
#endif

#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE

#ifndef configSYSTICK_CLOCK_HZ
    #define configSYSTICK_CLOCK_HZ    configCPU_CLOCK_HZ
    /* Ensure the SysTick is clocked at the same frequency as the core. */
    #define portNVIC_SYSTICK_CLK      ( 1UL << 2UL )
#else

/* The way the SysTick is clocked is not modified in case it is not the same
 * as the core. */
    #define portNVIC_SYSTICK_CLK    ( 0 )
#endif

#ifndef configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS
    #warning "configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS is not defined. We recommend defining it to 0 in FreeRTOSConfig.h for better security."
    #define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS    1
#endif

/* Prototype of all Interrupt Service Routines (ISRs). */
typedef void ( * portISR_t )( void );

/* Constants required to access and manipulate the NVIC. */
#define portNVIC_SYSTICK_CTRL_REG                 ( *( ( volatile uint32_t * ) 0xe000e010 ) )
#define portNVIC_SYSTICK_LOAD_REG                 ( *( ( volatile uint32_t * ) 0xe000e014 ) )
#define portNVIC_SYSTICK_CURRENT_VALUE_REG        ( *( ( volatile uint32_t * ) 0xe000e018 ) )
#define portNVIC_SHPR3_REG                        ( *( ( volatile uint32_t * ) 0xe000ed20 ) )
#define portNVIC_SHPR2_REG                        ( *( ( volatile uint32_t * ) 0xe000ed1c ) )
#define portNVIC_SYS_CTRL_STATE_REG               ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
#define portNVIC_MEM_FAULT_ENABLE                 ( 1UL << 16UL )

/* Constants used to detect Cortex-M7 r0p0 and r0p1 cores, and ensure
 * that a work around is active for errata 837070. */
#define portCPUID                                 ( *( ( volatile uint32_t * ) 0xE000ed00 ) )
#define portCORTEX_M7_r0p1_ID                     ( 0x410FC271UL )
#define portCORTEX_M7_r0p0_ID                     ( 0x410FC270UL )

/* Constants required to access and manipulate the MPU. */
#define portMPU_TYPE_REG                          ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_REGION_BASE_ADDRESS_REG           ( *( ( volatile uint32_t * ) 0xe000ed9C ) )
#define portMPU_REGION_ATTRIBUTE_REG              ( *( ( volatile uint32_t * ) 0xe000edA0 ) )
#define portMPU_CTRL_REG                          ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
#define portEXPECTED_MPU_TYPE_VALUE               ( configTOTAL_MPU_REGIONS << 8UL )
#define portMPU_ENABLE                            ( 0x01UL )
#define portMPU_BACKGROUND_ENABLE                 ( 1UL << 2UL )
#define portPRIVILEGED_EXECUTION_START_ADDRESS    ( 0UL )
#define portMPU_REGION_VALID                      ( 0x10UL )
#define portMPU_REGION_ENABLE                     ( 0x01UL )
#define portPERIPHERALS_START_ADDRESS             0x40000000UL
#define portPERIPHERALS_END_ADDRESS               0x5FFFFFFFUL

/* Constants required to access and manipulate the SysTick. */
#define portNVIC_SYSTICK_INT                      ( 0x00000002UL )
#define portNVIC_SYSTICK_ENABLE                   ( 0x00000001UL )
#define portMIN_INTERRUPT_PRIORITY                ( 255UL )
#define portNVIC_PENDSV_PRI                       ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
#define portNVIC_SYSTICK_PRI                      ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )

/* Constants required to manipulate the VFP. */
#define portFPCCR                                 ( ( volatile uint32_t * ) 0xe000ef34UL ) /* Floating point context control register. */
#define portASPEN_AND_LSPEN_BITS                  ( 0x3UL << 30UL )

/* Constants required to set up the initial stack. */
#define portINITIAL_XPSR                          ( 0x01000000UL )
#define portINITIAL_EXC_RETURN                    ( 0xfffffffdUL )
#define portINITIAL_CONTROL_IF_UNPRIVILEGED       ( 0x03 )
#define portINITIAL_CONTROL_IF_PRIVILEGED         ( 0x02 )

/* Constants used to check the installation of the FreeRTOS interrupt handlers. */
#define portSCB_VTOR_REG                          ( *( ( portISR_t ** ) 0xE000ED08 ) )
#define portVECTOR_INDEX_SVC                      ( 11 )
#define portVECTOR_INDEX_PENDSV                   ( 14 )

/* Constants required to check the validity of an interrupt priority. */
#define portFIRST_USER_INTERRUPT_NUMBER           ( 16 )
#define portNVIC_IP_REGISTERS_OFFSET_16           ( 0xE000E3F0 )
#define portAIRCR_REG                             ( *( ( volatile uint32_t * ) 0xE000ED0C ) )
#define portMAX_8_BIT_VALUE                       ( ( uint8_t ) 0xff )
#define portTOP_BIT_OF_BYTE                       ( ( uint8_t ) 0x80 )
#define portMAX_PRIGROUP_BITS                     ( ( uint8_t ) 7 )
#define portPRIORITY_GROUP_MASK                   ( 0x07UL << 8UL )
#define portPRIGROUP_SHIFT                        ( 8UL )

/* Constants used during system call enter and exit. */
#define portPSR_STACK_PADDING_MASK                ( 1UL << 9UL )
#define portEXC_RETURN_STACK_FRAME_TYPE_MASK      ( 1UL << 4UL )

/* Offsets in the stack to the parameters when inside the SVC handler. */
#define portOFFSET_TO_LR                          ( 5 )
#define portOFFSET_TO_PC                          ( 6 )
#define portOFFSET_TO_PSR                         ( 7 )


/* For strict compliance with the Cortex-M spec the task start address should
 * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
#define portSTART_ADDRESS_MASK    ( ( StackType_t ) 0xfffffffeUL )

/* Does addr lie within [start, end] address range? */
#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \
    ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) )

/* Is the access request satisfied by the available permissions? */
#define portIS_AUTHORIZED( accessRequest, permissions ) \
    ( ( ( permissions ) & ( accessRequest ) ) == accessRequest )

/* Max value that fits in a uint32_t type. */
#define portUINT32_MAX    ( ~( ( uint32_t ) 0 ) )

/* Check if adding a and b will result in overflow. */
#define portADD_UINT32_WILL_OVERFLOW( a, b )    ( ( a ) > ( portUINT32_MAX - ( b ) ) )
/*-----------------------------------------------------------*/

/*
 * Configure a number of standard MPU regions that are used by all tasks.
 */
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;

/*
 * Return the smallest MPU region size that a given number of bytes will fit
 * into.  The region size is returned as the value that should be programmed
 * into the region attribute register for that region.
 */
static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) PRIVILEGED_FUNCTION;

/*
 * Setup the timer to generate the tick interrupts.  The implementation in this
 * file is weak to allow application writers to change the timer used to
 * generate the tick interrupt.
 */
void vPortSetupTimerInterrupt( void );

/*
 * Standard FreeRTOS exception handlers.
 */
void xPortPendSVHandler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
void xPortSysTickHandler( void ) PRIVILEGED_FUNCTION;
void vPortSVCHandler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;

/*
 * Starts the scheduler by restoring the context of the first task to run.
 */
static void prvRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;

/*
 * C portion of the SVC handler.  The SVC handler is split between an asm entry
 * and a C wrapper for simplicity of coding and maintenance.
 */
void vSVCHandler_C( uint32_t * pulRegisters ) __attribute__( ( noinline ) ) PRIVILEGED_FUNCTION;

/*
 * Function to enable the VFP.
 */
static void vPortEnableVFP( void ) __attribute__( ( naked ) );


BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) );


void vResetPrivilege( void ) __attribute__( ( naked ) );

/**
 * @brief Make a task unprivileged.
 */
void vPortSwitchToUserMode( void );

/**
 * @brief Enter critical section.
 */
#if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
    void vPortEnterCritical( void ) FREERTOS_SYSTEM_CALL;
#else
    void vPortEnterCritical( void ) PRIVILEGED_FUNCTION;
#endif

/**
 * @brief Exit from critical section.
 */
#if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
    void vPortExitCritical( void ) FREERTOS_SYSTEM_CALL;
#else
    void vPortExitCritical( void ) PRIVILEGED_FUNCTION;
#endif

#if ( configUSE_MPU_WRAPPERS_V1 == 0 )

    void vSystemCallEnter( uint32_t * pulTaskStack,
                           uint32_t ulLR,
                           uint8_t ucSystemCallNumber ) PRIVILEGED_FUNCTION;

#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */

#if ( configUSE_MPU_WRAPPERS_V1 == 0 )

/**
 * @brief Raise SVC for exiting from a system call.
 */
    void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;

#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */

#if ( configUSE_MPU_WRAPPERS_V1 == 0 )

    void vSystemCallExit( uint32_t * pulSystemCallStack,
                          uint32_t ulLR ) PRIVILEGED_FUNCTION;

#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */

/**
 * @brief Checks whether or not the calling task is privileged.
 *
 * @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
 */
BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION;
/*-----------------------------------------------------------*/


static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;

#if ( configUSE_MPU_WRAPPERS_V1 == 0 )

/*
 * This variable is set to pdTRUE when the scheduler is started.
 */
    PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE;

#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */


#if ( configASSERT_DEFINED == 1 )
    static uint8_t ucMaxSysCallPriority = 0;
    static uint32_t ulMaxPRIGROUPValue = 0;
    static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16;
#endif /* configASSERT_DEFINED */

/*-----------------------------------------------------------*/

/*
 * See header file for description.
 */
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
                                     TaskFunction_t pxCode,
                                     void * pvParameters,
                                     BaseType_t xRunPrivileged,
                                     xMPU_SETTINGS * xMPUSettings )
{
    if( xRunPrivileged == pdTRUE )
    {
        xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG;
        xMPUSettings->ulContext[ 0 ] = portINITIAL_CONTROL_IF_PRIVILEGED;
    }
    else
    {
        xMPUSettings->ulTaskFlags &= ( ~( portTASK_IS_PRIVILEGED_FLAG ) );
        xMPUSettings->ulContext[ 0 ] = portINITIAL_CONTROL_IF_UNPRIVILEGED;
    }

    xMPUSettings->ulContext[ 1 ] = 0x04040404;                                        /* r4. */
    xMPUSettings->ulContext[ 2 ] = 0x05050505;                                        /* r5. */
    xMPUSettings->ulContext[ 3 ] = 0x06060606;                                        /* r6. */
    xMPUSettings->ulContext[ 4 ] = 0x07070707;                                        /* r7. */
    xMPUSettings->ulContext[ 5 ] = 0x08080808;                                        /* r8. */
    xMPUSettings->ulContext[ 6 ] = 0x09090909;                                        /* r9. */
    xMPUSettings->ulContext[ 7 ] = 0x10101010;                                        /* r10. */
    xMPUSettings->ulContext[ 8 ] = 0x11111111;                                        /* r11. */
    xMPUSettings->ulContext[ 9 ] = portINITIAL_EXC_RETURN;                            /* EXC_RETURN. */

    xMPUSettings->ulContext[ 10 ] = ( uint32_t ) ( pxTopOfStack - 8 );                /* PSP with the hardware saved stack. */
    xMPUSettings->ulContext[ 11 ] = ( uint32_t ) pvParameters;                        /* r0. */
    xMPUSettings->ulContext[ 12 ] = 0x01010101;                                       /* r1. */
    xMPUSettings->ulContext[ 13 ] = 0x02020202;                                       /* r2. */
    xMPUSettings->ulContext[ 14 ] = 0x03030303;                                       /* r3. */
    xMPUSettings->ulContext[ 15 ] = 0x12121212;                                       /* r12. */
    xMPUSettings->ulContext[ 16 ] = 0;                                                /* LR. */
    xMPUSettings->ulContext[ 17 ] = ( ( uint32_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC. */
    xMPUSettings->ulContext[ 18 ] = portINITIAL_XPSR;                                 /* xPSR. */

    #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
    {
        /* Ensure that the system call stack is double word aligned. */
        xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] );
        xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) &
                                                                                 ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) );

        /* This is not NULL only for the duration of a system call. */
        xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL;
    }
    #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */

    return &( xMPUSettings->ulContext[ 19 ] );
}
/*-----------------------------------------------------------*/

#if ( configUSE_MPU_WRAPPERS_V1 == 0 )

    void vPortSVCHandler( void ) /* __attribute__( ( naked ) ) PRIVILEGED_FUNCTION */
    {
        __asm volatile
        (
            ".syntax unified                \n"
            ".extern vSVCHandler_C          \n"
            ".extern vSystemCallEnter       \n"
            ".extern vSystemCallExit        \n"
            "                               \n"
            "tst lr, #4                     \n"
            "ite eq                         \n"
            "mrseq r0, msp                  \n"
            "mrsne r0, psp                  \n"
            "                               \n"
            "ldr r1, [r0, #24]              \n"
            "ldrb r2, [r1, #-2]             \n"
            "cmp r2, %0                     \n"
            "blt syscall_enter              \n"
            "cmp r2, %1                     \n"
            "beq syscall_exit               \n"
            "b vSVCHandler_C                \n"
            "                               \n"
            "syscall_enter:                 \n"
            "    mov r1, lr                 \n"
            "    b vSystemCallEnter         \n"
            "                               \n"
            "syscall_exit:                  \n"
            "    mov r1, lr                 \n"
            "    b vSystemCallExit          \n"
            "                               \n"
            : /* No outputs. */
            : "i" ( NUM_SYSTEM_CALLS ), "i" ( portSVC_SYSTEM_CALL_EXIT )
            : "r0", "r1", "r2", "memory"
        );
    }

#else /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */

    void vPortSVCHandler( void )
    {
        /* Assumes psp was in use. */
        __asm volatile
        (
            #ifndef USE_PROCESS_STACK /* Code should not be required if a main() is using the process stack. */
                "   tst lr, #4                      \n"
                "   ite eq                          \n"
                "   mrseq r0, msp                   \n"
                "   mrsne r0, psp                   \n"
            #else
                "   mrs r0, psp                     \n"
            #endif
            "   b %0                            \n"
            ::"i" ( vSVCHandler_C ) : "r0", "memory"
        );
    }

#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

void vSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */
{
    uint8_t ucSVCNumber;
    uint32_t ulPC;

    #if ( ( configUSE_MPU_WRAPPERS_V1 == 1 ) && ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) )
        #if defined( __ARMCC_VERSION )

            /* Declaration when these variable are defined in code instead of being
             * exported from linker scripts. */
            extern uint32_t * __syscalls_flash_start__;
            extern uint32_t * __syscalls_flash_end__;
        #else
            /* Declaration when these variable are exported from linker scripts. */
            extern uint32_t __syscalls_flash_start__[];
            extern uint32_t __syscalls_flash_end__[];
        #endif /* #if defined( __ARMCC_VERSION ) */
    #endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 1 ) && ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) ) */

    /* The stack contains: r0, r1, r2, r3, r12, LR, PC and xPSR.  The first
     * argument (r0) is pulParam[ 0 ]. */
    ulPC = pulParam[ portOFFSET_TO_PC ];
    ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ];

    switch( ucSVCNumber )
    {
        case portSVC_START_SCHEDULER:
            prvRestoreContextOfFirstTask();
            break;

        case portSVC_YIELD:
            portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;

            __asm volatile ( "dsb" ::: "memory" );
            __asm volatile ( "isb" );

            break;

    #if ( configUSE_MPU_WRAPPERS_V1 == 1 )
        #if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 )
            case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the
                                           * svc was raised from any of the
                                           * system calls. */

                if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) &&
                    ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) )
                {
                    __asm volatile
                    (
                        "   mrs r1, control     \n" /* Obtain current control value. */
                        "   bic r1, #1          \n" /* Set privilege bit. */
                        "   msr control, r1     \n" /* Write back new control value. */
                        ::: "r1", "memory"
                    );
                }

                break;
        #else /* if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */
            case portSVC_RAISE_PRIVILEGE:
                __asm volatile
                (
                    "   mrs r1, control     \n" /* Obtain current control value. */
                    "   bic r1, #1          \n" /* Set privilege bit. */
                    "   msr control, r1     \n" /* Write back new control value. */
                    ::: "r1", "memory"
                );
                break;
        #endif /* #if( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */
    #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */

        default: /* Unknown SVC call. */
            break;
    }
}
/*-----------------------------------------------------------*/

#if ( configUSE_MPU_WRAPPERS_V1 == 0 )

    void vSystemCallEnter( uint32_t * pulTaskStack,
                           uint32_t ulLR,
                           uint8_t ucSystemCallNumber ) /* PRIVILEGED_FUNCTION */
    {
        extern TaskHandle_t pxCurrentTCB;
        extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
        xMPU_SETTINGS * pxMpuSettings;
        uint32_t * pulSystemCallStack;
        uint32_t ulStackFrameSize, ulSystemCallLocation, i;

        #if defined( __ARMCC_VERSION )
            /* Declaration when these variable are defined in code instead of being
             * exported from linker scripts. */
            extern uint32_t * __syscalls_flash_start__;
            extern uint32_t * __syscalls_flash_end__;
        #else
            /* Declaration when these variable are exported from linker scripts. */
            extern uint32_t __syscalls_flash_start__[];
            extern uint32_t __syscalls_flash_end__[];
        #endif /* #if defined( __ARMCC_VERSION ) */

        ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ];
        pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB );

                if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) &&
            ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) &&
            ( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ) &&
            ( uxSystemCallImplementations[ ucSystemCallNumber ] != ( UBaseType_t ) 0 ) )
        {
            pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack;

            if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
            {
                /* Extended frame i.e. FPU in use. */
                ulStackFrameSize = 26;
                __asm volatile (
                    " vpush {s0}         \n" /* Trigger lazy stacking. */
                    " vpop  {s0}         \n" /* Nullify the affect of the above instruction. */
                    ::: "memory"
                    );
            }
            else
            {
                /* Standard frame i.e. FPU not in use. */
                ulStackFrameSize = 8;
            }

            /* Make space on the system call stack for the stack frame. */
            pulSystemCallStack = pulSystemCallStack - ulStackFrameSize;

            /* Copy the stack frame. */
            for( i = 0; i < ulStackFrameSize; i++ )
            {
                pulSystemCallStack[ i ] = pulTaskStack[ i ];
            }

            /* Use the pulSystemCallStack in thread mode. */
            __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) );

            /* Raise the privilege for the duration of the system call. */
            __asm volatile (
                " mrs r1, control     \n" /* Obtain current control value. */
                " bic r1, #1          \n" /* Clear nPRIV bit. */
                " msr control, r1     \n" /* Write back new control value. */
                ::: "r1", "memory"
                );

            /* Remember the location where we should copy the stack frame when we exit from
             * the system call. */
            pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize;

            
            pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ];

            /* Start executing the system call upon returning from this handler. */
            pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ];
            /* Raise a request to exit from the system call upon finishing the
             * system call. */
            pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit;

            /* Record if the hardware used padding to force the stack pointer
             * to be double word aligned. */
            if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK )
            {
                pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG;
            }
            else
            {
                pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG );
            }

            /* We ensure in pxPortInitialiseStack that the system call stack is
             * double word aligned and therefore, there is no need of padding.
             * Clear the bit[9] of stacked xPSR. */
            pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK );
        }
    }

#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

#if ( configUSE_MPU_WRAPPERS_V1 == 0 )

    void vRequestSystemCallExit( void ) /* __attribute__( ( naked ) ) PRIVILEGED_FUNCTION */
    {
        __asm volatile ( "svc %0 \n" ::"i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" );
    }

#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

#if ( configUSE_MPU_WRAPPERS_V1 == 0 )

    void vSystemCallExit( uint32_t * pulSystemCallStack,
                          uint32_t ulLR ) /* PRIVILEGED_FUNCTION */
    {
        extern TaskHandle_t pxCurrentTCB;
        xMPU_SETTINGS * pxMpuSettings;
        uint32_t * pulTaskStack;
        uint32_t ulStackFrameSize, ulSystemCallLocation, i;

        #if defined( __ARMCC_VERSION )
            /* Declaration when these variable are defined in code instead of being
             * exported from linker scripts. */
            extern uint32_t * __privileged_functions_start__;
            extern uint32_t * __privileged_functions_end__;
        #else
            /* Declaration when these variable are exported from linker scripts. */
            extern uint32_t __privileged_functions_start__[];
            extern uint32_t __privileged_functions_end__[];
        #endif /* #if defined( __ARMCC_VERSION ) */

        ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ];
        pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB );

        if( ( ulSystemCallLocation >= ( uint32_t ) __privileged_functions_start__ ) &&
            ( ulSystemCallLocation <= ( uint32_t ) __privileged_functions_end__ ) &&
            ( pxMpuSettings->xSystemCallStackInfo.pulTaskStack != NULL ) )
        {
            pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack;

            if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
            {
                /* Extended frame i.e. FPU in use. */
                ulStackFrameSize = 26;
                __asm volatile (
                    " vpush {s0}         \n" /* Trigger lazy stacking. */
                    " vpop  {s0}         \n" /* Nullify the affect of the above instruction. */
                    ::: "memory"
                    );
            }
            else
            {
                /* Standard frame i.e. FPU not in use. */
                ulStackFrameSize = 8;
            }

            /* Make space on the task stack for the stack frame. */
            pulTaskStack = pulTaskStack - ulStackFrameSize;

            /* Copy the stack frame. */
            for( i = 0; i < ulStackFrameSize; i++ )
            {
                pulTaskStack[ i ] = pulSystemCallStack[ i ];
            }

            /* Use the pulTaskStack in thread mode. */
            __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) );

            /* Drop the privilege before returning to the thread mode. */
            __asm volatile (
                " mrs r1, control     \n" /* Obtain current control value. */
                " orr r1, #1          \n" /* Set nPRIV bit. */
                " msr control, r1     \n" /* Write back new control value. */
                ::: "r1", "memory"
                );

            /* Return to the caller of the System Call entry point (i.e. the
             * caller of the MPU_<API>). */
            pulTaskStack[ portOFFSET_TO_PC ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry;
            /* Ensure that LR has a valid value.*/
            pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry;

            /* If the hardware used padding to force the stack pointer
             * to be double word aligned, set the stacked xPSR bit[9],
             * otherwise clear it. */
            if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG )
            {
                pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK;
            }
            else
            {
                pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK );
            }

            /* This is not NULL only for the duration of the system call. */
            pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL;
        }
    }

#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */
{
    BaseType_t xTaskIsPrivileged = pdFALSE;
    const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */

    if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
    {
        xTaskIsPrivileged = pdTRUE;
    }

    return xTaskIsPrivileged;
}
/*-----------------------------------------------------------*/

static void prvRestoreContextOfFirstTask( void )
{
    __asm volatile
    (
        " ldr r0, =0xE000ED08                   \n" /* Use the NVIC offset register to locate the stack. */
        " ldr r0, [r0]                          \n"
        " ldr r0, [r0]                          \n"
        " msr msp, r0                           \n" /* Set the msp back to the start of the stack. */
        "                                       \n"
        /*------------ Program MPU. ------------ */
        " ldr r3, pxCurrentTCBConst2            \n" /* r3 = pxCurrentTCBConst2. */
        " ldr r2, [r3]                          \n" /* r2 = pxCurrentTCB. */
        " add r2, r2, #4                        \n" /* r2 = Second item in the TCB which is xMPUSettings. */
        "                                       \n"
        " dmb                                   \n" /* Complete outstanding transfers before disabling MPU. */
        " ldr r0, =0xe000ed94                   \n" /* MPU_CTRL register. */
        " ldr r3, [r0]                          \n" /* Read the value of MPU_CTRL. */
        " bic r3, #1                            \n" /* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */
        " str r3, [r0]                          \n" /* Disable MPU. */
        "                                       \n"
        " ldr r0, =0xe000ed9c                   \n" /* Region Base Address register. */
        " ldmia r2!, {r4-r11}                   \n" /* Read 4 sets of MPU registers [MPU Region # 0 - 3]. */
        " stmia r0, {r4-r11}                    \n" /* Write 4 sets of MPU registers [MPU Region # 0 - 3]. */
        "                                       \n"
        #if ( configTOTAL_MPU_REGIONS == 16 )
            " ldmia r2!, {r4-r11}                   \n" /* Read 4 sets of MPU registers [MPU Region # 4 - 8]. */
            " stmia r0, {r4-r11}                    \n" /* Write 4 sets of MPU registers. [MPU Region # 4 - 8]. */
            " ldmia r2!, {r4-r11}                   \n" /* Read 4 sets of MPU registers [MPU Region # 9 - 12]. */
            " stmia r0, {r4-r11}                    \n" /* Write 4 sets of MPU registers. [MPU Region # 9 - 12]. */
        #endif /* configTOTAL_MPU_REGIONS == 16. */
        "                                       \n"
        " ldr r0, =0xe000ed94                   \n" /* MPU_CTRL register. */
        " ldr r3, [r0]                          \n" /* Read the value of MPU_CTRL. */
        " orr r3, #1                            \n" /* r3 = r3 | 1 i.e. Set the bit 0 in r3. */
        " str r3, [r0]                          \n" /* Enable MPU. */
        " dsb                                   \n" /* Force memory writes before continuing. */
        "                                       \n"
        /*---------- Restore Context. ---------- */
        " ldr r3, pxCurrentTCBConst2            \n" /* r3 = pxCurrentTCBConst2. */
        " ldr r2, [r3]                          \n" /* r2 = pxCurrentTCB. */
        " ldr r1, [r2]                          \n" /* r1 = Location of saved context in TCB. */
        "                                       \n"
        " ldmdb r1!, {r0, r4-r11}               \n" /* r0 contains PSP after the hardware had saved context. r4-r11 contain hardware saved context. */
        " msr psp, r0                           \n"
        " stmia r0, {r4-r11}                    \n" /* Copy the hardware saved context on the task stack. */
        " ldmdb r1!, {r3-r11, lr}               \n" /* r3 contains CONTROL register. r4-r11 and LR restored. */
        " msr control, r3                       \n"
        " str r1, [r2]                          \n" /* Save the location where the context should be saved next as the first member of TCB. */
        "                                       \n"
        " mov r0, #0                            \n"
        " msr basepri, r0                       \n"
        " bx lr                                 \n"
        "                                       \n"
        " .ltorg                                \n" /* Assemble current literal pool to avoid offset-out-of-bound errors with lto. */
        " .align 4                              \n"
        " pxCurrentTCBConst2: .word pxCurrentTCB\n"
    );
}
/*-----------------------------------------------------------*/

/*
 * See header file for description.
 */
BaseType_t xPortStartScheduler( void )
{
    /* Errata 837070 workaround must only be enabled on Cortex-M7 r0p0
     * and r0p1 cores. */
    #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
        configASSERT( ( portCPUID == portCORTEX_M7_r0p1_ID ) || ( portCPUID == portCORTEX_M7_r0p0_ID ) );
    #else

        /* When using this port on a Cortex-M7 r0p0 or r0p1 core, define
         * configENABLE_ERRATA_837070_WORKAROUND to 1 in your
         * FreeRTOSConfig.h. */
        configASSERT( portCPUID != portCORTEX_M7_r0p1_ID );
        configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
    #endif

        #if ( configCHECK_HANDLER_INSTALLATION == 1 )
    {
        const portISR_t * const pxVectorTable = portSCB_VTOR_REG;

        configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == vPortSVCHandler );
        configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == xPortPendSVHandler );
    }
    #endif /* configCHECK_HANDLER_INSTALLATION */

    #if ( configASSERT_DEFINED == 1 )
    {
        volatile uint8_t ucOriginalPriority;
        volatile uint32_t ulImplementedPrioBits = 0;
        volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
        volatile uint8_t ucMaxPriorityValue;

                ucOriginalPriority = *pucFirstUserPriorityRegister;

        /* Determine the number of priority bits available.  First write to all
         * possible bits. */
        *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;

        /* Read the value back to see how many bits stuck. */
        ucMaxPriorityValue = *pucFirstUserPriorityRegister;

        /* Use the same mask on the maximum system call priority. */
        ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;

                configASSERT( ucMaxSysCallPriority );

        /* Check that the bits not implemented in hardware are zero in
         * configMAX_SYSCALL_INTERRUPT_PRIORITY. */
        configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U );

        /* Calculate the maximum acceptable priority group value for the number
         * of bits read back. */

        while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
        {
            ulImplementedPrioBits++;
            ucMaxPriorityValue <<= ( uint8_t ) 0x01;
        }

        if( ulImplementedPrioBits == 8 )
        {
            configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
            ulMaxPRIGROUPValue = 0;
        }
        else
        {
            ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits;
        }

        /* Shift the priority group value back to its position within the AIRCR
         * register. */
        ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
        ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;

        /* Restore the clobbered interrupt priority register to its original
         * value. */
        *pucFirstUserPriorityRegister = ucOriginalPriority;
    }
    #endif /* configASSERT_DEFINED */

    /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
     * the highest priority. */
    portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
    portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
    portNVIC_SHPR2_REG = 0;

    /* Configure the regions in the MPU that are common to all tasks. */
    prvSetupMPU();

    /* Start the timer that generates the tick ISR.  Interrupts are disabled
     * here already. */
    vPortSetupTimerInterrupt();

    /* Initialise the critical nesting count ready for the first task. */
    uxCriticalNesting = 0;

    #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
    {
        xSchedulerRunning = pdTRUE;
    }
    #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */

    /* Ensure the VFP is enabled - it should be anyway. */
    vPortEnableVFP();

    /* Lazy save always. */
    *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS;

        __asm volatile (
        " ldr r0, =0xE000ED08   \n" /* Use the NVIC offset register to locate the stack. */
        " ldr r0, [r0]          \n"
        " ldr r0, [r0]          \n"
        " msr msp, r0           \n" /* Set the msp back to the start of the stack. */
        " mov r0, #0            \n" /* Clear the bit that indicates the FPU is in use, see comment above. */
        " msr control, r0       \n"
        " cpsie i               \n" /* Globally enable interrupts. */
        " cpsie f               \n"
        " dsb                   \n"
        " isb                   \n"
        " svc %0                \n" /* System call to start first task. */
        " nop                   \n"
        " .ltorg                \n"
        ::"i" ( portSVC_START_SCHEDULER ) : "memory" );

    /* Should not get here! */
    return 0;
}
/*-----------------------------------------------------------*/

void vPortEndScheduler( void )
{
    /* Not implemented in ports where there is nothing to return to.
     * Artificially force an assert. */
    configASSERT( uxCriticalNesting == 1000UL );
}
/*-----------------------------------------------------------*/

void vPortEnterCritical( void )
{
    #if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
        if( portIS_PRIVILEGED() == pdFALSE )
        {
            portRAISE_PRIVILEGE();
            portMEMORY_BARRIER();

            portDISABLE_INTERRUPTS();
            uxCriticalNesting++;
            portMEMORY_BARRIER();

            portRESET_PRIVILEGE();
            portMEMORY_BARRIER();
        }
        else
        {
            portDISABLE_INTERRUPTS();
            uxCriticalNesting++;
        }
    #else /* if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) */
        portDISABLE_INTERRUPTS();
        uxCriticalNesting++;
    #endif /* if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) */
}
/*-----------------------------------------------------------*/

void vPortExitCritical( void )
{
    #if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
        if( portIS_PRIVILEGED() == pdFALSE )
        {
            portRAISE_PRIVILEGE();
            portMEMORY_BARRIER();

            configASSERT( uxCriticalNesting );
            uxCriticalNesting--;

            if( uxCriticalNesting == 0 )
            {
                portENABLE_INTERRUPTS();
            }

            portMEMORY_BARRIER();

            portRESET_PRIVILEGE();
            portMEMORY_BARRIER();
        }
        else
        {
            configASSERT( uxCriticalNesting );
            uxCriticalNesting--;

            if( uxCriticalNesting == 0 )
            {
                portENABLE_INTERRUPTS();
            }
        }
    #else /* if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) */
        configASSERT( uxCriticalNesting );
        uxCriticalNesting--;

        if( uxCriticalNesting == 0 )
        {
            portENABLE_INTERRUPTS();
        }
    #endif /* if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) */
}
/*-----------------------------------------------------------*/

void xPortPendSVHandler( void )
{
    /* This is a naked function. */

    __asm volatile
    (
        " ldr r3, pxCurrentTCBConst             \n" /* r3 = pxCurrentTCBConst. */
        " ldr r2, [r3]                          \n" /* r2 = pxCurrentTCB. */
        " ldr r1, [r2]                          \n" /* r1 = Location where the context should be saved. */
        "                                       \n"
        /*------------ Save Context. ----------- */
        " mrs r3, control                       \n"
        " mrs r0, psp                           \n"
        " isb                                   \n"
        "                                       \n"
        " add r0, r0, #0x20                     \n" /* Move r0 to location where s0 is saved. */
        " tst lr, #0x10                         \n"
        " ittt eq                               \n"
        " vstmiaeq r1!, {s16-s31}               \n" /* Store s16-s31. */
        " vldmiaeq r0, {s0-s16}                 \n" /* Copy hardware saved FP context into s0-s16. */
        " vstmiaeq r1!, {s0-s16}                \n" /* Store hardware saved FP context. */
        " sub r0, r0, #0x20                     \n" /* Set r0 back to the location of hardware saved context. */
        "                                       \n"
        " stmia r1!, {r3-r11, lr}               \n" /* Store CONTROL register, r4-r11 and LR. */
        " ldmia r0, {r4-r11}                    \n" /* Copy hardware saved context into r4-r11. */
        " stmia r1!, {r0, r4-r11}               \n" /* Store original PSP (after hardware has saved context) and the hardware saved context. */
        " str r1, [r2]                          \n" /* Save the location from where the context should be restored as the first member of TCB. */
        "                                       \n"
        /*---------- Select next task. --------- */
        " mov r0, %0                            \n"
        #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
            " cpsid i                               \n" /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
        #endif
        " msr basepri, r0                       \n"
        " dsb                                   \n"
        " isb                                   \n"
        #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
            " cpsie i                               \n" /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
        #endif
        " bl vTaskSwitchContext                 \n"
        " mov r0, #0                            \n"
        " msr basepri, r0                       \n"
        "                                       \n"
        /*------------ Program MPU. ------------ */
        " ldr r3, pxCurrentTCBConst             \n" /* r3 = pxCurrentTCBConst. */
        " ldr r2, [r3]                          \n" /* r2 = pxCurrentTCB. */
        " add r2, r2, #4                        \n" /* r2 = Second item in the TCB which is xMPUSettings. */
        "                                       \n"
        " dmb                                   \n" /* Complete outstanding transfers before disabling MPU. */
        " ldr r0, =0xe000ed94                   \n" /* MPU_CTRL register. */
        " ldr r3, [r0]                          \n" /* Read the value of MPU_CTRL. */
        " bic r3, #1                            \n" /* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */
        " str r3, [r0]                          \n" /* Disable MPU. */
        "                                       \n"
        " ldr r0, =0xe000ed9c                   \n" /* Region Base Address register. */
        " ldmia r2!, {r4-r11}                   \n" /* Read 4 sets of MPU registers [MPU Region # 0 - 3]. */
        " stmia r0, {r4-r11}                    \n" /* Write 4 sets of MPU registers [MPU Region # 0 - 3]. */
        "                                       \n"
        #if ( configTOTAL_MPU_REGIONS == 16 )
            " ldmia r2!, {r4-r11}                   \n" /* Read 4 sets of MPU registers [MPU Region # 4 - 7]. */
            " stmia r0, {r4-r11}                    \n" /* Write 4 sets of MPU registers. [MPU Region # 4 - 7]. */
            " ldmia r2!, {r4-r11}                   \n" /* Read 4 sets of MPU registers [MPU Region # 8 - 11]. */
            " stmia r0, {r4-r11}                    \n" /* Write 4 sets of MPU registers. [MPU Region # 8 - 11]. */
        #endif /* configTOTAL_MPU_REGIONS == 16. */
        "                                       \n"
        " ldr r0, =0xe000ed94                   \n" /* MPU_CTRL register. */
        " ldr r3, [r0]                          \n" /* Read the value of MPU_CTRL. */
        " orr r3, #1                            \n" /* r3 = r3 | 1 i.e. Set the bit 0 in r3. */
        " str r3, [r0]                          \n" /* Enable MPU. */
        " dsb                                   \n" /* Force memory writes before continuing. */
        "                                       \n"
        /*---------- Restore Context. ---------- */
        " ldr r3, pxCurrentTCBConst             \n" /* r3 = pxCurrentTCBConst. */
        " ldr r2, [r3]                          \n" /* r2 = pxCurrentTCB. */
        " ldr r1, [r2]                          \n" /* r1 = Location of saved context in TCB. */
        "                                       \n"
        " ldmdb r1!, {r0, r4-r11}               \n" /* r0 contains PSP after the hardware had saved context. r4-r11 contain hardware saved context. */
        " msr psp, r0                           \n"
        " stmia r0!, {r4-r11}                   \n" /* Copy the hardware saved context on the task stack. */
        " ldmdb r1!, {r3-r11, lr}               \n" /* r3 contains CONTROL register. r4-r11 and LR restored. */
        " msr control, r3                       \n"

        " tst lr, #0x10                         \n"
        " ittt eq                               \n"
        " vldmdbeq r1!, {s0-s16}                \n" /* s0-s16 contain hardware saved FP context. */
        " vstmiaeq r0!, {s0-s16}                \n" /* Copy hardware saved FP context on the task stack. */
        " vldmdbeq r1!, {s16-s31}               \n" /* Restore s16-s31. */

        " str r1, [r2]                          \n" /* Save the location where the context should be saved next as the first member of TCB. */
        " bx lr                                 \n"
        "                                       \n"
        " .ltorg                                \n" /* Assemble the current literal pool to avoid offset-out-of-bound errors with lto. */
        " .align 4                              \n"
        " pxCurrentTCBConst: .word pxCurrentTCB \n"
        ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
    );
}
/*-----------------------------------------------------------*/

void xPortSysTickHandler( void )
{
    uint32_t ulDummy;

    ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
    traceISR_ENTER();
    {
        /* Increment the RTOS tick. */
        if( xTaskIncrementTick() != pdFALSE )
        {
            traceISR_EXIT_TO_SCHEDULER();
            /* Pend a context switch. */
            portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
        }
        else
        {
            traceISR_EXIT();
        }
    }
    portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
}
/*-----------------------------------------------------------*/

/*
 * Setup the systick timer to generate the tick interrupts at the required
 * frequency.
 */
__attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void )
{
    /* Stop and clear the SysTick. */
    portNVIC_SYSTICK_CTRL_REG = 0UL;
    portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;

    /* Configure SysTick to interrupt at the requested rate. */
    portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
    portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE );
}
/*-----------------------------------------------------------*/

/* This is a naked function. */
static void vPortEnableVFP( void )
{
    __asm volatile
    (
        "   ldr.w r0, =0xE000ED88       \n" /* The FPU enable bits are in the CPACR. */
        "   ldr r1, [r0]                \n"
        "                               \n"
        "   orr r1, r1, #( 0xf << 20 )  \n" /* Enable CP10 and CP11 coprocessors, then save back. */
        "   str r1, [r0]                \n"
        "   bx r14                      \n"
        "   .ltorg                      \n"
    );
}
/*-----------------------------------------------------------*/

static void prvSetupMPU( void )
{
    #if defined( __ARMCC_VERSION )

        /* Declaration when these variable are defined in code instead of being
         * exported from linker scripts. */
        extern uint32_t * __privileged_functions_start__;
        extern uint32_t * __privileged_functions_end__;
        extern uint32_t * __FLASH_segment_start__;
        extern uint32_t * __FLASH_segment_end__;
        extern uint32_t * __privileged_data_start__;
        extern uint32_t * __privileged_data_end__;
    #else
        /* Declaration when these variable are exported from linker scripts. */
        extern uint32_t __privileged_functions_start__[];
        extern uint32_t __privileged_functions_end__[];
        extern uint32_t __FLASH_segment_start__[];
        extern uint32_t __FLASH_segment_end__[];
        extern uint32_t __privileged_data_start__[];
        extern uint32_t __privileged_data_end__[];
    #endif /* if defined( __ARMCC_VERSION ) */

    /* The only permitted number of regions are 8 or 16. */
    configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) );

    /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */
    configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE );

    /* Check the expected MPU is present. */
    if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE )
    {
        /* First setup the unprivileged flash for unprivileged read only access. */
        portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __FLASH_segment_start__ ) | /* Base address. */
                                          ( portMPU_REGION_VALID ) |
                                          ( portUNPRIVILEGED_FLASH_REGION );

        portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_READ_ONLY ) |
                                       ( ( configTEX_S_C_B_FLASH & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) |
                                       ( prvGetMPURegionSizeSetting( ( uint32_t ) __FLASH_segment_end__ - ( uint32_t ) __FLASH_segment_start__ ) ) |
                                       ( portMPU_REGION_ENABLE );

        /* Setup the privileged flash for privileged only access.  This is where
         * the kernel code is placed. */
        portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __privileged_functions_start__ ) | /* Base address. */
                                          ( portMPU_REGION_VALID ) |
                                          ( portPRIVILEGED_FLASH_REGION );

        portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_PRIVILEGED_READ_ONLY ) |
                                       ( ( configTEX_S_C_B_FLASH & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) |
                                       ( prvGetMPURegionSizeSetting( ( uint32_t ) __privileged_functions_end__ - ( uint32_t ) __privileged_functions_start__ ) ) |
                                       ( portMPU_REGION_ENABLE );

        /* Setup the privileged data RAM region.  This is where the kernel data
         * is placed. */
        portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __privileged_data_start__ ) | /* Base address. */
                                          ( portMPU_REGION_VALID ) |
                                          ( portPRIVILEGED_RAM_REGION );

        portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_PRIVILEGED_READ_WRITE ) |
                                       ( portMPU_REGION_EXECUTE_NEVER ) |
                                       ( ( configTEX_S_C_B_SRAM & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) |
                                       prvGetMPURegionSizeSetting( ( uint32_t ) __privileged_data_end__ - ( uint32_t ) __privileged_data_start__ ) |
                                       ( portMPU_REGION_ENABLE );

        /* By default allow everything to access the general peripherals.  The
         * system peripherals and registers are protected. */
        portMPU_REGION_BASE_ADDRESS_REG = ( portPERIPHERALS_START_ADDRESS ) |
                                          ( portMPU_REGION_VALID ) |
                                          ( portGENERAL_PERIPHERALS_REGION );

        portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_READ_WRITE | portMPU_REGION_EXECUTE_NEVER ) |
                                       ( prvGetMPURegionSizeSetting( portPERIPHERALS_END_ADDRESS - portPERIPHERALS_START_ADDRESS ) ) |
                                       ( portMPU_REGION_ENABLE );

        /* Enable the memory fault exception. */
        portNVIC_SYS_CTRL_STATE_REG |= portNVIC_MEM_FAULT_ENABLE;

        /* Enable the MPU with the background region configured. */
        portMPU_CTRL_REG |= ( portMPU_ENABLE | portMPU_BACKGROUND_ENABLE );
    }
}
/*-----------------------------------------------------------*/

static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes )
{
    uint32_t ulRegionSize, ulReturnValue = 4;

    /* 32 is the smallest region size, 31 is the largest valid value for
     * ulReturnValue. */
    for( ulRegionSize = 32UL; ulReturnValue < 31UL; ( ulRegionSize <<= 1UL ) )
    {
        if( ulActualSizeInBytes <= ulRegionSize )
        {
            break;
        }
        else
        {
            ulReturnValue++;
        }
    }

    /* Shift the code by one before returning so it can be written directly
     * into the the correct bit position of the attribute register. */
    return( ulReturnValue << 1UL );
}
/*-----------------------------------------------------------*/

BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
{
    __asm volatile
    (
        "   mrs r0, control                         \n" /* r0 = CONTROL. */
        "   tst r0, #1                              \n" /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
        "   ite ne                                  \n"
        "   movne r0, #0                            \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
        "   moveq r0, #1                            \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
        "   bx lr                                   \n" /* Return. */
        "                                           \n"
        "   .align 4                                \n"
        ::: "r0", "memory"
    );
}
/*-----------------------------------------------------------*/

void vResetPrivilege( void ) /* __attribute__ (( naked )) */
{
    __asm volatile
    (
        "   mrs r0, control                         \n" /* r0 = CONTROL. */
        "   orr r0, #1                              \n" /* r0 = r0 | 1. */
        "   msr control, r0                         \n" /* CONTROL = r0. */
        "   bx lr                                   \n" /* Return to the caller. */
        ::: "r0", "memory"
    );
}
/*-----------------------------------------------------------*/

void vPortSwitchToUserMode( void )
{
    /* Load the current task's MPU settings from its TCB. */
    xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL );

    /* Mark the task as unprivileged. */
    xTaskMpuSettings->ulTaskFlags &= ( ~( portTASK_IS_PRIVILEGED_FLAG ) );

    /* Lower the processor's privilege level. */
    vResetPrivilege();
}
/*-----------------------------------------------------------*/

void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
                                const struct xMEMORY_REGION * const xRegions,
                                StackType_t * pxBottomOfStack,
                                configSTACK_DEPTH_TYPE uxStackDepth )
{
    #if defined( __ARMCC_VERSION )

        /* Declaration when these variable are defined in code instead of being
         * exported from linker scripts. */
        extern uint32_t * __SRAM_segment_start__;
        extern uint32_t * __SRAM_segment_end__;
        extern uint32_t * __privileged_data_start__;
        extern uint32_t * __privileged_data_end__;
    #else
        /* Declaration when these variable are exported from linker scripts. */
        extern uint32_t __SRAM_segment_start__[];
        extern uint32_t __SRAM_segment_end__[];
        extern uint32_t __privileged_data_start__[];
        extern uint32_t __privileged_data_end__[];
    #endif /* if defined( __ARMCC_VERSION ) */

    int32_t lIndex;
    uint32_t ul;

    if( xRegions == NULL )
    {
        /* No MPU regions are specified so allow access to all RAM. */
        xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress =
            ( ( uint32_t ) __SRAM_segment_start__ ) | /* Base address. */
            ( portMPU_REGION_VALID ) |
            ( portSTACK_REGION );                     /* Region number. */

        xMPUSettings->xRegion[ 0 ].ulRegionAttribute =
            ( portMPU_REGION_READ_WRITE ) |
            ( portMPU_REGION_EXECUTE_NEVER ) |
            ( ( configTEX_S_C_B_SRAM & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) |
            ( prvGetMPURegionSizeSetting( ( uint32_t ) __SRAM_segment_end__ - ( uint32_t ) __SRAM_segment_start__ ) ) |
            ( portMPU_REGION_ENABLE );

        xMPUSettings->xRegionSettings[ 0 ].ulRegionStartAddress = ( uint32_t ) __SRAM_segment_start__;
        xMPUSettings->xRegionSettings[ 0 ].ulRegionEndAddress = ( uint32_t ) __SRAM_segment_end__;
        xMPUSettings->xRegionSettings[ 0 ].ulRegionPermissions = ( tskMPU_READ_PERMISSION |
                                                                   tskMPU_WRITE_PERMISSION );

        /* Invalidate user configurable regions. */
        for( ul = 1UL; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ )
        {
            xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( ( ul - 1UL ) | portMPU_REGION_VALID );
            xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL;
            xMPUSettings->xRegionSettings[ ul ].ulRegionStartAddress = 0UL;
            xMPUSettings->xRegionSettings[ ul ].ulRegionEndAddress = 0UL;
            xMPUSettings->xRegionSettings[ ul ].ulRegionPermissions = 0UL;
        }
    }
    else
    {
        /* This function is called automatically when the task is created - in
         * which case the stack region parameters will be valid.  At all other
         * times the stack parameters will not be valid and it is assumed that the
         * stack region has already been configured. */
        if( uxStackDepth > 0 )
        {
            /* Define the region that allows access to the stack. */
            xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress =
                ( ( uint32_t ) pxBottomOfStack ) |
                ( portMPU_REGION_VALID ) |
                ( portSTACK_REGION ); /* Region number. */

            xMPUSettings->xRegion[ 0 ].ulRegionAttribute =
                ( portMPU_REGION_READ_WRITE ) |
                ( portMPU_REGION_EXECUTE_NEVER ) |
                ( prvGetMPURegionSizeSetting( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) ) |
                ( ( configTEX_S_C_B_SRAM & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) |
                ( portMPU_REGION_ENABLE );

            xMPUSettings->xRegionSettings[ 0 ].ulRegionStartAddress = ( uint32_t ) pxBottomOfStack;
            xMPUSettings->xRegionSettings[ 0 ].ulRegionEndAddress = ( uint32_t ) ( ( uint32_t ) ( pxBottomOfStack ) +
                                                                                   ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1UL );
            xMPUSettings->xRegionSettings[ 0 ].ulRegionPermissions = ( tskMPU_READ_PERMISSION |
                                                                       tskMPU_WRITE_PERMISSION );
        }

        lIndex = 0;

        for( ul = 1UL; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ )
        {
            if( ( xRegions[ lIndex ] ).ulLengthInBytes > 0UL )
            {
                /* Translate the generic region definition contained in
                 * xRegions into the CM4 specific MPU settings that are then
                 * stored in xMPUSettings. */
                xMPUSettings->xRegion[ ul ].ulRegionBaseAddress =
                    ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) |
                    ( portMPU_REGION_VALID ) |
                    ( ul - 1UL ); /* Region number. */

                xMPUSettings->xRegion[ ul ].ulRegionAttribute =
                    ( prvGetMPURegionSizeSetting( xRegions[ lIndex ].ulLengthInBytes ) ) |
                    ( xRegions[ lIndex ].ulParameters ) |
                    ( portMPU_REGION_ENABLE );

                xMPUSettings->xRegionSettings[ ul ].ulRegionStartAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress;
                xMPUSettings->xRegionSettings[ ul ].ulRegionEndAddress = ( uint32_t ) ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1UL );
                xMPUSettings->xRegionSettings[ ul ].ulRegionPermissions = 0UL;

                if( ( ( xRegions[ lIndex ].ulParameters & portMPU_REGION_READ_ONLY ) == portMPU_REGION_READ_ONLY ) ||
                    ( ( xRegions[ lIndex ].ulParameters & portMPU_REGION_PRIVILEGED_READ_WRITE_UNPRIV_READ_ONLY ) == portMPU_REGION_PRIVILEGED_READ_WRITE_UNPRIV_READ_ONLY ) )
                {
                    xMPUSettings->xRegionSettings[ ul ].ulRegionPermissions = tskMPU_READ_PERMISSION;
                }

                if( ( xRegions[ lIndex ].ulParameters & portMPU_REGION_READ_WRITE ) == portMPU_REGION_READ_WRITE )
                {
                    xMPUSettings->xRegionSettings[ ul ].ulRegionPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION );
                }
            }
            else
            {
                /* Invalidate the region. */
                xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( ( ul - 1UL ) | portMPU_REGION_VALID );
                xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL;
                xMPUSettings->xRegionSettings[ ul ].ulRegionStartAddress = 0UL;
                xMPUSettings->xRegionSettings[ ul ].ulRegionEndAddress = 0UL;
                xMPUSettings->xRegionSettings[ ul ].ulRegionPermissions = 0UL;
            }

            lIndex++;
        }
    }
}
/*-----------------------------------------------------------*/

#if ( configUSE_MPU_WRAPPERS_V1 == 0 )

    BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer,
                                                uint32_t ulBufferLength,
                                                uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */

    {
        uint32_t i, ulBufferStartAddress, ulBufferEndAddress;
        BaseType_t xAccessGranted = pdFALSE;
        const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */

        if( xSchedulerRunning == pdFALSE )
        {
            /* Grant access to all the kernel objects before the scheduler
             * is started. It is necessary because there is no task running
             * yet and therefore, we cannot use the permissions of any
             * task. */
            xAccessGranted = pdTRUE;
        }
        else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
        {
            xAccessGranted = pdTRUE;
        }
        else
        {
            if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE )
            {
                ulBufferStartAddress = ( uint32_t ) pvBuffer;
                ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL );

                for( i = 0; i < portTOTAL_NUM_REGIONS_IN_TCB; i++ )
                {
                    if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress,
                                                     xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress,
                                                     xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) &&
                        portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress,
                                                     xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress,
                                                     xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) &&
                        portIS_AUTHORIZED( ulAccessRequested, xTaskMpuSettings->xRegionSettings[ i ].ulRegionPermissions ) )
                    {
                        xAccessGranted = pdTRUE;
                        break;
                    }
                }
            }
        }

        return xAccessGranted;
    }

#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

#if ( configASSERT_DEFINED == 1 )

    void vPortValidateInterruptPriority( void )
    {
        uint32_t ulCurrentInterrupt;
        uint8_t ucCurrentPriority;

        /* Obtain the number of the currently executing interrupt. */
        __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" );

        /* Is the interrupt number a user defined interrupt? */
        if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
        {
            /* Look up the interrupt's priority. */
            ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
            configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
        }

        
        configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
    }

#endif /* configASSERT_DEFINED */
/*-----------------------------------------------------------*/

#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )

    void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
                                         int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
    {
        uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
        xMPU_SETTINGS * xTaskMpuSettings;

        ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
        ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );

        xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );

        xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
    }

#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/

#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )

    void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
                                          int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
    {
        uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
        xMPU_SETTINGS * xTaskMpuSettings;

        ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
        ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );

        xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );

        xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
    }

#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/

#if ( configUSE_MPU_WRAPPERS_V1 == 0 )

    #if ( configENABLE_ACCESS_CONTROL_LIST == 1 )

        BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
        {
            uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
            BaseType_t xAccessGranted = pdFALSE;
            const xMPU_SETTINGS * xTaskMpuSettings;

            if( xSchedulerRunning == pdFALSE )
            {
                /* Grant access to all the kernel objects before the scheduler
                 * is started. It is necessary because there is no task running
                 * yet and therefore, we cannot use the permissions of any
                 * task. */
                xAccessGranted = pdTRUE;
            }
            else
            {
                xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */

                ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
                ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );

                if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
                {
                    xAccessGranted = pdTRUE;
                }
                else
                {
                    if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
                    {
                        xAccessGranted = pdTRUE;
                    }
                }
            }

            return xAccessGranted;
        }

    #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */

        BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
        {
            ( void ) lInternalIndexOfKernelObject;

            /* If Access Control List feature is not used, all the tasks have
             * access to all the kernel objects. */
            return pdTRUE;
        }

    #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */

#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

And here is the portmacro.h:

#ifndef PORTMACRO_H
#define PORTMACRO_H


/* *INDENT-OFF* */
#ifdef __cplusplus
    extern "C" {
#endif
/* *INDENT-ON* */

/*-----------------------------------------------------------
 * Port specific definitions.
 *
 * The settings in this file configure FreeRTOS correctly for the
 * given hardware and compiler.
 *
 * These settings should not be altered.
 *-----------------------------------------------------------
 */

/* Type definitions. */
#define portCHAR          char
#define portFLOAT         float
#define portDOUBLE        double
#define portLONG          long
#define portSHORT         short
#define portSTACK_TYPE    uint32_t
#define portBASE_TYPE     long

typedef portSTACK_TYPE   StackType_t;
typedef long             BaseType_t;
typedef unsigned long    UBaseType_t;

#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
    typedef uint16_t     TickType_t;
    #define portMAX_DELAY              ( TickType_t ) 0xffff
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
    typedef uint32_t     TickType_t;
    #define portMAX_DELAY              ( TickType_t ) 0xffffffffUL

/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
 * not need to be guarded with a critical section. */
    #define portTICK_TYPE_IS_ATOMIC    1
#else
    #error "configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width."
#endif

/* Errata 837070 workaround must be enabled on Cortex-M7 r0p0
 * and r0p1 cores. */
#ifndef configENABLE_ERRATA_837070_WORKAROUND
    #define configENABLE_ERRATA_837070_WORKAROUND    0
#endif
/*-----------------------------------------------------------*/

/* MPU specific constants. */
#define portUSING_MPU_WRAPPERS                                   1
#define portPRIVILEGE_BIT                                        ( 0x80000000UL )

#define portMPU_REGION_READ_WRITE                                ( 0x03UL << 24UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY                      ( 0x05UL << 24UL )
#define portMPU_REGION_READ_ONLY                                 ( 0x06UL << 24UL )
#define portMPU_REGION_PRIVILEGED_READ_WRITE                     ( 0x01UL << 24UL )
#define portMPU_REGION_PRIVILEGED_READ_WRITE_UNPRIV_READ_ONLY    ( 0x02UL << 24UL )
#define portMPU_REGION_CACHEABLE_BUFFERABLE                      ( 0x07UL << 16UL )
#define portMPU_REGION_EXECUTE_NEVER                             ( 0x01UL << 28UL )

/* Location of the TEX,S,C,B bits in the MPU Region Attribute and Size
 * Register (RASR). */
#define portMPU_RASR_TEX_S_C_B_LOCATION                          ( 16UL )
#define portMPU_RASR_TEX_S_C_B_MASK                              ( 0x3FUL )

/* MPU settings that can be overriden in FreeRTOSConfig.h. */
#ifndef configTOTAL_MPU_REGIONS
    /* Define to 8 for backward compatibility. */
    #define configTOTAL_MPU_REGIONS    ( 8UL )
#endif

/* TEX, Shareable (S), Cacheable (C) and Bufferable (B) bits for flash
 * region. */
#ifndef configTEX_S_C_B_FLASH
    /* Default to TEX=000, S=1, C=1, B=1 for backward compatibility. */
    #define configTEX_S_C_B_FLASH    ( 0x07UL )
#endif

/* TEX, Shareable (S), Cacheable (C) and Bufferable (B) bits for RAM
 * region. */
#ifndef configTEX_S_C_B_SRAM
    /* Default to TEX=000, S=1, C=1, B=1 for backward compatibility. */
    #define configTEX_S_C_B_SRAM          ( 0x07UL )
#endif

#define portSTACK_REGION                  ( configTOTAL_MPU_REGIONS - 5UL )
#define portGENERAL_PERIPHERALS_REGION    ( configTOTAL_MPU_REGIONS - 4UL )
#define portUNPRIVILEGED_FLASH_REGION     ( configTOTAL_MPU_REGIONS - 3UL )
#define portPRIVILEGED_FLASH_REGION       ( configTOTAL_MPU_REGIONS - 2UL )
#define portPRIVILEGED_RAM_REGION         ( configTOTAL_MPU_REGIONS - 1UL )
#define portFIRST_CONFIGURABLE_REGION     ( 0UL )
#define portLAST_CONFIGURABLE_REGION      ( configTOTAL_MPU_REGIONS - 6UL )
#define portNUM_CONFIGURABLE_REGIONS      ( configTOTAL_MPU_REGIONS - 5UL )
#define portTOTAL_NUM_REGIONS_IN_TCB      ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus 1 to create space for the stack region. */

typedef struct MPU_REGION_REGISTERS
{
    uint32_t ulRegionBaseAddress;
    uint32_t ulRegionAttribute;
} xMPU_REGION_REGISTERS;

typedef struct MPU_REGION_SETTINGS
{
    uint32_t ulRegionStartAddress;
    uint32_t ulRegionEndAddress;
    uint32_t ulRegionPermissions;
} xMPU_REGION_SETTINGS;

#if ( configUSE_MPU_WRAPPERS_V1 == 0 )

    #ifndef configSYSTEM_CALL_STACK_SIZE
        #error "configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2."
    #endif

    typedef struct SYSTEM_CALL_STACK_INFO
    {
        uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ];
        uint32_t * pulSystemCallStack;
        uint32_t * pulTaskStack;
        uint32_t ulLinkRegisterAtSystemCallEntry;
    } xSYSTEM_CALL_STACK_INFO;

#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */

#define MAX_CONTEXT_SIZE                    ( 52 )

/* Size of an Access Control List (ACL) entry in bits. */
#define portACL_ENTRY_SIZE_BITS             ( 32U )

/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
#define portSTACK_FRAME_HAS_PADDING_FLAG    ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG         ( 1UL << 1UL )

typedef struct MPU_SETTINGS
{
    xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS_IN_TCB ];
    xMPU_REGION_SETTINGS xRegionSettings[ portTOTAL_NUM_REGIONS_IN_TCB ];
    uint32_t ulContext[ MAX_CONTEXT_SIZE ];
    uint32_t ulTaskFlags;

    #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
        xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
        #if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
            uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
        #endif
    #endif
} xMPU_SETTINGS;

/* Architecture specifics. */
#define portSTACK_GROWTH      ( -1 )
#define portTICK_PERIOD_MS    ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT    8
#define portDONT_DISCARD      __attribute__( ( used ) )
/*-----------------------------------------------------------*/

/* SVC numbers for various services. */
#define portSVC_START_SCHEDULER        100
#define portSVC_YIELD                  101
#define portSVC_RAISE_PRIVILEGE        102
#define portSVC_SYSTEM_CALL_EXIT       103

/* Scheduler utilities. */

#define portYIELD()    __asm volatile ( "   SVC %0  \n" ::"i" ( portSVC_YIELD ) : "memory" )
#define portYIELD_WITHIN_API()                          \
    {                                                   \
        /* Set a PendSV to request a context switch. */ \
        portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
                                                        \
        /* Barriers are normally not required but do ensure the code is completely \
         * within the specified behaviour for the architecture. */ \
        __asm volatile ( "dsb" ::: "memory" );                     \
        __asm volatile ( "isb" );                                  \
    }

#define portNVIC_INT_CTRL_REG     ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT    ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired )            \
    do                                                      \
    {                                                       \
        if( xSwitchRequired )                               \
        {                                                   \
            traceISR_EXIT_TO_SCHEDULER();                   \
            portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
        }                                                   \
        else                                                \
        {                                                   \
            traceISR_EXIT();                                \
        }                                                   \
    } while( 0 )
#define portYIELD_FROM_ISR( x )    portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/

/* Critical section management. */
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
#define portSET_INTERRUPT_MASK_FROM_ISR()         ulPortRaiseBASEPRI()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x )    vPortSetBASEPRI( x )
#define portDISABLE_INTERRUPTS()                  vPortRaiseBASEPRI()
#define portENABLE_INTERRUPTS()                   vPortSetBASEPRI( 0 )
#define portENTER_CRITICAL()                      vPortEnterCritical()
#define portEXIT_CRITICAL()                       vPortExitCritical()

/*-----------------------------------------------------------*/

/* Task function macros as described on the FreeRTOS.org WEB site.  These are
 * not necessary for to use this port.  They are defined so the common demo files
 * (which build with all the ports) will build. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters )    void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters )          void vFunction( void * pvParameters )
/*-----------------------------------------------------------*/

/* Architecture specific optimisations. */
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
    #define configUSE_PORT_OPTIMISED_TASK_SELECTION    1
#endif

#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1

/* Generic helper function. */
    __attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
    {
        uint8_t ucReturn;

        __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );

        return ucReturn;
    }

/* Check the configuration. */
    #if ( configMAX_PRIORITIES > 32 )
        #error "configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32.  It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice."
    #endif

/* Store/clear the ready priorities in a bit map. */
    #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities )    ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
    #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities )     ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )

/*-----------------------------------------------------------*/

    #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities )    uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )

#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */

/*-----------------------------------------------------------*/

#ifdef configASSERT
    void vPortValidateInterruptPriority( void );
    #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID()    vPortValidateInterruptPriority()
#endif

/* portNOP() is not required by this port. */
#define portNOP()

#define portINLINE              __inline

#ifndef portFORCE_INLINE
    #define portFORCE_INLINE    inline __attribute__( ( always_inline ) )
#endif
/*-----------------------------------------------------------*/

extern BaseType_t xIsPrivileged( void );
extern void vResetPrivilege( void );
extern void vPortSwitchToUserMode( void );

/**
 * @brief Checks whether or not the processor is privileged.
 *
 * @return 1 if the processor is already privileged, 0 otherwise.
 */
#define portIS_PRIVILEGED()          xIsPrivileged()

/**
 * @brief Raise an SVC request to raise privilege.
 */
#define portRAISE_PRIVILEGE()        __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );

/**
 * @brief Lowers the privilege level by setting the bit 0 of the CONTROL
 * register.
 */
#define portRESET_PRIVILEGE()        vResetPrivilege()

/**
 * @brief Make a task unprivileged.
 *
 * It must be called from privileged tasks only. Calling it from unprivileged
 * task will result in a memory protection fault.
 */
#define portSWITCH_TO_USER_MODE()    vPortSwitchToUserMode()
/*-----------------------------------------------------------*/

extern BaseType_t xPortIsTaskPrivileged( void );

/**
 * @brief Checks whether or not the calling task is privileged.
 *
 * @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
 */
#define portIS_TASK_PRIVILEGED()    xPortIsTaskPrivileged()
/*-----------------------------------------------------------*/

portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void )
{
    uint32_t ulCurrentInterrupt;
    BaseType_t xReturn;

    /* Obtain the number of the currently executing interrupt. */
    __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" );

    if( ulCurrentInterrupt == 0 )
    {
        xReturn = pdFALSE;
    }
    else
    {
        xReturn = pdTRUE;
    }

    return xReturn;
}

/*-----------------------------------------------------------*/

portFORCE_INLINE static void vPortRaiseBASEPRI( void )
{
    uint32_t ulNewBASEPRI;

    __asm volatile
    (
        "   mov %0, %1                                              \n"
        #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
            "   cpsid i                                             \n" /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
        #endif
        "   msr basepri, %0                                         \n"
        "   isb                                                     \n"
        "   dsb                                                     \n"
        #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
            "   cpsie i                                             \n" /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
        #endif
        : "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
    );
}

/*-----------------------------------------------------------*/

portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void )
{
    uint32_t ulOriginalBASEPRI, ulNewBASEPRI;

    __asm volatile
    (
        "   mrs %0, basepri                                         \n"
        "   mov %1, %2                                              \n"
        #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
            "   cpsid i                                             \n" /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
        #endif
        "   msr basepri, %1                                         \n"
        "   isb                                                     \n"
        "   dsb                                                     \n"
        #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
            "   cpsie i                                             \n" /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
        #endif
        : "=r" ( ulOriginalBASEPRI ), "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
    );

    /* This return will not be reached but is necessary to prevent compiler
     * warnings. */
    return ulOriginalBASEPRI;
}
/*-----------------------------------------------------------*/

portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
{
    __asm volatile
    (
        "   msr basepri, %0 " ::"r" ( ulNewMaskValue ) : "memory"
    );
}
/*-----------------------------------------------------------*/

#define portMEMORY_BARRIER()    __asm volatile ( "" ::: "memory" )

#ifndef configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY
    #warning "configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY is not defined. We recommend defining it to 1 in FreeRTOSConfig.h for better security. www.FreeRTOS.org/FreeRTOS-V10.3.x.html"
    #define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY    0
#endif
/*-----------------------------------------------------------*/

/* *INDENT-OFF* */
    #ifdef __cplusplus
        }
    #endif
/* *INDENT-ON* */

#endif /* PORTMACRO_H */

Did you try the linker script I mentioned?

For sharing code, may be put your complete code in a GitHub repo and share the link.

Yes I have tried the linker script you mentioned and it didn’t work. Here is the link of my repo: GitHub - myriamKC/Test_FreeRTOS

Thank you for sharing the code. Would you please share the build instructions also.

The build instruction is : make build_and_flash_demo_freertos_tikee_rev_A_to_L

This repo is not accessible. Either make it public or grant me access. My GH username is aggarg.

I think it will be okay now. This is the link of the repo: https://github.com/myriamKC/Test_FreeRTOS

Try the following linker script:

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
SEARCH_DIR(.)
SEARCH_DIR(common/linker_scripts/)

/* Memory Spaces Definitions */
MEMORY
{
  flash (rx)  : ORIGIN = 0x00400000, LENGTH = 256K - 2 /* -2 for CRC16 */
  /*rom (rx)  : ORIGIN = 0x00410000, LENGTH = 64K -- reserved for bootloader upgrade*/
  ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
}

/* Initial 64K Flash is used to store kernel functions and
 * initial 512 bytes of RAM is used to store kernel data. */
__privileged_functions_region_size__  = 64K;
__privileged_data_region_size__       = 32K;

__FLASH_segment_start__               = ORIGIN( flash );
__FLASH_segment_end__                 = __FLASH_segment_start__ + 256K;

__SRAM_segment_start__                = ORIGIN( ram );
__SRAM_segment_end__                  = __SRAM_segment_start__ + 64K - 4;

__privileged_functions_start__        = __FLASH_segment_start__;
__privileged_functions_end__          = __FLASH_segment_start__ + __privileged_functions_region_size__;

__privileged_data_start__             = __SRAM_segment_start__;
__privileged_data_end__               = __SRAM_segment_start__ + __privileged_data_region_size__;


/* The stack size used by the application. NOTE: you need to adjust according to your application. */
__stack_size__ = DEFINED(__stack_size__) ? __stack_size__ : 0x4000; /* 16ko*/
__ram_end__ = ORIGIN(ram) + LENGTH(ram) - 4;

/* Section Definitions */
SECTIONS
{
    /* The startup code and FreeRTOS kernel code are placed into privileged
     * flash. */
    .privileged_functions :
    {
        . = ALIGN(4);
        _sfixed = .;
        KEEP(*(.vectors .vectors.*))
        KEEP(*(.fw_infos_section))
        . = ALIGN(4);
        *(privileged_functions)
        . = ALIGN(4);
        /* FILL(0xDEAD); Petit doute ici*/
        /* Ensure that un-privileged code is placed after the region reserved
         * for privileged kernel code. */
        /* Note that dot (.) actually refers to the byte offset from the start
         * of the current section (.privileged_functions in this case). As a
         * result, setting dot (.) to a value sets the size of the section. */
        . = __privileged_functions_region_size__;
    } >flash

    .text :
    {
        . = ALIGN(4);
        __syscalls_flash_start__ = .;
        *(freertos_system_calls)
        __syscalls_flash_end__ = .;
        . = ALIGN(4);
        *(.text .text.* .gnu.linkonce.t.*)
        *(.glue_7t) *(.glue_7)
        *(.rodata .rodata* .gnu.linkonce.r.*)
        *(.ARM.extab* .gnu.linkonce.armextab.*)

        KEEP(*(.fill_release_revM))

        /* Support C constructors, and C destructors in both user code
           and the C library. This also provides support for C++ code. */
        . = ALIGN(4);
        KEEP(*(.init))
        . = ALIGN(4);
        __preinit_array_start = .;
        KEEP (*(.preinit_array))
        __preinit_array_end = .;

        . = ALIGN(4);
        __init_array_start = .;
        KEEP (*(SORT(.init_array.*)))
        KEEP (*(.init_array))
        __init_array_end = .;

        . = ALIGN(0x4);
        KEEP (*crtbegin.o(.ctors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
        KEEP (*(SORT(.ctors.*)))
        KEEP (*crtend.o(.ctors))

        . = ALIGN(4);
        KEEP(*(.fini))

        . = ALIGN(4);
        __fini_array_start = .;
        KEEP (*(.fini_array))
        KEEP (*(SORT(.fini_array.*)))
        __fini_array_end = .;

        KEEP (*crtbegin.o(.dtors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
        KEEP (*(SORT(.dtors.*)))
        KEEP (*crtend.o(.dtors))

        . = ALIGN(4);
        _efixed = .;            /* End of text section */
    } > flash

    /* .ARM.exidx is sorted, so has to go in its own output section.  */
    PROVIDE_HIDDEN (__exidx_start = .);
    .ARM.exidx :
    {
      *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > flash
    PROVIDE_HIDDEN (__exidx_end = .);

    . = ALIGN(4);
    _etext = .;

    .relocate :
    {
        . = ALIGN(4);
        _srelocate = .;
        *(.ramfunc .ramfunc.*);
        *(.data .data.*);
        . = ALIGN(4);
    } > ram AT> flash


    /* FreeRTOS kernel data. */
    .privileged_data :
    {
        . = ALIGN(4);
        *(privileged_data)
        . = ALIGN(4);
        _erelocate = .;
        /* FILL(0xDEAD); */
        /* Ensure that un-privileged data is placed after the region reserved
         * for privileged kernel data. */
        /* Note that dot (.) actually refers to the byte offset from the start
         * of the current section (.privileged_data in this case). As a result,
         * setting dot (.) to a value sets the size of the section. */
        . = __privileged_data_region_size__;
    } >ram AT> flash


    /* .bss section which is used for uninitialized data */
    .bss (NOLOAD) :
    {
        . = ALIGN(4);
        _sbss = . ;
        _szero = .;
        *(.bss .bss.*)
        *(COMMON)
        . = ALIGN(4);
        _ebss = . ;
        _ezero = .;
    } > ram

    /* stack section */
    .stack (NOLOAD):
    {
        . = ALIGN(8);
        _sstack = .;
        . = . + __stack_size__;
        . = ALIGN(8);
        _estack = .;
    } > ram

    . = ALIGN(4);
    _end = . ;
}

Now the event group are being created, thank you. But the scheduler is not working. Do you have an idea?