diff --git a/FreeRTOS/Source/include/FreeRTOS.h b/FreeRTOS/Source/include/FreeRTOS.h index f6f4b2e8a..2f3d16ac2 100644 --- a/FreeRTOS/Source/include/FreeRTOS.h +++ b/FreeRTOS/Source/include/FreeRTOS.h @@ -229,6 +229,9 @@ typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * ); #ifndef configASSERT #define configASSERT( x ) + #define configASSERT_DEFINED 0 +#else + #define configASSERT_DEFINED 1 #endif /* The timers module relies on xTaskGetSchedulerState(). */ @@ -592,6 +595,10 @@ typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * ); #define configINCLUDE_STATS_FORMATTING_FUNCTIONS 0 #endif +#ifndef portASSERT_IF_INTERRUPT_PRIORITY_INVALID + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() +#endif + /* For backward compatability. */ #define eTaskStateGet eTaskGetState diff --git a/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c b/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c index e9acf2eaa..a3d652f12 100644 --- a/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c +++ b/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c @@ -107,6 +107,12 @@ 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_SYSTICK_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +/* Constants required to check the validity of an interrupt prority. */ +#define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) +#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) +#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) ) +#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) + /* Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) @@ -166,6 +172,16 @@ static void prvPortStartFirstTask( void ) __attribute__ (( naked )); static unsigned long ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ +/* + * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure + * FreeRTOS API functions are not called from interrupts that have been assigned + * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. + */ +#if ( configASSERT_DEFINED == 1 ) + static unsigned char ucMaxSysCallPriority = 0; + static const volatile unsigned char * const pcInterruptPriorityRegisters = ( const volatile unsigned char * const ) portNVIC_IP_REGISTERS_OFFSET_16; +#endif /* configASSERT_DEFINED */ + /*-----------------------------------------------------------*/ /* @@ -231,6 +247,33 @@ portBASE_TYPE xPortStartScheduler( void ) See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); + #if( configASSERT_DEFINED == 1 ) + { + volatile unsigned long ulOriginalPriority; + volatile char * const pcFirstUserPriorityRegister = ( volatile char * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); + + /* 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 = *pcFirstUserPriorityRegister; + + /* Write the configMAX_SYSCALL_INTERRUPT_PRIORITY value to an interrupt + priority register. */ + *pcFirstUserPriorityRegister = configMAX_SYSCALL_INTERRUPT_PRIORITY; + + /* Read back the written priority to obtain its value as seen by the + hardware, which will only implement a subset of the priority bits. */ + ucMaxSysCallPriority = *pcFirstUserPriorityRegister; + + /* Restore the clobbered interrupt priority register to its original + value. */ + *pcFirstUserPriorityRegister = ulOriginalPriority; + } + #endif /* conifgASSERT_DEFINED */ + /* Make PendSV and SysTick the lowest priority interrupts. */ portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; @@ -523,4 +566,81 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void ) portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } /*-----------------------------------------------------------*/ + +#if( configASSERT_DEFINED == 1 ) + + void vPortValidateInterruptPriority( void ) + { + unsigned long ulCurrentInterrupt; + unsigned char ucCurrentPriority; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); + + /* Is the interrupt number a user defined interrupt? */ + if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) + { + /* Look up the interrupt's priority. */ + 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. + + 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. + + 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( 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). + + If CMSIS libraries are being used then the correct setting can be + achieved by calling NVIC_SetPriorityGrouping( 0 ); before starting the + scheduler. */ + configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) == 0 ); + } + +#endif /* configASSERT_DEFINED */ + + + + + + + + + + + + + + + + + + + + diff --git a/FreeRTOS/Source/portable/GCC/ARM_CM3/portmacro.h b/FreeRTOS/Source/portable/GCC/ARM_CM3/portmacro.h index 7335aa264..def764e1c 100644 --- a/FreeRTOS/Source/portable/GCC/ARM_CM3/portmacro.h +++ b/FreeRTOS/Source/portable/GCC/ARM_CM3/portmacro.h @@ -180,6 +180,13 @@ not necessary for to use this port. They are defined so the common demo files /*-----------------------------------------------------------*/ +#ifdef configASSERT + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() +#else + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() +#endif + /* portNOP() is not required by this port. */ #define portNOP() diff --git a/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c b/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c index f3826b1df..7cb06899b 100644 --- a/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c +++ b/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c @@ -104,6 +104,12 @@ #define portNVIC_PENDSV_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_SYSTICK_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +/* Constants required to check the validity of an interrupt prority. */ +#define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) +#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) +#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) ) +#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) + /* Constants required to manipulate the VFP. */ #define portFPCCR ( ( volatile unsigned long * ) 0xe000ef34 ) /* Floating point context control register. */ #define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) @@ -173,6 +179,16 @@ static void prvPortStartFirstTask( void ) __attribute__ (( naked )); static unsigned long ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ +/* + * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure + * FreeRTOS API functions are not called from interrupts that have been assigned + * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. + */ +#if ( configASSERT_DEFINED == 1 ) + static unsigned char ucMaxSysCallPriority = 0; + static const volatile unsigned char * const pcInterruptPriorityRegisters = ( const volatile unsigned char * const ) portNVIC_IP_REGISTERS_OFFSET_16; +#endif /* configASSERT_DEFINED */ + /*-----------------------------------------------------------*/ /* @@ -249,6 +265,33 @@ portBASE_TYPE xPortStartScheduler( void ) See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); + #if( configASSERT_DEFINED == 1 ) + { + volatile unsigned long ulOriginalPriority; + volatile char * const pcFirstUserPriorityRegister = ( volatile char * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); + + /* 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 = *pcFirstUserPriorityRegister; + + /* Write the configMAX_SYSCALL_INTERRUPT_PRIORITY value to an interrupt + priority register. */ + *pcFirstUserPriorityRegister = configMAX_SYSCALL_INTERRUPT_PRIORITY; + + /* Read back the written priority to obtain its value as seen by the + hardware, which will only implement a subset of the priority bits. */ + ucMaxSysCallPriority = *pcFirstUserPriorityRegister; + + /* Restore the clobbered interrupt priority register to its original + value. */ + *pcFirstUserPriorityRegister = ulOriginalPriority; + } + #endif /* conifgASSERT_DEFINED */ + /* Make PendSV and SysTick the lowest priority interrupts. */ portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; @@ -572,4 +615,63 @@ static void vPortEnableVFP( void ) " bx r14 " ); } +/*-----------------------------------------------------------*/ + +#if( configASSERT_DEFINED == 1 ) + + void vPortValidateInterruptPriority( void ) + { + unsigned long ulCurrentInterrupt; + unsigned char ucCurrentPriority; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); + + /* Is the interrupt number a user defined interrupt? */ + if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) + { + /* Look up the interrupt's priority. */ + 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. + + 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. + + 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( 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). + + If CMSIS libraries are being used then the correct setting can be + achieved by calling NVIC_SetPriorityGrouping( 0 ); before starting the + scheduler. */ + configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) == 0 ); + } + +#endif /* configASSERT_DEFINED */ + diff --git a/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h b/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h index 7d58e7b82..a006e4517 100644 --- a/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h +++ b/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h @@ -181,6 +181,13 @@ not necessary for to use this port. They are defined so the common demo files /*-----------------------------------------------------------*/ +#ifdef configASSERT + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() +#else + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() +#endif + /* portNOP() is not required by this port. */ #define portNOP() diff --git a/FreeRTOS/Source/portable/IAR/ARM_CM3/port.c b/FreeRTOS/Source/portable/IAR/ARM_CM3/port.c index db8c1f117..c8fbfde42 100644 --- a/FreeRTOS/Source/portable/IAR/ARM_CM3/port.c +++ b/FreeRTOS/Source/portable/IAR/ARM_CM3/port.c @@ -107,6 +107,12 @@ #define portNVIC_PENDSV_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_SYSTICK_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +/* Constants required to check the validity of an interrupt prority. */ +#define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) +#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) +#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) ) +#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) + /* Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) @@ -171,6 +177,16 @@ extern void vPortStartFirstTask( void ); static unsigned long ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ +/* + * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure + * FreeRTOS API functions are not called from interrupts that have been assigned + * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. + */ +#if ( configASSERT_DEFINED == 1 ) + static unsigned char ucMaxSysCallPriority = 0; + static const volatile unsigned char * const pcInterruptPriorityRegisters = ( const volatile unsigned char * const ) portNVIC_IP_REGISTERS_OFFSET_16; +#endif /* configASSERT_DEFINED */ + /*-----------------------------------------------------------*/ /* @@ -199,6 +215,33 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE */ portBASE_TYPE xPortStartScheduler( void ) { + #if( configASSERT_DEFINED == 1 ) + { + volatile unsigned long ulOriginalPriority; + volatile char * const pcFirstUserPriorityRegister = ( volatile char * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); + + /* 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 = *pcFirstUserPriorityRegister; + + /* Write the configMAX_SYSCALL_INTERRUPT_PRIORITY value to an interrupt + priority register. */ + *pcFirstUserPriorityRegister = configMAX_SYSCALL_INTERRUPT_PRIORITY; + + /* Read back the written priority to obtain its value as seen by the + hardware, which will only implement a subset of the priority bits. */ + ucMaxSysCallPriority = *pcFirstUserPriorityRegister; + + /* Restore the clobbered interrupt priority register to its original + value. */ + *pcFirstUserPriorityRegister = ulOriginalPriority; + } + #endif /* conifgASSERT_DEFINED */ + /* Make PendSV and SysTick the lowest priority interrupts. */ portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; @@ -425,4 +468,81 @@ __weak void vPortSetupTimerInterrupt( void ) portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } /*-----------------------------------------------------------*/ + +#if( configASSERT_DEFINED == 1 ) + + void vPortValidateInterruptPriority( void ) + { + unsigned long ulCurrentInterrupt; + unsigned char ucCurrentPriority; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); + + /* Is the interrupt number a user defined interrupt? */ + if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) + { + /* Look up the interrupt's priority. */ + 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. + + 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. + + 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( 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). + + If CMSIS libraries are being used then the correct setting can be + achieved by calling NVIC_SetPriorityGrouping( 0 ); before starting the + scheduler. */ + configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) == 0 ); + } + +#endif /* configASSERT_DEFINED */ + + + + + + + + + + + + + + + + + + + + diff --git a/FreeRTOS/Source/portable/IAR/ARM_CM3/portmacro.h b/FreeRTOS/Source/portable/IAR/ARM_CM3/portmacro.h index ad3632060..396bddacb 100644 --- a/FreeRTOS/Source/portable/IAR/ARM_CM3/portmacro.h +++ b/FreeRTOS/Source/portable/IAR/ARM_CM3/portmacro.h @@ -171,6 +171,13 @@ not necessary for to use this port. They are defined so the common demo files #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) /*-----------------------------------------------------------*/ +#ifdef configASSERT + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() +#else + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() +#endif + /* portNOP() is not required by this port. */ #define portNOP() diff --git a/FreeRTOS/Source/portable/IAR/ARM_CM4F/port.c b/FreeRTOS/Source/portable/IAR/ARM_CM4F/port.c index 543cba3cc..e5a365855 100644 --- a/FreeRTOS/Source/portable/IAR/ARM_CM4F/port.c +++ b/FreeRTOS/Source/portable/IAR/ARM_CM4F/port.c @@ -111,6 +111,12 @@ #define portNVIC_PENDSV_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_SYSTICK_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +/* Constants required to check the validity of an interrupt prority. */ +#define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) +#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) +#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) ) +#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) + /* Constants required to manipulate the VFP. */ #define portFPCCR ( ( volatile unsigned long * ) 0xe000ef34 ) /* Floating point context control register. */ #define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) @@ -179,6 +185,16 @@ extern void vPortEnableVFP( void ); static unsigned long ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ +/* + * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure + * FreeRTOS API functions are not called from interrupts that have been assigned + * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. + */ +#if ( configASSERT_DEFINED == 1 ) + static unsigned char ucMaxSysCallPriority = 0; + static const volatile unsigned char * const pcInterruptPriorityRegisters = ( const volatile unsigned char * const ) portNVIC_IP_REGISTERS_OFFSET_16; +#endif /* configASSERT_DEFINED */ + /*-----------------------------------------------------------*/ /* @@ -219,6 +235,33 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE */ portBASE_TYPE xPortStartScheduler( void ) { + #if( configASSERT_DEFINED == 1 ) + { + volatile unsigned long ulOriginalPriority; + volatile char * const pcFirstUserPriorityRegister = ( volatile char * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); + + /* 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 = *pcFirstUserPriorityRegister; + + /* Write the configMAX_SYSCALL_INTERRUPT_PRIORITY value to an interrupt + priority register. */ + *pcFirstUserPriorityRegister = configMAX_SYSCALL_INTERRUPT_PRIORITY; + + /* Read back the written priority to obtain its value as seen by the + hardware, which will only implement a subset of the priority bits. */ + ucMaxSysCallPriority = *pcFirstUserPriorityRegister; + + /* Restore the clobbered interrupt priority register to its original + value. */ + *pcFirstUserPriorityRegister = ulOriginalPriority; + } + #endif /* conifgASSERT_DEFINED */ + /* Make PendSV and SysTick the lowest priority interrupts. */ portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; @@ -451,4 +494,81 @@ __weak void vPortSetupTimerInterrupt( void ) portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; } /*-----------------------------------------------------------*/ + +#if( configASSERT_DEFINED == 1 ) + + void vPortValidateInterruptPriority( void ) + { + unsigned long ulCurrentInterrupt; + unsigned char ucCurrentPriority; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); + + /* Is the interrupt number a user defined interrupt? */ + if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) + { + /* Look up the interrupt's priority. */ + 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. + + 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. + + 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( 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). + + If CMSIS libraries are being used then the correct setting can be + achieved by calling NVIC_SetPriorityGrouping( 0 ); before starting the + scheduler. */ + configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) == 0 ); + } + +#endif /* configASSERT_DEFINED */ + + + + + + + + + + + + + + + + + + + + diff --git a/FreeRTOS/Source/portable/IAR/ARM_CM4F/portmacro.h b/FreeRTOS/Source/portable/IAR/ARM_CM4F/portmacro.h index 8ef0e0724..3d3be493f 100644 --- a/FreeRTOS/Source/portable/IAR/ARM_CM4F/portmacro.h +++ b/FreeRTOS/Source/portable/IAR/ARM_CM4F/portmacro.h @@ -172,6 +172,13 @@ not necessary for to use this port. They are defined so the common demo files #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) /*-----------------------------------------------------------*/ +#ifdef configASSERT + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() +#else + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() +#endif + /* portNOP() is not required by this port. */ #define portNOP() diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c b/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c index 9254d6271..8311f94c7 100644 --- a/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c +++ b/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c @@ -117,6 +117,12 @@ is defined. */ #define portNVIC_PENDSV_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_SYSTICK_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +/* Constants required to check the validity of an interrupt prority. */ +#define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) +#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) +#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) ) +#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) + /* Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) @@ -179,6 +185,16 @@ static void prvStartFirstTask( void ); static unsigned long ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ +/* + * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure + * FreeRTOS API functions are not called from interrupts that have been assigned + * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. + */ +#if ( configASSERT_DEFINED == 1 ) + static unsigned char ucMaxSysCallPriority = 0; + static const volatile unsigned char * const pcInterruptPriorityRegisters = ( const volatile unsigned char * const ) portNVIC_IP_REGISTERS_OFFSET_16; +#endif /* configASSERT_DEFINED */ + /*-----------------------------------------------------------*/ /* @@ -241,6 +257,33 @@ __asm void prvStartFirstTask( void ) */ portBASE_TYPE xPortStartScheduler( void ) { + #if( configASSERT_DEFINED == 1 ) + { + volatile unsigned long ulOriginalPriority; + volatile char * const pcFirstUserPriorityRegister = ( volatile char * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); + + /* 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 = *pcFirstUserPriorityRegister; + + /* Write the configMAX_SYSCALL_INTERRUPT_PRIORITY value to an interrupt + priority register. */ + *pcFirstUserPriorityRegister = configMAX_SYSCALL_INTERRUPT_PRIORITY; + + /* Read back the written priority to obtain its value as seen by the + hardware, which will only implement a subset of the priority bits. */ + ucMaxSysCallPriority = *pcFirstUserPriorityRegister; + + /* Restore the clobbered interrupt priority register to its original + value. */ + *pcFirstUserPriorityRegister = ulOriginalPriority; + } + #endif /* conifgASSERT_DEFINED */ + /* Make PendSV and SysTick the lowest priority interrupts. */ portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; @@ -524,3 +567,72 @@ __asm void vPortClearInterruptMask( unsigned long ulNewMask ) msr basepri, r0 bx r14 } +/*-----------------------------------------------------------*/ + +__asm unsigned long vPortGetIPSR( void ) +{ + PRESERVE8 + + mrs r0, ipsr + bx r14 +} +/*-----------------------------------------------------------*/ + +#if( configASSERT_DEFINED == 1 ) + + void vPortValidateInterruptPriority( void ) + { + unsigned long ulCurrentInterrupt; + unsigned char ucCurrentPriority; + + /* Obtain the number of the currently executing interrupt. */ + ulCurrentInterrupt = vPortGetIPSR(); + + /* Is the interrupt number a user defined interrupt? */ + if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) + { + /* Look up the interrupt's priority. */ + 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. + + 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. + + 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( 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). + + If CMSIS libraries are being used then the correct setting can be + achieved by calling NVIC_SetPriorityGrouping( 0 ); before starting the + scheduler. */ + configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) == 0 ); + } + +#endif /* configASSERT_DEFINED */ + + diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CM3/portmacro.h b/FreeRTOS/Source/portable/RVDS/ARM_CM3/portmacro.h index 80a7b2f3f..8e3522657 100644 --- a/FreeRTOS/Source/portable/RVDS/ARM_CM3/portmacro.h +++ b/FreeRTOS/Source/portable/RVDS/ARM_CM3/portmacro.h @@ -170,6 +170,13 @@ not necessary for to use this port. They are defined so the common demo files #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) /*-----------------------------------------------------------*/ +#ifdef configASSERT + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() +#else + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() +#endif + /* portNOP() is not required by this port. */ #define portNOP() diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c b/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c index 616a8330b..1877f9a16 100644 --- a/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c +++ b/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c @@ -117,6 +117,12 @@ is defined. */ #define portNVIC_PENDSV_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_SYSTICK_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +/* Constants required to check the validity of an interrupt prority. */ +#define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) +#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) +#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) ) +#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) + /* Constants required to manipulate the VFP. */ #define portFPCCR ( ( volatile unsigned long * ) 0xe000ef34 ) /* Floating point context control register. */ #define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) @@ -188,6 +194,16 @@ static void prvEnableVFP( void ); static unsigned long ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ +/* + * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure + * FreeRTOS API functions are not called from interrupts that have been assigned + * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. + */ +#if ( configASSERT_DEFINED == 1 ) + static unsigned char ucMaxSysCallPriority = 0; + static const volatile unsigned char * const pcInterruptPriorityRegisters = ( unsigned char * ) portNVIC_IP_REGISTERS_OFFSET_16; +#endif /* configASSERT_DEFINED */ + /*-----------------------------------------------------------*/ /* @@ -279,6 +295,33 @@ __asm void prvEnableVFP( void ) */ portBASE_TYPE xPortStartScheduler( void ) { + #if( configASSERT_DEFINED == 1 ) + { + volatile unsigned long ulOriginalPriority; + volatile char * const pcFirstUserPriorityRegister = ( char * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); + + /* 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 = *pcFirstUserPriorityRegister; + + /* Write the configMAX_SYSCALL_INTERRUPT_PRIORITY value to an interrupt + priority register. */ + *pcFirstUserPriorityRegister = configMAX_SYSCALL_INTERRUPT_PRIORITY; + + /* Read back the written priority to obtain its value as seen by the + hardware, which will only implement a subset of the priority bits. */ + ucMaxSysCallPriority = *pcFirstUserPriorityRegister; + + /* Restore the clobbered interrupt priority register to its original + value. */ + *pcFirstUserPriorityRegister = ulOriginalPriority; + } + #endif /* conifgASSERT_DEFINED */ + /* Make PendSV and SysTick the lowest priority interrupts. */ portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; @@ -587,3 +630,72 @@ __asm void vPortClearInterruptMask( unsigned long ulNewMask ) msr basepri, r0 bx r14 } +/*-----------------------------------------------------------*/ + +__asm unsigned long vPortGetIPSR( void ) +{ + PRESERVE8 + + mrs r0, ipsr + bx r14 +} +/*-----------------------------------------------------------*/ + +#if( configASSERT_DEFINED == 1 ) + + void vPortValidateInterruptPriority( void ) + { + unsigned long ulCurrentInterrupt; + unsigned char ucCurrentPriority; + + /* Obtain the number of the currently executing interrupt. */ + ulCurrentInterrupt = vPortGetIPSR(); + + /* Is the interrupt number a user defined interrupt? */ + if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) + { + /* Look up the interrupt's priority. */ + 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. + + 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. + + 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( 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). + + If CMSIS libraries are being used then the correct setting can be + achieved by calling NVIC_SetPriorityGrouping( 0 ); before starting the + scheduler. */ + configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) == 0 ); + } + +#endif /* configASSERT_DEFINED */ + + diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CM4F/portmacro.h b/FreeRTOS/Source/portable/RVDS/ARM_CM4F/portmacro.h index ef8fa6252..d2ab5a527 100644 --- a/FreeRTOS/Source/portable/RVDS/ARM_CM4F/portmacro.h +++ b/FreeRTOS/Source/portable/RVDS/ARM_CM4F/portmacro.h @@ -171,6 +171,13 @@ not necessary for to use this port. They are defined so the common demo files #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) /*-----------------------------------------------------------*/ +#ifdef configASSERT + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() +#else + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() +#endif + /* portNOP() is not required by this port. */ #define portNOP() diff --git a/FreeRTOS/Source/queue.c b/FreeRTOS/Source/queue.c index b9024d535..ec665174b 100644 --- a/FreeRTOS/Source/queue.c +++ b/FreeRTOS/Source/queue.c @@ -940,6 +940,7 @@ xQUEUE *pxQueue; configASSERT( pxQueue ); configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) ); + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); /* Similar to xQueueGenericSend, except we don't block if there is no room in the queue. Also we don't directly wake a task that was blocked on a @@ -1050,7 +1051,7 @@ xQUEUE *pxQueue; the highest priority task wanting to access the queue. */ if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) { - /* Remember the read position in case the queue is only being + /* Remember the read position in case the queue is only being peeked. */ pcOriginalReadPosition = pxQueue->u.pcReadFrom; @@ -1188,6 +1189,7 @@ xQUEUE *pxQueue; pxQueue = ( xQUEUE * ) xQueue; configASSERT( pxQueue ); configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); { @@ -1199,9 +1201,9 @@ xQUEUE *pxQueue; prvCopyDataFromQueue( pxQueue, pvBuffer ); --( pxQueue->uxMessagesWaiting ); - /* If the queue is locked the event list will not be modified. - Instead update the lock count so the task that unlocks the queue - will know that an ISR has removed data while the queue was + /* If the queue is locked the event list will not be modified. + Instead update the lock count so the task that unlocks the queue + will know that an ISR has removed data while the queue was locked. */ if( pxQueue->xRxLock == queueUNLOCKED ) { @@ -1249,6 +1251,7 @@ xQUEUE *pxQueue; pxQueue = ( xQUEUE * ) xQueue; configASSERT( pxQueue ); configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); { @@ -1388,9 +1391,9 @@ static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, port { if( pxQueue->uxMessagesWaiting > 0 ) { - /* An item is not being added but overwritten, so subtract - one from the recorded number of items in the queue so when - one is added again below the number of recorded items remains + /* An item is not being added but overwritten, so subtract + one from the recorded number of items in the queue so when + one is added again below the number of recorded items remains correct. */ --( pxQueue->uxMessagesWaiting ); } diff --git a/FreeRTOS/Source/tasks.c b/FreeRTOS/Source/tasks.c index 83d9f09a3..dc4f60107 100644 --- a/FreeRTOS/Source/tasks.c +++ b/FreeRTOS/Source/tasks.c @@ -1176,6 +1176,7 @@ tskTCB * pxNewTCB; unsigned portBASE_TYPE uxSavedInterruptStatus; configASSERT( xTaskToResume ); + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); pxTCB = ( tskTCB * ) xTaskToResume; @@ -1414,6 +1415,8 @@ portTickType xTaskGetTickCountFromISR( void ) portTickType xReturn; unsigned portBASE_TYPE uxSavedInterruptStatus; + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); xReturn = xTickCount; portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );