|
|
|
@ -194,7 +194,7 @@ extern void vPortRestoreContextOfFirstTask( void ) PRIVILEGED_FUNCTION;
|
|
|
|
|
/**
|
|
|
|
|
* @brief Enter critical section.
|
|
|
|
|
*/
|
|
|
|
|
#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
|
|
|
|
|
#if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
|
|
|
|
|
void vPortEnterCritical( void ) FREERTOS_SYSTEM_CALL;
|
|
|
|
|
#else
|
|
|
|
|
void vPortEnterCritical( void ) PRIVILEGED_FUNCTION;
|
|
|
|
@ -203,7 +203,7 @@ extern void vPortRestoreContextOfFirstTask( void ) PRIVILEGED_FUNCTION;
|
|
|
|
|
/**
|
|
|
|
|
* @brief Exit from critical section.
|
|
|
|
|
*/
|
|
|
|
|
#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
|
|
|
|
|
#if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
|
|
|
|
|
void vPortExitCritical( void ) FREERTOS_SYSTEM_CALL;
|
|
|
|
|
#else
|
|
|
|
|
void vPortExitCritical( void ) PRIVILEGED_FUNCTION;
|
|
|
|
@ -316,9 +316,9 @@ void vPortSVCHandler_C( uint32_t * pulParam )
|
|
|
|
|
{
|
|
|
|
|
__asm volatile
|
|
|
|
|
(
|
|
|
|
|
" mrs r1, control \n"/* Obtain current control value. */
|
|
|
|
|
" bic r1, r1, #1 \n"/* Set privilege bit. */
|
|
|
|
|
" msr control, r1 \n"/* Write back new control value. */
|
|
|
|
|
" mrs r1, control \n" /* Obtain current control value. */
|
|
|
|
|
" bic r1, r1, #1 \n" /* Set privilege bit. */
|
|
|
|
|
" msr control, r1 \n" /* Write back new control value. */
|
|
|
|
|
::: "r1", "memory"
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
@ -328,9 +328,9 @@ void vPortSVCHandler_C( uint32_t * pulParam )
|
|
|
|
|
case portSVC_RAISE_PRIVILEGE:
|
|
|
|
|
__asm volatile
|
|
|
|
|
(
|
|
|
|
|
" mrs r1, control \n"/* Obtain current control value. */
|
|
|
|
|
" bic r1, r1, #1 \n"/* Set privilege bit. */
|
|
|
|
|
" msr control, r1 \n"/* Write back new control value. */
|
|
|
|
|
" mrs r1, control \n" /* Obtain current control value. */
|
|
|
|
|
" bic r1, r1, #1 \n" /* Set privilege bit. */
|
|
|
|
|
" msr control, r1 \n" /* Write back new control value. */
|
|
|
|
|
::: "r1", "memory"
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
@ -352,6 +352,7 @@ BaseType_t xPortStartScheduler( void )
|
|
|
|
|
#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. */
|
|
|
|
@ -360,74 +361,101 @@ BaseType_t xPortStartScheduler( void )
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if ( configASSERT_DEFINED == 1 )
|
|
|
|
|
{
|
|
|
|
|
volatile uint32_t ulOriginalPriority;
|
|
|
|
|
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
|
|
|
|
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.
|
|
|
|
|
*
|
|
|
|
|
* Save the interrupt priority value that is about to be clobbered. */
|
|
|
|
|
ulOriginalPriority = *pucFirstUserPriorityRegister;
|
|
|
|
|
{
|
|
|
|
|
volatile uint32_t ulOriginalPriority;
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
/* 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.
|
|
|
|
|
*
|
|
|
|
|
* 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. */
|
|
|
|
|
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
|
|
|
|
/* 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;
|
|
|
|
|
/* 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;
|
|
|
|
|
/* Use the same mask on the maximum system call priority. */
|
|
|
|
|
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
|
|
|
|
|
|
|
|
|
/* Check that the maximum system call priority is nonzero after
|
|
|
|
|
* accounting for the number of priority bits supported by the
|
|
|
|
|
* hardware. A priority of 0 is invalid because setting the BASEPRI
|
|
|
|
|
* register to 0 unmasks all interrupts, and interrupts with priority 0
|
|
|
|
|
* cannot be masked using BASEPRI.
|
|
|
|
|
* See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
|
|
|
|
|
configASSERT( ucMaxSysCallPriority );
|
|
|
|
|
/* Check that the maximum system call priority is nonzero after
|
|
|
|
|
* accounting for the number of priority bits supported by the
|
|
|
|
|
* hardware. A priority of 0 is invalid because setting the BASEPRI
|
|
|
|
|
* register to 0 unmasks all interrupts, and interrupts with priority 0
|
|
|
|
|
* cannot be masked using BASEPRI.
|
|
|
|
|
* See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
|
|
|
|
|
configASSERT( ucMaxSysCallPriority );
|
|
|
|
|
|
|
|
|
|
/* Calculate the maximum acceptable priority group value for the number
|
|
|
|
|
* of bits read back. */
|
|
|
|
|
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
|
|
|
|
|
/* Calculate the maximum acceptable priority group value for the number
|
|
|
|
|
* of bits read back. */
|
|
|
|
|
|
|
|
|
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
|
|
|
|
{
|
|
|
|
|
ulMaxPRIGROUPValue--;
|
|
|
|
|
ucMaxPriorityValue <<= ( uint8_t ) 0x01;
|
|
|
|
|
}
|
|
|
|
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
|
|
|
|
{
|
|
|
|
|
ulImplementedPrioBits++;
|
|
|
|
|
ucMaxPriorityValue <<= ( uint8_t ) 0x01;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#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. */
|
|
|
|
|
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#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. */
|
|
|
|
|
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* 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 = ulOriginalPriority;
|
|
|
|
|
if( ulImplementedPrioBits == 8 )
|
|
|
|
|
{
|
|
|
|
|
/* When the hardware implements 8 priority bits, there is no way for
|
|
|
|
|
* the software to configure PRIGROUP to not have sub-priorities. As
|
|
|
|
|
* a result, the least significant bit is always used for sub-priority
|
|
|
|
|
* and there are 128 preemption priorities and 2 sub-priorities.
|
|
|
|
|
*
|
|
|
|
|
* This may cause some confusion in some cases - for example, if
|
|
|
|
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
|
|
|
|
|
* priority interrupts will be masked in Critical Sections as those
|
|
|
|
|
* are at the same preemption priority. This may appear confusing as
|
|
|
|
|
* 4 is higher (numerically lower) priority than
|
|
|
|
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
|
|
|
|
|
* have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
|
|
|
|
|
* to 4, this confusion does not happen and the behaviour remains the same.
|
|
|
|
|
*
|
|
|
|
|
* The following assert ensures that the sub-priority bit in the
|
|
|
|
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
|
|
|
|
|
* confusion. */
|
|
|
|
|
configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
|
|
|
|
|
ulMaxPRIGROUPValue = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#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. */
|
|
|
|
|
configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS );
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#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. */
|
|
|
|
|
configASSERT( ulImplementedPrioBits == configPRIO_BITS );
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* 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 = ulOriginalPriority;
|
|
|
|
|
}
|
|
|
|
|
#endif /* configASSERT_DEFINED */
|
|
|
|
|
|
|
|
|
|
/* Make PendSV and SysTick the lowest priority interrupts. */
|
|
|
|
@ -468,32 +496,49 @@ void vPortEndScheduler( void )
|
|
|
|
|
|
|
|
|
|
void vPortEnterCritical( void )
|
|
|
|
|
{
|
|
|
|
|
#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
|
|
|
|
|
if( portIS_PRIVILEGED() == pdFALSE )
|
|
|
|
|
{
|
|
|
|
|
portRAISE_PRIVILEGE();
|
|
|
|
|
portMEMORY_BARRIER();
|
|
|
|
|
#if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
|
|
|
|
|
if( portIS_PRIVILEGED() == pdFALSE )
|
|
|
|
|
{
|
|
|
|
|
portRAISE_PRIVILEGE();
|
|
|
|
|
portMEMORY_BARRIER();
|
|
|
|
|
|
|
|
|
|
portDISABLE_INTERRUPTS();
|
|
|
|
|
uxCriticalNesting++;
|
|
|
|
|
|
|
|
|
|
/* This is not the interrupt safe version of the enter critical function so
|
|
|
|
|
* assert() if it is being called from an interrupt context. Only API
|
|
|
|
|
* functions that end in "FromISR" can be used in an interrupt. Only assert if
|
|
|
|
|
* the critical nesting count is 1 to protect against recursive calls if the
|
|
|
|
|
* assert function also uses a critical section. */
|
|
|
|
|
if( uxCriticalNesting == 1 )
|
|
|
|
|
{
|
|
|
|
|
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
portDISABLE_INTERRUPTS();
|
|
|
|
|
uxCriticalNesting++;
|
|
|
|
|
/* This is not the interrupt safe version of the enter critical function so
|
|
|
|
|
* assert() if it is being called from an interrupt context. Only API
|
|
|
|
|
* functions that end in "FromISR" can be used in an interrupt. Only assert if
|
|
|
|
|
* the critical nesting count is 1 to protect against recursive calls if the
|
|
|
|
|
* assert function also uses a critical section. */
|
|
|
|
|
if( uxCriticalNesting == 1 )
|
|
|
|
|
portMEMORY_BARRIER();
|
|
|
|
|
|
|
|
|
|
portRESET_PRIVILEGE();
|
|
|
|
|
portMEMORY_BARRIER();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
|
|
|
|
|
portDISABLE_INTERRUPTS();
|
|
|
|
|
uxCriticalNesting++;
|
|
|
|
|
|
|
|
|
|
/* This is not the interrupt safe version of the enter critical function so
|
|
|
|
|
* assert() if it is being called from an interrupt context. Only API
|
|
|
|
|
* functions that end in "FromISR" can be used in an interrupt. Only assert if
|
|
|
|
|
* the critical nesting count is 1 to protect against recursive calls if the
|
|
|
|
|
* assert function also uses a critical section. */
|
|
|
|
|
if( uxCriticalNesting == 1 )
|
|
|
|
|
{
|
|
|
|
|
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
portMEMORY_BARRIER();
|
|
|
|
|
|
|
|
|
|
portRESET_PRIVILEGE();
|
|
|
|
|
portMEMORY_BARRIER();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
#else /* if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) */
|
|
|
|
|
portDISABLE_INTERRUPTS();
|
|
|
|
|
uxCriticalNesting++;
|
|
|
|
|
|
|
|
|
|
/* This is not the interrupt safe version of the enter critical function so
|
|
|
|
|
* assert() if it is being called from an interrupt context. Only API
|
|
|
|
|
* functions that end in "FromISR" can be used in an interrupt. Only assert if
|
|
|
|
@ -503,45 +548,42 @@ void vPortEnterCritical( void )
|
|
|
|
|
{
|
|
|
|
|
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
portDISABLE_INTERRUPTS();
|
|
|
|
|
uxCriticalNesting++;
|
|
|
|
|
/* This is not the interrupt safe version of the enter critical function so
|
|
|
|
|
* assert() if it is being called from an interrupt context. Only API
|
|
|
|
|
* functions that end in "FromISR" can be used in an interrupt. Only assert if
|
|
|
|
|
* the critical nesting count is 1 to protect against recursive calls if the
|
|
|
|
|
* assert function also uses a critical section. */
|
|
|
|
|
if( uxCriticalNesting == 1 )
|
|
|
|
|
{
|
|
|
|
|
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
#endif /* if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) */
|
|
|
|
|
}
|
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
void vPortExitCritical( void )
|
|
|
|
|
{
|
|
|
|
|
#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
|
|
|
|
|
if( portIS_PRIVILEGED() == pdFALSE )
|
|
|
|
|
{
|
|
|
|
|
portRAISE_PRIVILEGE();
|
|
|
|
|
portMEMORY_BARRIER();
|
|
|
|
|
#if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
|
|
|
|
|
if( portIS_PRIVILEGED() == pdFALSE )
|
|
|
|
|
{
|
|
|
|
|
portRAISE_PRIVILEGE();
|
|
|
|
|
portMEMORY_BARRIER();
|
|
|
|
|
|
|
|
|
|
configASSERT( uxCriticalNesting );
|
|
|
|
|
uxCriticalNesting--;
|
|
|
|
|
configASSERT( uxCriticalNesting );
|
|
|
|
|
uxCriticalNesting--;
|
|
|
|
|
|
|
|
|
|
if( uxCriticalNesting == 0 )
|
|
|
|
|
{
|
|
|
|
|
portENABLE_INTERRUPTS();
|
|
|
|
|
if( uxCriticalNesting == 0 )
|
|
|
|
|
{
|
|
|
|
|
portENABLE_INTERRUPTS();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
portMEMORY_BARRIER();
|
|
|
|
|
|
|
|
|
|
portRESET_PRIVILEGE();
|
|
|
|
|
portMEMORY_BARRIER();
|
|
|
|
|
}
|
|
|
|
|
portMEMORY_BARRIER();
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
configASSERT( uxCriticalNesting );
|
|
|
|
|
uxCriticalNesting--;
|
|
|
|
|
|
|
|
|
|
portRESET_PRIVILEGE();
|
|
|
|
|
portMEMORY_BARRIER();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if( uxCriticalNesting == 0 )
|
|
|
|
|
{
|
|
|
|
|
portENABLE_INTERRUPTS();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else /* if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) */
|
|
|
|
|
configASSERT( uxCriticalNesting );
|
|
|
|
|
uxCriticalNesting--;
|
|
|
|
|
|
|
|
|
@ -549,16 +591,7 @@ void vPortExitCritical( void )
|
|
|
|
|
{
|
|
|
|
|
portENABLE_INTERRUPTS();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
configASSERT( uxCriticalNesting );
|
|
|
|
|
uxCriticalNesting--;
|
|
|
|
|
|
|
|
|
|
if( uxCriticalNesting == 0 )
|
|
|
|
|
{
|
|
|
|
|
portENABLE_INTERRUPTS();
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
#endif /* if ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) */
|
|
|
|
|
}
|
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
@ -710,7 +743,7 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
|
|
|
|
|
xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress =
|
|
|
|
|
( ( uint32_t ) __SRAM_segment_start__ ) | /* Base address. */
|
|
|
|
|
( portMPU_REGION_VALID ) |
|
|
|
|
|
( portSTACK_REGION ); /* Region number. */
|
|
|
|
|
( portSTACK_REGION ); /* Region number. */
|
|
|
|
|
|
|
|
|
|
xMPUSettings->xRegion[ 0 ].ulRegionAttribute =
|
|
|
|
|
( portMPU_REGION_READ_WRITE ) |
|
|
|
|
|