mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-20 05:21:59 -04:00
Update the Cortex-M vPortValidateInterruptPriority() implementation to ensure compatibility with the STM32 standard peripheral library.
This commit is contained in:
parent
f522d6a2da
commit
679a3c670c
|
@ -97,14 +97,18 @@ FreeRTOS.org versions prior to V4.4.0 did not include this definition. */
|
||||||
#define portNVIC_PENDSV_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL )
|
#define portNVIC_PENDSV_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL )
|
||||||
#define portNVIC_SYSTICK_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL )
|
#define portNVIC_SYSTICK_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL )
|
||||||
|
|
||||||
/* Constants required to check the validity of an interrupt prority. */
|
/* Constants required to check the validity of an interrupt priority. */
|
||||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||||
#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) )
|
#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) )
|
||||||
|
#define portMAX_8_BIT_VALUE ( ( unsigned char ) 0xff )
|
||||||
|
#define portTOP_BIT_OF_BYTE ( ( unsigned char ) 0x80 )
|
||||||
|
#define portMAX_PRIGROUP_BITS ( ( unsigned char ) 7 )
|
||||||
#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL )
|
#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL )
|
||||||
|
#define portPRIGROUP_SHIFT ( 8UL )
|
||||||
|
|
||||||
/* Constants required to set up the initial stack. */
|
/* Constants required to set up the initial stack. */
|
||||||
#define portINITIAL_XPSR ( 0x01000000 )
|
#define portINITIAL_XPSR ( 0x01000000UL )
|
||||||
|
|
||||||
/* The systick is a 24-bit counter. */
|
/* The systick is a 24-bit counter. */
|
||||||
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
|
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
|
||||||
|
@ -169,6 +173,7 @@ static void prvPortStartFirstTask( void ) __attribute__ (( naked ));
|
||||||
*/
|
*/
|
||||||
#if ( configASSERT_DEFINED == 1 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
static unsigned char ucMaxSysCallPriority = 0;
|
static unsigned char ucMaxSysCallPriority = 0;
|
||||||
|
static unsigned long ulMaxPRIGROUPValue = 0;
|
||||||
static const volatile unsigned char * const pcInterruptPriorityRegisters = ( const volatile unsigned char * const ) portNVIC_IP_REGISTERS_OFFSET_16;
|
static const volatile unsigned char * const pcInterruptPriorityRegisters = ( const volatile unsigned char * const ) portNVIC_IP_REGISTERS_OFFSET_16;
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
|
@ -241,6 +246,7 @@ portBASE_TYPE xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
volatile unsigned long ulOriginalPriority;
|
volatile unsigned long ulOriginalPriority;
|
||||||
volatile char * const pcFirstUserPriorityRegister = ( volatile char * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
volatile char * const pcFirstUserPriorityRegister = ( volatile char * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
||||||
|
volatile unsigned char ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
functions can be called. ISR safe functions are those that end in
|
functions can be called. ISR safe functions are those that end in
|
||||||
|
@ -250,13 +256,29 @@ portBASE_TYPE xPortStartScheduler( void )
|
||||||
Save the interrupt priority value that is about to be clobbered. */
|
Save the interrupt priority value that is about to be clobbered. */
|
||||||
ulOriginalPriority = *pcFirstUserPriorityRegister;
|
ulOriginalPriority = *pcFirstUserPriorityRegister;
|
||||||
|
|
||||||
/* Write the configMAX_SYSCALL_INTERRUPT_PRIORITY value to an interrupt
|
/* Determine the number of priority bits available. First write to all
|
||||||
priority register. */
|
possible bits. */
|
||||||
*pcFirstUserPriorityRegister = configMAX_SYSCALL_INTERRUPT_PRIORITY;
|
*pcFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||||
|
|
||||||
/* Read back the written priority to obtain its value as seen by the
|
/* Read the value back to see how many bits stuck. */
|
||||||
hardware, which will only implement a subset of the priority bits. */
|
ucMaxPriorityValue = *pcFirstUserPriorityRegister;
|
||||||
ucMaxSysCallPriority = *pcFirstUserPriorityRegister;
|
|
||||||
|
/* Use the same mask on the maximum system call priority. */
|
||||||
|
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
||||||
|
|
||||||
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
|
of bits read back. */
|
||||||
|
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
|
||||||
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
|
{
|
||||||
|
ulMaxPRIGROUPValue--;
|
||||||
|
ucMaxPriorityValue <<= ( unsigned char ) 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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
|
/* Restore the clobbered interrupt priority register to its original
|
||||||
value. */
|
value. */
|
||||||
|
@ -606,10 +628,13 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
||||||
to be pre-emption priority bits. The following assertion will fail if
|
to be pre-emption priority bits. The following assertion will fail if
|
||||||
this is not the case (if some bits represent a sub-priority).
|
this is not the case (if some bits represent a sub-priority).
|
||||||
|
|
||||||
If CMSIS libraries are being used then the correct setting can be
|
If the application only uses CMSIS libraries for interrupt
|
||||||
achieved by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
configuration then the correct setting can be achieved on all Cortex-M
|
||||||
scheduler. */
|
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
||||||
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) == 0 );
|
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 */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
|
@ -94,11 +94,15 @@
|
||||||
#define portNVIC_PENDSV_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL )
|
#define portNVIC_PENDSV_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL )
|
||||||
#define portNVIC_SYSTICK_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL )
|
#define portNVIC_SYSTICK_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL )
|
||||||
|
|
||||||
/* Constants required to check the validity of an interrupt prority. */
|
/* Constants required to check the validity of an interrupt priority. */
|
||||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||||
#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) )
|
#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) )
|
||||||
|
#define portMAX_8_BIT_VALUE ( ( unsigned char ) 0xff )
|
||||||
|
#define portTOP_BIT_OF_BYTE ( ( unsigned char ) 0x80 )
|
||||||
|
#define portMAX_PRIGROUP_BITS ( ( unsigned char ) 7 )
|
||||||
#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL )
|
#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL )
|
||||||
|
#define portPRIGROUP_SHIFT ( 8UL )
|
||||||
|
|
||||||
/* Constants required to manipulate the VFP. */
|
/* Constants required to manipulate the VFP. */
|
||||||
#define portFPCCR ( ( volatile unsigned long * ) 0xe000ef34 ) /* Floating point context control register. */
|
#define portFPCCR ( ( volatile unsigned long * ) 0xe000ef34 ) /* Floating point context control register. */
|
||||||
|
@ -176,6 +180,7 @@ static void prvPortStartFirstTask( void ) __attribute__ (( naked ));
|
||||||
*/
|
*/
|
||||||
#if ( configASSERT_DEFINED == 1 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
static unsigned char ucMaxSysCallPriority = 0;
|
static unsigned char ucMaxSysCallPriority = 0;
|
||||||
|
static unsigned long ulMaxPRIGROUPValue = 0;
|
||||||
static const volatile unsigned char * const pcInterruptPriorityRegisters = ( const volatile unsigned char * const ) portNVIC_IP_REGISTERS_OFFSET_16;
|
static const volatile unsigned char * const pcInterruptPriorityRegisters = ( const volatile unsigned char * const ) portNVIC_IP_REGISTERS_OFFSET_16;
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
|
@ -259,6 +264,7 @@ portBASE_TYPE xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
volatile unsigned long ulOriginalPriority;
|
volatile unsigned long ulOriginalPriority;
|
||||||
volatile char * const pcFirstUserPriorityRegister = ( volatile char * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
volatile char * const pcFirstUserPriorityRegister = ( volatile char * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
||||||
|
volatile unsigned char ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
functions can be called. ISR safe functions are those that end in
|
functions can be called. ISR safe functions are those that end in
|
||||||
|
@ -268,13 +274,29 @@ portBASE_TYPE xPortStartScheduler( void )
|
||||||
Save the interrupt priority value that is about to be clobbered. */
|
Save the interrupt priority value that is about to be clobbered. */
|
||||||
ulOriginalPriority = *pcFirstUserPriorityRegister;
|
ulOriginalPriority = *pcFirstUserPriorityRegister;
|
||||||
|
|
||||||
/* Write the configMAX_SYSCALL_INTERRUPT_PRIORITY value to an interrupt
|
/* Determine the number of priority bits available. First write to all
|
||||||
priority register. */
|
possible bits. */
|
||||||
*pcFirstUserPriorityRegister = configMAX_SYSCALL_INTERRUPT_PRIORITY;
|
*pcFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||||
|
|
||||||
/* Read back the written priority to obtain its value as seen by the
|
/* Read the value back to see how many bits stuck. */
|
||||||
hardware, which will only implement a subset of the priority bits. */
|
ucMaxPriorityValue = *pcFirstUserPriorityRegister;
|
||||||
ucMaxSysCallPriority = *pcFirstUserPriorityRegister;
|
|
||||||
|
/* Use the same mask on the maximum system call priority. */
|
||||||
|
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
||||||
|
|
||||||
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
|
of bits read back. */
|
||||||
|
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
|
||||||
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
|
{
|
||||||
|
ulMaxPRIGROUPValue--;
|
||||||
|
ucMaxPriorityValue <<= ( unsigned char ) 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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
|
/* Restore the clobbered interrupt priority register to its original
|
||||||
value. */
|
value. */
|
||||||
|
@ -656,10 +678,13 @@ static void vPortEnableVFP( void )
|
||||||
to be pre-emption priority bits. The following assertion will fail if
|
to be pre-emption priority bits. The following assertion will fail if
|
||||||
this is not the case (if some bits represent a sub-priority).
|
this is not the case (if some bits represent a sub-priority).
|
||||||
|
|
||||||
If CMSIS libraries are being used then the correct setting can be
|
If the application only uses CMSIS libraries for interrupt
|
||||||
achieved by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
configuration then the correct setting can be achieved on all Cortex-M
|
||||||
scheduler. */
|
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
||||||
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) == 0 );
|
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 */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
|
@ -101,7 +101,11 @@
|
||||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||||
#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) )
|
#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) )
|
||||||
|
#define portMAX_8_BIT_VALUE ( ( unsigned char ) 0xff )
|
||||||
|
#define portTOP_BIT_OF_BYTE ( ( unsigned char ) 0x80 )
|
||||||
|
#define portMAX_PRIGROUP_BITS ( ( unsigned char ) 7 )
|
||||||
#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL )
|
#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL )
|
||||||
|
#define portPRIGROUP_SHIFT ( 8UL )
|
||||||
|
|
||||||
/* Constants required to set up the initial stack. */
|
/* Constants required to set up the initial stack. */
|
||||||
#define portINITIAL_XPSR ( 0x01000000 )
|
#define portINITIAL_XPSR ( 0x01000000 )
|
||||||
|
@ -174,6 +178,7 @@ extern void vPortStartFirstTask( void );
|
||||||
*/
|
*/
|
||||||
#if ( configASSERT_DEFINED == 1 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
static unsigned char ucMaxSysCallPriority = 0;
|
static unsigned char ucMaxSysCallPriority = 0;
|
||||||
|
static unsigned long ulMaxPRIGROUPValue = 0;
|
||||||
static const volatile unsigned char * const pcInterruptPriorityRegisters = ( const volatile unsigned char * const ) portNVIC_IP_REGISTERS_OFFSET_16;
|
static const volatile unsigned char * const pcInterruptPriorityRegisters = ( const volatile unsigned char * const ) portNVIC_IP_REGISTERS_OFFSET_16;
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
|
@ -209,6 +214,7 @@ portBASE_TYPE xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
volatile unsigned long ulOriginalPriority;
|
volatile unsigned long ulOriginalPriority;
|
||||||
volatile char * const pcFirstUserPriorityRegister = ( volatile char * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
volatile char * const pcFirstUserPriorityRegister = ( volatile char * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
||||||
|
volatile unsigned char ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
functions can be called. ISR safe functions are those that end in
|
functions can be called. ISR safe functions are those that end in
|
||||||
|
@ -218,13 +224,29 @@ portBASE_TYPE xPortStartScheduler( void )
|
||||||
Save the interrupt priority value that is about to be clobbered. */
|
Save the interrupt priority value that is about to be clobbered. */
|
||||||
ulOriginalPriority = *pcFirstUserPriorityRegister;
|
ulOriginalPriority = *pcFirstUserPriorityRegister;
|
||||||
|
|
||||||
/* Write the configMAX_SYSCALL_INTERRUPT_PRIORITY value to an interrupt
|
/* Determine the number of priority bits available. First write to all
|
||||||
priority register. */
|
possible bits. */
|
||||||
*pcFirstUserPriorityRegister = configMAX_SYSCALL_INTERRUPT_PRIORITY;
|
*pcFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||||
|
|
||||||
/* Read back the written priority to obtain its value as seen by the
|
/* Read the value back to see how many bits stuck. */
|
||||||
hardware, which will only implement a subset of the priority bits. */
|
ucMaxPriorityValue = *pcFirstUserPriorityRegister;
|
||||||
ucMaxSysCallPriority = *pcFirstUserPriorityRegister;
|
|
||||||
|
/* Use the same mask on the maximum system call priority. */
|
||||||
|
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
||||||
|
|
||||||
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
|
of bits read back. */
|
||||||
|
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
|
||||||
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
|
{
|
||||||
|
ulMaxPRIGROUPValue--;
|
||||||
|
ucMaxPriorityValue <<= ( unsigned char ) 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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
|
/* Restore the clobbered interrupt priority register to its original
|
||||||
value. */
|
value. */
|
||||||
|
@ -508,10 +530,13 @@ __weak void vPortSetupTimerInterrupt( void )
|
||||||
to be pre-emption priority bits. The following assertion will fail if
|
to be pre-emption priority bits. The following assertion will fail if
|
||||||
this is not the case (if some bits represent a sub-priority).
|
this is not the case (if some bits represent a sub-priority).
|
||||||
|
|
||||||
If CMSIS libraries are being used then the correct setting can be
|
If the application only uses CMSIS libraries for interrupt
|
||||||
achieved by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
configuration then the correct setting can be achieved on all Cortex-M
|
||||||
scheduler. */
|
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
||||||
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) == 0 );
|
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 */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
|
@ -105,7 +105,11 @@
|
||||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||||
#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) )
|
#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) )
|
||||||
|
#define portMAX_8_BIT_VALUE ( ( unsigned char ) 0xff )
|
||||||
|
#define portTOP_BIT_OF_BYTE ( ( unsigned char ) 0x80 )
|
||||||
|
#define portMAX_PRIGROUP_BITS ( ( unsigned char ) 7 )
|
||||||
#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL )
|
#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL )
|
||||||
|
#define portPRIGROUP_SHIFT ( 8UL )
|
||||||
|
|
||||||
/* Constants required to manipulate the VFP. */
|
/* Constants required to manipulate the VFP. */
|
||||||
#define portFPCCR ( ( volatile unsigned long * ) 0xe000ef34 ) /* Floating point context control register. */
|
#define portFPCCR ( ( volatile unsigned long * ) 0xe000ef34 ) /* Floating point context control register. */
|
||||||
|
@ -182,6 +186,7 @@ extern void vPortEnableVFP( void );
|
||||||
*/
|
*/
|
||||||
#if ( configASSERT_DEFINED == 1 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
static unsigned char ucMaxSysCallPriority = 0;
|
static unsigned char ucMaxSysCallPriority = 0;
|
||||||
|
static unsigned long ulMaxPRIGROUPValue = 0;
|
||||||
static const volatile unsigned char * const pcInterruptPriorityRegisters = ( const volatile unsigned char * const ) portNVIC_IP_REGISTERS_OFFSET_16;
|
static const volatile unsigned char * const pcInterruptPriorityRegisters = ( const volatile unsigned char * const ) portNVIC_IP_REGISTERS_OFFSET_16;
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
|
@ -229,6 +234,7 @@ portBASE_TYPE xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
volatile unsigned long ulOriginalPriority;
|
volatile unsigned long ulOriginalPriority;
|
||||||
volatile char * const pcFirstUserPriorityRegister = ( volatile char * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
volatile char * const pcFirstUserPriorityRegister = ( volatile char * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
||||||
|
volatile unsigned char ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
functions can be called. ISR safe functions are those that end in
|
functions can be called. ISR safe functions are those that end in
|
||||||
|
@ -238,13 +244,29 @@ portBASE_TYPE xPortStartScheduler( void )
|
||||||
Save the interrupt priority value that is about to be clobbered. */
|
Save the interrupt priority value that is about to be clobbered. */
|
||||||
ulOriginalPriority = *pcFirstUserPriorityRegister;
|
ulOriginalPriority = *pcFirstUserPriorityRegister;
|
||||||
|
|
||||||
/* Write the configMAX_SYSCALL_INTERRUPT_PRIORITY value to an interrupt
|
/* Determine the number of priority bits available. First write to all
|
||||||
priority register. */
|
possible bits. */
|
||||||
*pcFirstUserPriorityRegister = configMAX_SYSCALL_INTERRUPT_PRIORITY;
|
*pcFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||||
|
|
||||||
/* Read back the written priority to obtain its value as seen by the
|
/* Read the value back to see how many bits stuck. */
|
||||||
hardware, which will only implement a subset of the priority bits. */
|
ucMaxPriorityValue = *pcFirstUserPriorityRegister;
|
||||||
ucMaxSysCallPriority = *pcFirstUserPriorityRegister;
|
|
||||||
|
/* Use the same mask on the maximum system call priority. */
|
||||||
|
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
||||||
|
|
||||||
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
|
of bits read back. */
|
||||||
|
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
|
||||||
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
|
{
|
||||||
|
ulMaxPRIGROUPValue--;
|
||||||
|
ucMaxPriorityValue <<= ( unsigned char ) 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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
|
/* Restore the clobbered interrupt priority register to its original
|
||||||
value. */
|
value. */
|
||||||
|
@ -534,10 +556,13 @@ __weak void vPortSetupTimerInterrupt( void )
|
||||||
to be pre-emption priority bits. The following assertion will fail if
|
to be pre-emption priority bits. The following assertion will fail if
|
||||||
this is not the case (if some bits represent a sub-priority).
|
this is not the case (if some bits represent a sub-priority).
|
||||||
|
|
||||||
If CMSIS libraries are being used then the correct setting can be
|
If the application only uses CMSIS libraries for interrupt
|
||||||
achieved by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
configuration then the correct setting can be achieved on all Cortex-M
|
||||||
scheduler. */
|
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
||||||
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) == 0 );
|
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 */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
|
@ -111,7 +111,11 @@ is defined. */
|
||||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||||
#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) )
|
#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) )
|
||||||
|
#define portMAX_8_BIT_VALUE ( ( unsigned char ) 0xff )
|
||||||
|
#define portTOP_BIT_OF_BYTE ( ( unsigned char ) 0x80 )
|
||||||
|
#define portMAX_PRIGROUP_BITS ( ( unsigned char ) 7 )
|
||||||
#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL )
|
#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL )
|
||||||
|
#define portPRIGROUP_SHIFT ( 8UL )
|
||||||
|
|
||||||
/* Constants required to set up the initial stack. */
|
/* Constants required to set up the initial stack. */
|
||||||
#define portINITIAL_XPSR ( 0x01000000 )
|
#define portINITIAL_XPSR ( 0x01000000 )
|
||||||
|
@ -182,6 +186,7 @@ static void prvStartFirstTask( void );
|
||||||
*/
|
*/
|
||||||
#if ( configASSERT_DEFINED == 1 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
static unsigned char ucMaxSysCallPriority = 0;
|
static unsigned char ucMaxSysCallPriority = 0;
|
||||||
|
static unsigned long ulMaxPRIGROUPValue = 0;
|
||||||
static const volatile unsigned char * const pcInterruptPriorityRegisters = ( unsigned char * ) portNVIC_IP_REGISTERS_OFFSET_16;
|
static const volatile unsigned char * const pcInterruptPriorityRegisters = ( unsigned char * ) portNVIC_IP_REGISTERS_OFFSET_16;
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
|
@ -251,6 +256,7 @@ portBASE_TYPE xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
volatile unsigned long ulOriginalPriority;
|
volatile unsigned long ulOriginalPriority;
|
||||||
volatile char * const pcFirstUserPriorityRegister = ( char * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
volatile char * const pcFirstUserPriorityRegister = ( char * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
||||||
|
volatile unsigned char ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
functions can be called. ISR safe functions are those that end in
|
functions can be called. ISR safe functions are those that end in
|
||||||
|
@ -260,13 +266,29 @@ portBASE_TYPE xPortStartScheduler( void )
|
||||||
Save the interrupt priority value that is about to be clobbered. */
|
Save the interrupt priority value that is about to be clobbered. */
|
||||||
ulOriginalPriority = *pcFirstUserPriorityRegister;
|
ulOriginalPriority = *pcFirstUserPriorityRegister;
|
||||||
|
|
||||||
/* Write the configMAX_SYSCALL_INTERRUPT_PRIORITY value to an interrupt
|
/* Determine the number of priority bits available. First write to all
|
||||||
priority register. */
|
possible bits. */
|
||||||
*pcFirstUserPriorityRegister = configMAX_SYSCALL_INTERRUPT_PRIORITY;
|
*pcFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||||
|
|
||||||
/* Read back the written priority to obtain its value as seen by the
|
/* Read the value back to see how many bits stuck. */
|
||||||
hardware, which will only implement a subset of the priority bits. */
|
ucMaxPriorityValue = *pcFirstUserPriorityRegister;
|
||||||
ucMaxSysCallPriority = *pcFirstUserPriorityRegister;
|
|
||||||
|
/* Use the same mask on the maximum system call priority. */
|
||||||
|
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
||||||
|
|
||||||
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
|
of bits read back. */
|
||||||
|
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
|
||||||
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
|
{
|
||||||
|
ulMaxPRIGROUPValue--;
|
||||||
|
ucMaxPriorityValue <<= ( unsigned char ) 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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
|
/* Restore the clobbered interrupt priority register to its original
|
||||||
value. */
|
value. */
|
||||||
|
@ -617,10 +639,13 @@ __asm unsigned long vPortGetIPSR( void )
|
||||||
to be pre-emption priority bits. The following assertion will fail if
|
to be pre-emption priority bits. The following assertion will fail if
|
||||||
this is not the case (if some bits represent a sub-priority).
|
this is not the case (if some bits represent a sub-priority).
|
||||||
|
|
||||||
If CMSIS libraries are being used then the correct setting can be
|
If the application only uses CMSIS libraries for interrupt
|
||||||
achieved by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
configuration then the correct setting can be achieved on all Cortex-M
|
||||||
scheduler. */
|
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
||||||
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) == 0 );
|
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 */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
|
@ -111,7 +111,11 @@ is defined. */
|
||||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||||
#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) )
|
#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) )
|
||||||
|
#define portMAX_8_BIT_VALUE ( ( unsigned char ) 0xff )
|
||||||
|
#define portTOP_BIT_OF_BYTE ( ( unsigned char ) 0x80 )
|
||||||
|
#define portMAX_PRIGROUP_BITS ( ( unsigned char ) 7 )
|
||||||
#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL )
|
#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL )
|
||||||
|
#define portPRIGROUP_SHIFT ( 8UL )
|
||||||
|
|
||||||
/* Constants required to manipulate the VFP. */
|
/* Constants required to manipulate the VFP. */
|
||||||
#define portFPCCR ( ( volatile unsigned long * ) 0xe000ef34 ) /* Floating point context control register. */
|
#define portFPCCR ( ( volatile unsigned long * ) 0xe000ef34 ) /* Floating point context control register. */
|
||||||
|
@ -191,6 +195,7 @@ static void prvEnableVFP( void );
|
||||||
*/
|
*/
|
||||||
#if ( configASSERT_DEFINED == 1 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
static unsigned char ucMaxSysCallPriority = 0;
|
static unsigned char ucMaxSysCallPriority = 0;
|
||||||
|
static unsigned long ulMaxPRIGROUPValue = 0;
|
||||||
static const volatile unsigned char * const pcInterruptPriorityRegisters = ( unsigned char * ) portNVIC_IP_REGISTERS_OFFSET_16;
|
static const volatile unsigned char * const pcInterruptPriorityRegisters = ( unsigned char * ) portNVIC_IP_REGISTERS_OFFSET_16;
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
|
@ -289,6 +294,7 @@ portBASE_TYPE xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
volatile unsigned long ulOriginalPriority;
|
volatile unsigned long ulOriginalPriority;
|
||||||
volatile char * const pcFirstUserPriorityRegister = ( char * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
volatile char * const pcFirstUserPriorityRegister = ( char * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
||||||
|
volatile unsigned char ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
functions can be called. ISR safe functions are those that end in
|
functions can be called. ISR safe functions are those that end in
|
||||||
|
@ -298,13 +304,29 @@ portBASE_TYPE xPortStartScheduler( void )
|
||||||
Save the interrupt priority value that is about to be clobbered. */
|
Save the interrupt priority value that is about to be clobbered. */
|
||||||
ulOriginalPriority = *pcFirstUserPriorityRegister;
|
ulOriginalPriority = *pcFirstUserPriorityRegister;
|
||||||
|
|
||||||
/* Write the configMAX_SYSCALL_INTERRUPT_PRIORITY value to an interrupt
|
/* Determine the number of priority bits available. First write to all
|
||||||
priority register. */
|
possible bits. */
|
||||||
*pcFirstUserPriorityRegister = configMAX_SYSCALL_INTERRUPT_PRIORITY;
|
*pcFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||||
|
|
||||||
/* Read back the written priority to obtain its value as seen by the
|
/* Read the value back to see how many bits stuck. */
|
||||||
hardware, which will only implement a subset of the priority bits. */
|
ucMaxPriorityValue = *pcFirstUserPriorityRegister;
|
||||||
ucMaxSysCallPriority = *pcFirstUserPriorityRegister;
|
|
||||||
|
/* Use the same mask on the maximum system call priority. */
|
||||||
|
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
||||||
|
|
||||||
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
|
of bits read back. */
|
||||||
|
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
|
||||||
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
|
{
|
||||||
|
ulMaxPRIGROUPValue--;
|
||||||
|
ucMaxPriorityValue <<= ( unsigned char ) 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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
|
/* Restore the clobbered interrupt priority register to its original
|
||||||
value. */
|
value. */
|
||||||
|
@ -680,10 +702,13 @@ __asm unsigned long vPortGetIPSR( void )
|
||||||
to be pre-emption priority bits. The following assertion will fail if
|
to be pre-emption priority bits. The following assertion will fail if
|
||||||
this is not the case (if some bits represent a sub-priority).
|
this is not the case (if some bits represent a sub-priority).
|
||||||
|
|
||||||
If CMSIS libraries are being used then the correct setting can be
|
If the application only uses CMSIS libraries for interrupt
|
||||||
achieved by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
configuration then the correct setting can be achieved on all Cortex-M
|
||||||
scheduler. */
|
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
||||||
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) == 0 );
|
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 */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
Loading…
Reference in a new issue