xTaskNotifyWait wake-up with a delay

yevpator75 wrote on Thursday, February 14, 2019:

Hello,
I would like to ask about task notifications.
I have a UART DMA transfer and when it is done, from the interrupt context I send a notification to a waiting task :

uint32_t
sts = xTaskNotifyFromISR (gp_uartTxLogHandle,UART_TX_FREE_NOTIF_VAL, eSetBits, pdFALSE);

In the waiting task I have the following:

notifyRetVal = xTaskNotifyWait (0,TASK_NOTIF_BITS_TO_CLEAR,&val, UART_TX_DMA_BUSY_TIMEOUT);

The problem is that the waiting task unblocks always with a long latency. I see on the oscilloscope that the unblocking happens only after a new RTOS tick passes. The notifyRetVal , which I mentioned in the code above, is pdTRUE.
I checked in the User Manual and didn’t find there any mentioning that it should behave like I am observing now. I expect that when I send a notification , the blocking task should unblock immediately, given there is no any other task with a higher priority.

Thanks in advance for any help!

richard_damon wrote on Thursday, February 14, 2019:

The last paramater, which you are passing a pdFALSE, is normally supposed to be a pointer to a variable that the ISR passes in, that the notify will set true if something was woken. The ISR is then supposed to at its end, test this and cause the scheduler to run if needed, causing an immediate switch. pdFALSE, is 0, so it looks like a NULL pointer, which means the result isn’t returned, then the ISR never causes the scheduler to run, so until some other interrupt occures (like the timer) that does run the scheduler, the current running task doesn’t change.

yevpator75 wrote on Thursday, February 14, 2019:

Thank you Richard.
Now I see I indeed improperly interpreted the last parameter, as you explained above.
Every time I call notifyFromISR , i should then call portYIELD_FROM_ISR( xHigherPriorityTaskWoken );

richarddamon wrote on Friday, February 15, 2019:

You don’txxxFROM need a portYIELD_FROM_ISR for each xxxFromISR call, but should have one at the end of every ISR that uses functions that might unblock a task. On some ports it doesn’t matter where the portYIED_FROM_ISR statement is, but on others it needs to be at the very end.