cancel
Showing results for 
Search instead for 
Did you mean: 

ISR blocked due wrong "Deferred Interrupt Handling" implementation in CMSIS RTOS2?

regjoe
Senior

Hello,

I'm hunting a bug probably caused by a race condition running multiple tasks and IRQ handlers under FreeRTOS on a STM32H75x MCU.

My code shall run a task after (DMA-) IRQ has fired using the Deferred Interrupt Handling method shown in this example   using the CMSIS2 RTOS API. In rare situations, it seems that the task is started delayed, maybe blocked by another task of same priority.

All (DMA-/UART-/TIMER) IRQs have prio 5, all tasks have FreeRTOS prio "REALTIME".

The FreeRTOS example (comments removed) goes like this:

void vANInterruptHandler( void )
{
    BaseType_t xHigherPriorityTaskWoken;

    prvClearInterruptSource();

    xHigherPriorityTaskWoken = pdFALSE;

    vTaskNotifyGiveFromISR( xHandlingTask, &xHigherPriorityTaskWoken );

    portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}

I wonder how this can be implemented using the CMSIS RTOS API2.

My code, according to this example here, goes quite as follows:

void IrqHandler(void) {  
    osEventFlagsSet(evt_id, 0x00000001U);
    // osThreadYield();
}

I wonder if this code is the correct translation/implementation of the FreeRTOS code above. Most certainly not, but I do not know what CMSIS RTOS function matches the portYIELD_FROM_ISR.

According to the documentation, osEventFlagSet() can be called in ISR function but osThreadYield() not, so I wonder what is the appropriate CMSIS implementation.

Any idea?

Thanks in advance

 

1 ACCEPTED SOLUTION

Accepted Solutions
Saket_Om
ST Employee

Hello @regjoe 

  • If you need the signaled task to run immediately, make sure it has a higher priority than other tasks.
  • If tasks have the same priority, the scheduler will not preempt the currently running task just because an event flag was set.
  • Do not call osThreadYield() in the ISR. It's not ISR-safe and not needed.
To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om

View solution in original post

3 REPLIES 3
Saket_Om
ST Employee

Hello @regjoe 

  • If you need the signaled task to run immediately, make sure it has a higher priority than other tasks.
  • If tasks have the same priority, the scheduler will not preempt the currently running task just because an event flag was set.
  • Do not call osThreadYield() in the ISR. It's not ISR-safe and not needed.
To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om

Hello @Saket_Om 

I've 5 tasks to poll a lots of devices connected to 5 RS485 busses, so all tasks must have same prio. According to your answer, I think it is best to put all real time stuff into IRQ handler(s) and put all uncritical code into tasks triggered by IRQ handler.

Can you pls explain or pass me a link why osThreadYield() is not needed at IRQ exit but portYIELD() is required?

 

  

Hello @regjoe 

Please look to the link below:

CMSIS-RTOS2: Thread Management

It is mentioned that the osThreadYield() function cannot be called from ISR.

Saket_Om_0-1757076052328.png

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om