FreeRTOS : xQueueSendFromISR

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

FreeRTOS : xQueueSendFromISR

2,962 Views
emvlabs
Contributor III

I want to message from ISR to Task.

So, My code is are below

I use i.MX RT1064

void IsrKeyEvent(char event, char data) {

/* We have not woken a task at the start of the ISR. */

    BaseType_t xHigherPriorityTaskWoken = pdFALSE;

    ISR_EVENT isrEvent;

    isrEvent.event = event;

    isrEvent.data = data; 

    xQueueSendFromISR( xQueueIsr, &isrEvent, &xHigherPriorityTaskWoken );

}

but always assert fail in vPortValidateInterruptPriority()

What's wrong ?

0 Kudos
Reply
2 Replies

2,894 Views
dmarks_ls
Senior Contributor I

Also, once you get your interrupt working, you'll want to add this line to the end of your ISR:

taskYIELD_FROM_ISR(xHigherPriorityTaskWoken);

You can read here for more information as to why this is required.

rtos - FreeRTOS: Why to call taskYIELD_FROM_ISR() method within the isrHandler - Stack Overflow 

0 Kudos
Reply

2,894 Views
dmarks_ls
Senior Contributor I

Most likely, you have not set the priority of that particular interrupt vector in the NVIC peripheral.  By default, all interrupt sources have a priority of 0 (which is the highest priority).  However, FreeRTOS needs to reserve at least the top-most interrupt priority for itself.  In FreeRTOSConfig.h, you'll find this line:

#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2‍

This defines the highest allowable priority for any interrupt that needs to call FreeRTOS functions, like your ISR does.  So in this example, the available priorities for your ISR would be 2, 3, 4... 15, 16.  You can have interrupts that are of higher priority (e.g. 0 or 1), but they must not call FreeRTOS API functions.

If you're not setting the interrupt priority, then the priority is 0 by default, and when you call xQueueSendFromISR(), the assert fails because your ISR has the same or higher priority as the RTOS.  You fix this by calling:

NVIC_SetPriority(irqn, priority);

where irqn is the identifier for your interrupt vector (e.g. GPIO1_INT0_IRQn) and priority is your interrupt priority, which numerically must be equal to or greater than configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY.  Do this prior to enabling your interrupt.  For instance, if I want to set the interrupt priority for LPUART2 to 4, I would write

NVIC_SetPriority(LPUART2_IRQn, 4);

Try that, I suspect that will fix your problem.

David R.