xQueueSendFromISR() & xQueueReceiveFromISR() causing configASSERT() failure in V8.2.3

Hi, I have a block of code for handling USART interrupts on an STM32F407 discovery board: ~~~~ void USART2IRQHandler( void ) { portBASETYPE 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

xQueueSendFromISR() & xQueueReceiveFromISR() causing configASSERT() failure in V8.2.3

I’m not sure what more I can say over and above the information provided in the comments of the code you have already posted…….you have an incorrect interrupt priority. You didn’t hit this assert before because the assert was added to the code after the older FreeRTOS version you were using, and it seems your code will always have had this bug but you were just lucky enough not to hit it – yet. More information is provided on the following link: http://www.freertos.org/RTOS-Cortex-M3-M4.html Regards.

xQueueSendFromISR() & xQueueReceiveFromISR() causing configASSERT() failure in V8.2.3

Thank you for getting back to me. I’ll take a look at the link you sent me, and I’ll let you know how I get on. Regards Andrew

xQueueSendFromISR() & xQueueReceiveFromISR() causing configASSERT() failure in V8.2.3

Hi, I have read through the link you have provided, and I’m still unclear what I’m doing wrong. I have attached my project. I have placed a couple of snippets of code which I beleive to be where my problem lies. In FreeRTOSConfig.h the relevent interrupt priority macros are defined as: ~~~~ /* Cortex-M specific definitions. */

ifdef __NVICPRIOBITS

/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
#define configPRIO_BITS             __NVIC_PRIO_BITS

else

#define configPRIO_BITS             4        /* 15 priority levels */

endif

/* The lowest interrupt priority that can be used in a call to a “set priority” function. */

define configLIBRARYLOWESTINTERRUPT_PRIORITY 0xf

/* The highest interrupt priority that can be used by any interrupt service routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER PRIORITY THAN THIS! (higher priorities are lower numeric values. */

define configLIBRARYMAXSYSCALLINTERRUPTPRIORITY 5

/* Interrupt priorities used by the kernel port layer itself. These are generic to all Cortex-M ports, and do not rely on any particular library functions. */

define configKERNELINTERRUPTPRIORITY ( configLIBRARYLOWESTINTERRUPTPRIORITY << (8 – configPRIOBITS) )

/* !!!! configMAXSYSCALLINTERRUPT_PRIORITY must not be set to zero !!!! See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */

define configMAXSYSCALLINTERRUPTPRIORITY ( configLIBRARYMAXSYSCALLINTERRUPTPRIORITY << (8 – configPRIOBITS) )

~~~~ In my serial.c file, the usart interrupts are set up with: ~~~~ NVICInitStructure.NVICIRQChannel = USART2IRQn; NVICInitStructure.NVICIRQChannelPreemptionPriority = configMAXSYSCALLINTERRUPTPRIORITY + 10; NVICInitStructure.NVICIRQChannelSubPriority = 0; // Not used as 4 bits are used for the pre-emption priority. NVICInitStructure.NVICIRQChannelCmd = ENABLE; NVICInit( &NVICInitStructure ); USARTITConfig( USART2, USARTIT_RXNE, ENABLE ); ~~~~ If I have understood the documentation correctly, then the usart interrupt priority should be well within the range of the interrupt priority limts. If I comment out xQueueSendFromISR() & xQueueReceiveFromISR() in my usart isr, the firmware does not hit configASSERT.

xQueueSendFromISR() & xQueueReceiveFromISR() causing configASSERT() failure in V8.2.3

Those priorities look ok. As you are using an STM32, have you also called NVICPriorityGroupConfig( NVICPriorityGroup_4 ); ?

xQueueSendFromISR() & xQueueReceiveFromISR() causing configASSERT() failure in V8.2.3

Hi, Thank you for your response. My target is not STM32. It is the KINETIS K64 series as stated in the original post. There are 4 tasks: OSATaskCreate(tasktwo,”tasktwo”,TASKONESTACKSIZE,0,6u,NULL,false,&tasktwotaskhandler); OSATaskCreate(vATask,”vATask”,TASKONESTACKSIZE,0,5u,NULL,false,&vATasktaskhandler); OSATaskCreate(vADifferentTask,”vADifferentTask”,TASKONESTACKSIZE,0,5u,NULL,false,&vADifferentTasktask_handler);
//create task
result = OSA_TaskCreate(task_one,
        (uint8_t *)"task_one",
        TASK_ONE_STACK_SIZE,
        0,
        6u,
        (task_param_t)0,
        false,
        &task_one_task_handler);

        and here:

        void vATask( void *pvParameters )
{ struct AMessage *pxMessage; uint32_t * test_ptr;
// Create a queue capable of containing 10 pointers to AMessage structures.
// These should be passed by pointer as they contain a lot of data.
xQueue = xQueueCreate( 16, sizeof( unsigned int*  ) );
if( xQueue == 0 )
{
    // Failed to create the queue.
}



// ...



// Send a pointer to a struct AMessage object.  Don't block if the
// queue is already full.
pxMessage = & xMessage;
test_ptr= &test_var;
xQueueSend( xQueue, ( void * )/* &pxMessage*/&test_ptr, ( TickType_t ) 0 );



// ... Rest of task code.
}

xQueueSendFromISR() & xQueueReceiveFromISR() causing configASSERT() failure in V8.2.3

Sorry my mistake. My reply doe not belong to the this original post.

xQueueSendFromISR() & xQueueReceiveFromISR() causing configASSERT() failure in V8.2.3

I have called NVICPriorityGroupConfig( NVICPriorityGroup_4 ); just before calling vTaskStartScheduler(); My main() function reads: ~~~~ int main( void ) {
HwInit();

vDebugInitQueue();
vDebugPrintf( "rnEPS Test1 0.0.1 - 1/4/2012rn" );
vDebugPrintResetType();

// Tasks get started here...
xTaskCreate( vTimeTask, (signed char *) "TIME", configMINIMAL_STACK_SIZE,
        NULL, mainTIME_TASK_PRIORITY, &hTimeTask );
xTaskCreate( vMemsTask, (signed char *) "MEMS", configMINIMAL_STACK_SIZE,
        NULL, mainMEMS_TASK_PRIORITY, &hMemsTask );
xTaskCreate( vDebugTask, (signed char *) “DEBUG”, configMINIMAL_STACK_SIZE, NULL, mainDEBUG_TASK_PRIORITY, &hDebugTask ); NVICPriorityGroupConfig( NVICPriorityGroup_4 );
vTaskStartScheduler(); // This should never return.

// Will only get here if there was insufficient memory to create
// the idle task.
for( ;; );  
} ~~~~ When I step into xQueueReceiveFromISR(), the code reaches vPortValidateInterruptPriority() as I would expect, then I get some results which I’m perplexed by. When asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); is called ulCurrentInterrupt is 32 which according to the stm32 reference manual is I2C1ER. The ISR which calls xQueueReceiveFromISR() is USART2IRQHandler(), and has a value of 38.

xQueueSendFromISR() & xQueueReceiveFromISR() causing configASSERT() failure in V8.2.3

Looks like it is not the interrupt you think, but be careful with the numbering in case the numbers are an index into the vector table or from the first non system interrupt.