Updates to CM3_MPU GCC port

- System calls are now only allowed from kernel code. This change can be turned on
  or off using configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY.
- MPU is disabled before reprogramming it and enabled afterwards to be compliant
  with ARM recommendations.
diff --git a/FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/port.c b/FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/port.c
index 25eb413..3125009 100644
--- a/FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/port.c
+++ b/FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/port.c
@@ -30,8 +30,8 @@
  *----------------------------------------------------------*/

 

 /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining

-all the API functions to use the MPU wrappers.  That should only be done when

-task.h is included from an application file. */

+ * all the API functions to use the MPU wrappers.  That should only be done when

+ * task.h is included from an application file. */

 #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE

 

 /* Scheduler includes. */

@@ -46,7 +46,7 @@
 	#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. */

+	 * as the core. */

 	#define portNVIC_SYSTICK_CLK	( 0 )

 #endif

 

@@ -86,21 +86,22 @@
 #define portINITIAL_CONTROL_IF_PRIVILEGED		( 0x02 )

 

 /* 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 )

+#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 )

 

 /* Offsets in the stack to the parameters when inside the SVC handler. */

 #define portOFFSET_TO_PC						( 6 )

 

 /* 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 )

+ * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */

+#define portSTART_ADDRESS_MASK					( ( StackType_t ) 0xfffffffeUL )

+/*-----------------------------------------------------------*/

 

 /*

  * Configure a number of standard MPU regions that are used by all tasks.

@@ -171,8 +172,8 @@
 /*-----------------------------------------------------------*/

 

 /* Each task maintains its own interrupt status in the critical nesting

-variable.  Note this is not saved as part of the task context as context

-switches can only occur when uxCriticalNesting is zero. */

+ * variable.  Note this is not saved as part of the task context as context

+ * switches can only occur when uxCriticalNesting is zero. */

 static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;

 

 /*

@@ -185,7 +186,6 @@
 	 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 */

-

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

 

 /*

@@ -194,7 +194,7 @@
 StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged )

 {

 	/* Simulate the stack frame as it would be created by a context switch

-	interrupt. */

+	 * interrupt. */

 	pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */

 	*pxTopOfStack = portINITIAL_XPSR;	/* xPSR */

 	pxTopOfStack--;

@@ -240,10 +240,25 @@
 static void prvSVCHandler(	uint32_t *pulParam )

 {

 uint8_t ucSVCNumber;

+uint32_t ulPC;

+#if( 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( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */

 

-	/* The stack contains: r0, r1, r2, r3, r12, r14, the return address and

-	xPSR.  The first argument (r0) is pulParam[ 0 ]. */

-	ucSVCNumber = ( ( uint8_t * ) pulParam[ portOFFSET_TO_PC ] )[ -2 ];

+	/* 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	:	portNVIC_SYSPRI1_REG |= portNVIC_SVC_PRI;

@@ -252,14 +267,32 @@
 

 		case portSVC_YIELD				:	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. */

+											 * but do ensure the code is completely

+											 * within the specified behaviour for the

+											 * architecture. */

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

 											__asm volatile( "isb" );

 

 											break;

 

+

+	#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

 		case portSVC_RAISE_PRIVILEGE	:	__asm volatile

 											(

 												"	mrs r1, control		\n" /* Obtain current control value. */

@@ -268,6 +301,7 @@
 												::: "r1", "memory"

 											);

 											break;

+	#endif /* #if( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */

 

 		default							:	/* Unknown SVC call. */

 											break;

@@ -287,9 +321,23 @@
 		"	ldr r1, [r3]					\n"

 		"	ldr r0, [r1]					\n" /* The first item in the TCB is the task top of stack. */

 		"	add r1, r1, #4					\n" /* Move onto the second item in the TCB... */

+		"									\n"

+		"	dmb								\n" /* Complete outstanding transfers before disabling MPU. */

+		"	ldr r2, =0xe000ed94				\n" /* MPU_CTRL register. */

+		"	ldr r3, [r2]					\n" /* Read the value of MPU_CTRL. */

+		"	bic r3, #1						\n" /* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */

+		"	str r3, [r2]					\n" /* Disable MPU. */

+		"									\n"

 		"	ldr r2, =0xe000ed9c				\n" /* Region Base Address register. */

 		"	ldmia r1!, {r4-r11}				\n" /* Read 4 sets of MPU registers. */

 		"	stmia r2!, {r4-r11}				\n" /* Write 4 sets of MPU registers. */

+		"									\n"

+		"	ldr r2, =0xe000ed94				\n" /* MPU_CTRL register. */

+		"	ldr r3, [r2]					\n" /* Read the value of MPU_CTRL. */

+		"	orr r3, #1						\n" /* r3 = r3 | 1 i.e. Set the bit 0 in r3. */

+		"	str r3, [r2]					\n" /* Enable MPU. */

+		"	dsb								\n" /* Force memory writes before continuing. */

+		"									\n"

 		"	ldmia r0!, {r3, r4-r11}			\n" /* Pop the registers that are not automatically saved on exception entry. */

 		"	msr control, r3					\n"

 		"	msr psp, r0						\n" /* Restore the task stack pointer. */

@@ -310,7 +358,7 @@
 BaseType_t xPortStartScheduler( void )

 {

 	/* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0.  See

-	http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */

+	 * http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */

 	configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) );

 

 	#if( configASSERT_DEFINED == 1 )

@@ -320,15 +368,15 @@
 		volatile uint8_t ucMaxPriorityValue;

 

 		/* Determine the maximum priority from which ISR safe FreeRTOS API

-		functions can be called.  ISR safe functions are those that end in

-		"FromISR".  FreeRTOS maintains separate thread and ISR API functions to

-		ensure interrupt entry is as fast and simple as possible.

+		 * functions can be called.  ISR safe functions are those that end in

+		 * "FromISR".  FreeRTOS maintains separate thread and ISR API functions

+		 * to ensure interrupt entry is as fast and simple as possible.

 

-		Save the interrupt priority value that is about to be clobbered. */

+		 * Save the interrupt priority value that is about to be clobbered. */

 		ulOriginalPriority = *pucFirstUserPriorityRegister;

 

 		/* Determine the number of priority bits available.  First write to all

-		possible bits. */

+		 * possible bits. */

 		*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;

 

 		/* Read the value back to see how many bits stuck. */

@@ -338,7 +386,7 @@
 		ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;

 

 		/* Calculate the maximum acceptable priority group value for the number

-		of bits read back. */

+		 * of bits read back. */

 		ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;

 		while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )

 		{

@@ -349,8 +397,8 @@
 		#ifdef __NVIC_PRIO_BITS

 		{

 			/* Check the CMSIS configuration that defines the number of

-			priority bits matches the number of priority bits actually queried

-			from the hardware. */

+			 * priority bits matches the number of priority bits actually queried

+			 * from the hardware. */

 			configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );

 		}

 		#endif

@@ -358,26 +406,26 @@
 		#ifdef configPRIO_BITS

 		{

 			/* Check the FreeRTOS configuration that defines the number of

-			priority bits matches the number of priority bits actually queried

-			from the hardware. */

+			 * priority bits matches the number of priority bits actually queried

+			 * from the hardware. */

 			configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );

 		}

 		#endif

 

 		/* Shift the priority group value back to its position within the AIRCR

-		register. */

+		 * register. */

 		ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;

 		ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;

 

 		/* Restore the clobbered interrupt priority register to its original

-		value. */

+		 * value. */

 		*pucFirstUserPriorityRegister = ulOriginalPriority;

 	}

 	#endif /* conifgASSERT_DEFINED */

 

 	/* Make PendSV and SysTick the same priority as the kernel, and the SVC

-	handler higher priority so it can be used to exit a critical section (where

-	lower priorities are masked). */

+	 * handler higher priority so it can be used to exit a critical section (where

+	 * lower priorities are masked). */

 	portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;

 	portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;

 

@@ -385,7 +433,7 @@
 	prvSetupMPU();

 

 	/* Start the timer that generates the tick ISR.  Interrupts are disabled

-	here already. */

+	 * here already. */

 	vPortSetupTimerInterrupt();

 

 	/* Initialise the critical nesting count ready for the first task. */

@@ -413,7 +461,7 @@
 void vPortEndScheduler( void )

 {

 	/* Not implemented in ports where there is nothing to return to.

-	Artificially force an assert. */

+	 * Artificially force an assert. */

 	configASSERT( uxCriticalNesting == 1000UL );

 }

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

@@ -471,9 +519,23 @@
 		"	ldr r1, [r3]						\n"

 		"	ldr r0, [r1]						\n" /* The first item in the TCB is the task top of stack. */

 		"	add r1, r1, #4						\n" /* Move onto the second item in the TCB... */

+		"										\n"

+		"	dmb									\n" /* Complete outstanding transfers before disabling MPU. */

+		"	ldr r2, =0xe000ed94					\n" /* MPU_CTRL register. */

+		"	ldr r3, [r2]						\n" /* Read the value of MPU_CTRL. */

+		"	bic r3, #1							\n" /* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */

+		"	str r3, [r2]						\n" /* Disable MPU. */

+		"										\n"

 		"	ldr r2, =0xe000ed9c					\n" /* Region Base Address register. */

 		"	ldmia r1!, {r4-r11}					\n" /* Read 4 sets of MPU registers. */

 		"	stmia r2!, {r4-r11}					\n" /* Write 4 sets of MPU registers. */

+		"										\n"

+		"	ldr r2, =0xe000ed94					\n" /* MPU_CTRL register. */

+		"	ldr r3, [r2]						\n" /* Read the value of MPU_CTRL. */

+		"	orr r3, #1							\n" /* r3 = r3 | 1 i.e. Set the bit 0 in r3. */

+		"	str r3, [r2]						\n" /* Enable MPU. */

+		"	dsb									\n" /* Force memory writes before continuing. */

+		"										\n"

 		"	ldmia r0!, {r3, r4-r11}				\n" /* Pop the registers that are not automatically saved on exception entry. */

 		"	msr control, r3						\n"

 		"										\n"

@@ -542,8 +604,8 @@
 										( portMPU_REGION_ENABLE );

 

 		/* Setup the first 16K for privileged only access (even though less

-		than 10K is actually being used).  This is where the kernel code is

-		placed. */

+		 * than 10K is actually being used).  This is where the kernel code is

+		 * placed. */

 		portMPU_REGION_BASE_ADDRESS_REG =	( ( uint32_t ) __FLASH_segment_start__ ) | /* Base address. */

 											( portMPU_REGION_VALID ) |

 											( portPRIVILEGED_FLASH_REGION );

@@ -554,7 +616,7 @@
 										( portMPU_REGION_ENABLE );

 

 		/* Setup the privileged data RAM region.  This is where the kernel data

-		is placed. */

+		 * is placed. */

 		portMPU_REGION_BASE_ADDRESS_REG =	( ( uint32_t ) __privileged_data_start__ ) | /* Base address. */

 											( portMPU_REGION_VALID ) |

 											( portPRIVILEGED_RAM_REGION );

@@ -565,7 +627,7 @@
 										( portMPU_REGION_ENABLE );

 

 		/* By default allow everything to access the general peripherals.  The

-		system peripherals and registers are protected. */

+		 * system peripherals and registers are protected. */

 		portMPU_REGION_BASE_ADDRESS_REG =	( portPERIPHERALS_START_ADDRESS ) |

 											( portMPU_REGION_VALID ) |

 											( portGENERAL_PERIPHERALS_REGION );

@@ -588,7 +650,7 @@
 uint32_t ulRegionSize, ulReturnValue = 4;

 

 	/* 32 is the smallest region size, 31 is the largest valid value for

-	ulReturnValue. */

+	 * ulReturnValue. */

 	for( ulRegionSize = 32UL; ulReturnValue < 31UL; ( ulRegionSize <<= 1UL ) )

 	{

 		if( ulActualSizeInBytes <= ulRegionSize )

@@ -602,7 +664,7 @@
 	}

 

 	/* Shift the code by one before returning so it can be written directly

-	into the the correct bit position of the attribute register. */

+	 * into the the correct bit position of the attribute register. */

 	return ( ulReturnValue << 1UL );

 }

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

@@ -661,7 +723,7 @@
 				( portMPU_REGION_ENABLE );

 

 		/* Re-instate the privileged only RAM region as xRegion[ 0 ] will have

-		just removed the privileged only parameters. */

+		 * just removed the privileged only parameters. */

 		xMPUSettings->xRegion[ 1 ].ulRegionBaseAddress =

 				( ( uint32_t ) __privileged_data_start__ ) | /* Base address. */

 				( portMPU_REGION_VALID ) |

@@ -683,9 +745,9 @@
 	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. */

+		 * 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( ulStackDepth > 0 )

 		{

 			/* Define the region that allows access to the stack. */

@@ -708,8 +770,8 @@
 			if( ( xRegions[ lIndex ] ).ulLengthInBytes > 0UL )

 			{

 				/* Translate the generic region definition contained in

-				xRegions into the CM3 specific MPU settings that are then

-				stored in xMPUSettings. */

+				 * xRegions into the CM3 specific MPU settings that are then

+				 * stored in xMPUSettings. */

 				xMPUSettings->xRegion[ ul ].ulRegionBaseAddress =

 						( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) |

 						( portMPU_REGION_VALID ) |

@@ -750,48 +812,46 @@
 			ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];

 

 			/* The following assertion will fail if a service routine (ISR) for

-			an interrupt that has been assigned a priority above

-			configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API

-			function.  ISR safe FreeRTOS API functions must *only* be called

-			from interrupts that have been assigned a priority at or below

-			configMAX_SYSCALL_INTERRUPT_PRIORITY.

+			 * an interrupt that has been assigned a priority above

+			 * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API

+			 * function.  ISR safe FreeRTOS API functions must *only* be called

+			 * from interrupts that have been assigned a priority at or below

+			 * configMAX_SYSCALL_INTERRUPT_PRIORITY.

 

-			Numerically low interrupt priority numbers represent logically high

-			interrupt priorities, therefore the priority of the interrupt must

-			be set to a value equal to or numerically *higher* than

-			configMAX_SYSCALL_INTERRUPT_PRIORITY.

+			 * Numerically low interrupt priority numbers represent logically high

+			 * interrupt priorities, therefore the priority of the interrupt must

+			 * be set to a value equal to or numerically *higher* than

+			 * configMAX_SYSCALL_INTERRUPT_PRIORITY.

 

-			Interrupts that	use the FreeRTOS API must not be left at their

-			default priority of	zero as that is the highest possible priority,

-			which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,

-			and	therefore also guaranteed to be invalid.

+			 * Interrupts that	use the FreeRTOS API must not be left at their

+			 * default priority of	zero as that is the highest possible priority,

+			 * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,

+			 * and	therefore also guaranteed to be invalid.

 

-			FreeRTOS maintains separate thread and ISR API functions to ensure

-			interrupt entry is as fast and simple as possible.

+			 * FreeRTOS maintains separate thread and ISR API functions to ensure

+			 * interrupt entry is as fast and simple as possible.

 

-			The following links provide detailed information:

-			http://www.freertos.org/RTOS-Cortex-M3-M4.html

-			http://www.freertos.org/FAQHelp.html */

+			 * The following links provide detailed information:

+			 * http://www.freertos.org/RTOS-Cortex-M3-M4.html

+			 * http://www.freertos.org/FAQHelp.html */

 			configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );

 		}

 

 		/* Priority grouping:  The interrupt controller (NVIC) allows the bits

-		that define each interrupt's priority to be split between bits that

-		define the interrupt's pre-emption priority bits and bits that define

-		the interrupt's sub-priority.  For simplicity all bits must be defined

-		to be pre-emption priority bits.  The following assertion will fail if

-		this is not the case (if some bits represent a sub-priority).

+		 * that define each interrupt's priority to be split between bits that

+		 * define the interrupt's pre-emption priority bits and bits that define

+		 * the interrupt's sub-priority.  For simplicity all bits must be defined

+		 * to be pre-emption priority bits.  The following assertion will fail if

+		 * this is not the case (if some bits represent a sub-priority).

 

-		If the application only uses CMSIS libraries for interrupt

-		configuration then the correct setting can be achieved on all Cortex-M

-		devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the

-		scheduler.  Note however that some vendor specific peripheral libraries

-		assume a non-zero priority group setting, in which cases using a value

-		of zero will result in unpredicable behaviour. */

+		 * If the application only uses CMSIS libraries for interrupt

+		 * configuration then the correct setting can be achieved on all Cortex-M

+		 * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the

+		 * scheduler.  Note however that some vendor specific peripheral libraries

+		 * assume a non-zero priority group setting, in which cases using a value

+		 * of zero will result in unpredicable behaviour. */

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

 	}

 

 #endif /* configASSERT_DEFINED */

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

-

-

diff --git a/FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/portmacro.h b/FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/portmacro.h
index ff8ddb6..415255f 100644
--- a/FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/portmacro.h
+++ b/FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/portmacro.h
@@ -73,12 +73,13 @@
 #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_CACHEABLE_BUFFERABLE		( 0x07UL << 16UL )

-#define portMPU_REGION_EXECUTE_NEVER			( 0x01UL << 28UL )

+#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 )

 

 #define portUNPRIVILEGED_FLASH_REGION		( 0UL )

 #define portPRIVILEGED_FLASH_REGION			( 1UL )

@@ -293,6 +294,11 @@
 

 #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."

+	#define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 0

+#endif

+/*-----------------------------------------------------------*/

 #ifdef __cplusplus

 }

 #endif