Added portASSERT_IF_INTERRUPT_PRIORITY_INVALID() implementation to Cortex-M3 and Cortex-M4F ports.

This commit is contained in:
Richard Barry 2013-07-04 11:20:28 +00:00
parent b521d70e7e
commit c4eef61d39
15 changed files with 748 additions and 7 deletions

View File

@ -229,6 +229,9 @@ typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );
#ifndef configASSERT #ifndef configASSERT
#define configASSERT( x ) #define configASSERT( x )
#define configASSERT_DEFINED 0
#else
#define configASSERT_DEFINED 1
#endif #endif
/* The timers module relies on xTaskGetSchedulerState(). */ /* The timers module relies on xTaskGetSchedulerState(). */
@ -592,6 +595,10 @@ typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );
#define configINCLUDE_STATS_FORMATTING_FUNCTIONS 0 #define configINCLUDE_STATS_FORMATTING_FUNCTIONS 0
#endif #endif
#ifndef portASSERT_IF_INTERRUPT_PRIORITY_INVALID
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID()
#endif
/* For backward compatability. */ /* For backward compatability. */
#define eTaskStateGet eTaskGetState #define eTaskStateGet eTaskGetState

View File

@ -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_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. */
#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. */ /* Constants required to set up the initial stack. */
#define portINITIAL_XPSR ( 0x01000000 ) #define portINITIAL_XPSR ( 0x01000000 )
@ -166,6 +172,16 @@ static void prvPortStartFirstTask( void ) __attribute__ (( naked ));
static unsigned long ulStoppedTimerCompensation = 0; static unsigned long ulStoppedTimerCompensation = 0;
#endif /* configUSE_TICKLESS_IDLE */ #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 */ See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); 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. */ /* Make PendSV and SysTick the lowest priority interrupts. */
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_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; 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 */

View File

@ -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. */ /* portNOP() is not required by this port. */
#define portNOP() #define portNOP()

View File

@ -104,6 +104,12 @@
#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. */
#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. */ /* 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. */
#define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) #define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL )
@ -173,6 +179,16 @@ static void prvPortStartFirstTask( void ) __attribute__ (( naked ));
static unsigned long ulStoppedTimerCompensation = 0; static unsigned long ulStoppedTimerCompensation = 0;
#endif /* configUSE_TICKLESS_IDLE */ #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 */ See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); 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. */ /* Make PendSV and SysTick the lowest priority interrupts. */
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
@ -572,4 +615,63 @@ static void vPortEnableVFP( void )
" bx r14 " " 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 */

View File

@ -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. */ /* portNOP() is not required by this port. */
#define portNOP() #define portNOP()

View File

@ -107,6 +107,12 @@
#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. */
#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. */ /* Constants required to set up the initial stack. */
#define portINITIAL_XPSR ( 0x01000000 ) #define portINITIAL_XPSR ( 0x01000000 )
@ -171,6 +177,16 @@ extern void vPortStartFirstTask( void );
static unsigned long ulStoppedTimerCompensation = 0; static unsigned long ulStoppedTimerCompensation = 0;
#endif /* configUSE_TICKLESS_IDLE */ #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 ) 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. */ /* Make PendSV and SysTick the lowest priority interrupts. */
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_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; 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 */

View File

@ -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 ) #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. */ /* portNOP() is not required by this port. */
#define portNOP() #define portNOP()

View File

@ -111,6 +111,12 @@
#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. */
#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. */ /* 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. */
#define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) #define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL )
@ -179,6 +185,16 @@ extern void vPortEnableVFP( void );
static unsigned long ulStoppedTimerCompensation = 0; static unsigned long ulStoppedTimerCompensation = 0;
#endif /* configUSE_TICKLESS_IDLE */ #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 ) 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. */ /* Make PendSV and SysTick the lowest priority interrupts. */
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_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; 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 */

View File

@ -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 ) #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. */ /* portNOP() is not required by this port. */
#define portNOP() #define portNOP()

View File

@ -117,6 +117,12 @@ is defined. */
#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. */
#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. */ /* Constants required to set up the initial stack. */
#define portINITIAL_XPSR ( 0x01000000 ) #define portINITIAL_XPSR ( 0x01000000 )
@ -179,6 +185,16 @@ static void prvStartFirstTask( void );
static unsigned long ulStoppedTimerCompensation = 0; static unsigned long ulStoppedTimerCompensation = 0;
#endif /* configUSE_TICKLESS_IDLE */ #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 ) 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. */ /* Make PendSV and SysTick the lowest priority interrupts. */
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
@ -524,3 +567,72 @@ __asm void vPortClearInterruptMask( unsigned long ulNewMask )
msr basepri, r0 msr basepri, r0
bx r14 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 */

View File

@ -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 ) #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. */ /* portNOP() is not required by this port. */
#define portNOP() #define portNOP()

View File

@ -117,6 +117,12 @@ is defined. */
#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. */
#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. */ /* 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. */
#define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) #define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL )
@ -188,6 +194,16 @@ static void prvEnableVFP( void );
static unsigned long ulStoppedTimerCompensation = 0; static unsigned long ulStoppedTimerCompensation = 0;
#endif /* configUSE_TICKLESS_IDLE */ #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 ) 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. */ /* Make PendSV and SysTick the lowest priority interrupts. */
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
@ -587,3 +630,72 @@ __asm void vPortClearInterruptMask( unsigned long ulNewMask )
msr basepri, r0 msr basepri, r0
bx r14 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 */

View File

@ -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 ) #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. */ /* portNOP() is not required by this port. */
#define portNOP() #define portNOP()

View File

@ -940,6 +940,7 @@ xQUEUE *pxQueue;
configASSERT( pxQueue ); configASSERT( pxQueue );
configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) ); configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) );
portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
/* Similar to xQueueGenericSend, except we don't block if there is no room /* 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 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. */ the highest priority task wanting to access the queue. */
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) 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. */ peeked. */
pcOriginalReadPosition = pxQueue->u.pcReadFrom; pcOriginalReadPosition = pxQueue->u.pcReadFrom;
@ -1188,6 +1189,7 @@ xQUEUE *pxQueue;
pxQueue = ( xQUEUE * ) xQueue; pxQueue = ( xQUEUE * ) xQueue;
configASSERT( pxQueue ); configASSERT( pxQueue );
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
{ {
@ -1199,9 +1201,9 @@ xQUEUE *pxQueue;
prvCopyDataFromQueue( pxQueue, pvBuffer ); prvCopyDataFromQueue( pxQueue, pvBuffer );
--( pxQueue->uxMessagesWaiting ); --( pxQueue->uxMessagesWaiting );
/* If the queue is locked the event list will not be modified. /* If the queue is locked the event list will not be modified.
Instead update the lock count so the task that unlocks the queue Instead update the lock count so the task that unlocks the queue
will know that an ISR has removed data while the queue was will know that an ISR has removed data while the queue was
locked. */ locked. */
if( pxQueue->xRxLock == queueUNLOCKED ) if( pxQueue->xRxLock == queueUNLOCKED )
{ {
@ -1249,6 +1251,7 @@ xQUEUE *pxQueue;
pxQueue = ( xQUEUE * ) xQueue; pxQueue = ( xQUEUE * ) xQueue;
configASSERT( pxQueue ); configASSERT( pxQueue );
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
{ {
@ -1388,9 +1391,9 @@ static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, port
{ {
if( pxQueue->uxMessagesWaiting > 0 ) if( pxQueue->uxMessagesWaiting > 0 )
{ {
/* An item is not being added but overwritten, so subtract /* An item is not being added but overwritten, so subtract
one from the recorded number of items in the queue so when one from the recorded number of items in the queue so when
one is added again below the number of recorded items remains one is added again below the number of recorded items remains
correct. */ correct. */
--( pxQueue->uxMessagesWaiting ); --( pxQueue->uxMessagesWaiting );
} }

View File

@ -1176,6 +1176,7 @@ tskTCB * pxNewTCB;
unsigned portBASE_TYPE uxSavedInterruptStatus; unsigned portBASE_TYPE uxSavedInterruptStatus;
configASSERT( xTaskToResume ); configASSERT( xTaskToResume );
portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
pxTCB = ( tskTCB * ) xTaskToResume; pxTCB = ( tskTCB * ) xTaskToResume;
@ -1414,6 +1415,8 @@ portTickType xTaskGetTickCountFromISR( void )
portTickType xReturn; portTickType xReturn;
unsigned portBASE_TYPE uxSavedInterruptStatus; unsigned portBASE_TYPE uxSavedInterruptStatus;
portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
xReturn = xTickCount; xReturn = xTickCount;
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );