ajellisuk wrote on Friday, February 19, 2016:
Hi,
I have a block of code for handling USART interrupts on an STM32F407 discovery board:
void USART2_IRQHandler( void )
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
portCHAR cChar;
if( USART_GetITStatus( USART2, USART_IT_TXE ) == SET )
{
/* The interrupt was caused by the TX register becoming empty. Are
there any more characters to transmit? */
if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE )
{
// A character was retrieved from the queue so can be sent to the
// USART now.
USART_SendData( USART2, cChar );
}
else
{
USART_ITConfig( USART2, USART_IT_TXE, DISABLE );
}
}
if( USART_GetITStatus( USART2, USART_IT_RXNE ) == SET )
{
/* A character has been received on the USART, send it to the Rx
handler task. */
cChar = USART_ReceiveData( USART2 );
xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken );
}
/* If sending or receiving from a queue has caused a task to unblock, and
the unblocked task has a priority equal to or higher than the currently
running task (the task this ISR interrupted), then xHigherPriorityTaskWoken
will have automatically been set to pdTRUE within the queue send or receive
function. portEND_SWITCHING_ISR() will then ensure that this ISR returns
directly to the higher priority unblocked task. */
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
Previously I was using V7.1.0, which is available through CooCox. The code worked fine with this version of FreeRTOS, but I needed to upgrade to V8.2.3 so that I could access some of the new features, such as xTaskNotify. When I try and run my firmware, whenever either of the aforementioned functions are used, my firmware ends up hitting configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); in the following block of code:
#if( configASSERT_DEFINED == 1 )
void vPortValidateInterruptPriority( void )
{
uint32_t ulCurrentInterrupt;
uint8_t 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 the application only uses CMSIS libraries for interrupt
configuration then the correct setting can be achieved on all Cortex-M
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
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 */
Can anyone suggest what the issue is here please? As I say the code worked fine with an older version of FreeRTOS, so is there something extra I need to use xQueueSendFromISR() & xQueueReceiveFromISR() in later versions of FreeRTOS.
Thanks
Andrew