@ -123,14 +123,19 @@
number of bits implemented by the interrupt controller . */
# if configUNIQUE_INTERRUPT_PRIORITIES == 16
# define portPRIORITY_SHIFT 4
# define portMAX_BINARY_POINT_VALUE 3
# elif configUNIQUE_INTERRUPT_PRIORITIES == 32
# define portPRIORITY_SHIFT 3
# define portMAX_BINARY_POINT_VALUE 2
# elif configUNIQUE_INTERRUPT_PRIORITIES == 64
# define portPRIORITY_SHIFT 2
# define portMAX_BINARY_POINT_VALUE 1
# elif configUNIQUE_INTERRUPT_PRIORITIES == 128
# define portPRIORITY_SHIFT 1
# define portMAX_BINARY_POINT_VALUE 0
# elif configUNIQUE_INTERRUPT_PRIORITIES == 256
# define portPRIORITY_SHIFT 0
# define portMAX_BINARY_POINT_VALUE 0
# else
# error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware
# endif
@ -154,11 +159,19 @@ context. */
# define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )
# define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C )
# define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 )
# define portICCBPR_BINARY_POINT_OFFSET ( 0x08 )
# define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 )
# define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET )
# define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile unsigned long * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) )
# define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET )
# define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET )
# define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET )
# define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile unsigned long * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) )
# define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile unsigned char * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) )
/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary
point is zero . */
# define portBINARY_POINT_BITS ( ( unsigned char ) 0x03 )
/* Constants required to setup the initial task context. */
# define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
@ -200,11 +213,6 @@ the scheduler starts. As it is stored as part of the task context it will
automatically be set to 0 when the first task is started . */
volatile unsigned long ulCriticalNesting = 9999UL ;
/* The value to be written to the interrupt controllers priority mask register
to mask interrupts that can use the FreeRTOS API without masking higher priority
interrupts . */
const unsigned long ulPortAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY < < portPRIORITY_SHIFT ) ;
/* Used to pass constants into the ASM code. The address at which variables are
placed is the constant value so indirect loads in the asm code are not
required . */
@ -312,6 +320,13 @@ unsigned long ulAPSR;
configASSERT ( ulAPSR ! = portAPSR_USER_MODE ) ;
if ( ulAPSR ! = portAPSR_USER_MODE )
{
/* Only continue if the binary point value is set to its lowest possible
setting . See the comments in vPortValidateInterruptPriority ( ) below for
more information . */
configASSERT ( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) < = portMAX_BINARY_POINT_VALUE ) ;
if ( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) < = portMAX_BINARY_POINT_VALUE )
{
/* Start the timer that generates the tick ISR. */
configSETUP_TICK_INTERRUPT ( ) ;
@ -319,9 +334,11 @@ unsigned long ulAPSR;
__enable_irq ( ) ;
vPortRestoreTaskContext ( ) ;
}
}
/* Will only get here if xTaskStartScheduler() was called with the CPU in
a non - privileged mode . */
a non - privileged mode or the binary point register was not set to its lowest
possible value . */
return 0 ;
}
/*-----------------------------------------------------------*/
@ -371,7 +388,7 @@ void FreeRTOS_Tick_Handler( void )
handler runs at the lowest priority , so interrupts cannot already be masked ,
so there is no need to save and restore the current mask value . */
__disable_irq ( ) ;
portICCPMR_PRIORITY_MASK_REGISTER = ulPortAPIPriorityMask ;
portICCPMR_PRIORITY_MASK_REGISTER = ( configMAX_API_CALL_INTERRUPT_PRIORITY < < portPRIORITY_SHIFT ) ;
__asm ( " DSB \n "
" ISB \n " ) ;
__enable_irq ( ) ;
@ -414,7 +431,7 @@ unsigned long ulPortSetInterruptMask( void )
unsigned long ulReturn ;
__disable_irq ( ) ;
if ( portICCPMR_PRIORITY_MASK_REGISTER = = ulPortAPIPriorityMask )
if ( portICCPMR_PRIORITY_MASK_REGISTER = = ( configMAX_API_CALL_INTERRUPT_PRIORITY < < portPRIORITY_SHIFT ) )
{
/* Interrupts were already masked. */
ulReturn = pdTRUE ;
@ -422,7 +439,7 @@ unsigned long ulReturn;
else
{
ulReturn = pdFALSE ;
portICCPMR_PRIORITY_MASK_REGISTER = ulPortAPIPriorityMask ;
portICCPMR_PRIORITY_MASK_REGISTER = ( configMAX_API_CALL_INTERRUPT_PRIORITY < < portPRIORITY_SHIFT ) ;
__asm ( " DSB \n "
" ISB \n " ) ;
}
@ -430,5 +447,47 @@ unsigned long ulReturn;
return ulReturn ;
}
/*-----------------------------------------------------------*/
# if( configASSERT_DEFINED == 1 )
void vPortValidateInterruptPriority ( void )
{
/* 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 .
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 .
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 */
configASSERT ( portICCRPR_RUNNING_PRIORITY_REGISTER > = ( configMAX_API_CALL_INTERRUPT_PRIORITY < < portPRIORITY_SHIFT ) ) ;
/* Priority grouping: The interrupt controller (GIC) 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 ) .
The priority grouping is configured by the GIC ' s binary point register
( ICCBPR ) . Writting 0 to ICCBPR will ensure it is set to its lowest
possible value ( which may be above 0 ) . */
configASSERT ( portICCBPR_BINARY_POINT_REGISTER < = portMAX_BINARY_POINT_VALUE ) ;
}
# endif /* configASSERT_DEFINED */