Calling xTaskNotify or vTaskNotifyGiveFromISR after vTaskSuspendAll

I have the following use case:

vTaskSuspendAll();
// Work on some shared data
...
if (...) {  xTaskNotify(...); }
...
xTaskResumeAll()

Is it safe to call xTaskNotify with the scheduler suspended? There is no assertion check in Free RTOS against doing this. Is it OK if I call vTaskNotifyGiveFromISR instead (which seems to work for me)? I would want the notified task to be resumed when the xTaskResumeAll call is made, if it is higher priority than the calling task.

In the current code, the unblocked task will run when the next time the scheduler runs - which, in the worst case, may be the end of the tick period. Is it possible to re-factor your code like the below:

nofifyTask = pdFALSE;
vTaskSuspendAll();
// Work on some shared data
...
if (...) {  nofifyTask = pdTRUE; }
...
xTaskResumeAll()
if( nofifyTask == pdTRUE ) { xTaskNotify(...); }

Thanks.

Thanks for responding. I am surprised that the scheduler won’t be run when xTaskResumeAll is called, because that function has a return value to say whether a task switch occurred.

I can refactor the code like that, but I think that has a small disadvantage. If the task that is notified has a higher priority than the calling task, then ideally it should be woken up as soon as the xTaskResumeAll is made. However, with the refactoring, if a third task with a priority in between the two becomes ready before the xTaskResumeAll call, then that task will be scheduled immediately, and the higher priority task will not be run (because it hasn’t been notified yet).

Ignore my previous response. Which hardware are you running on? I tested it on a Cortex-M4 and the high priority task runs right away. Here is the sequence:

  1. xTaskGenericNotify unblocks the high priority task and puts it on the ready list: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/tasks.c#L4918
  2. It then pends a PendSV: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/tasks.c#L4943
  3. PendSV handler calls vTaskSwitchContext which finds that the scheduler is suspended and sets xYieldPending to true: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/tasks.c#L3016
  4. xTaskResumeAll sees that a yield is pending and pends the PendSV: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/tasks.c#L2295
  5. PendSV handler calls vTaskSwitchContext which schedules the high priority task.

Thanks.

1 Like

I am running the same code on ARM Cortex M0, ARM Cortex M4 and ARM Cortex M7. It sounds that it may work then!

I am currently calling vTaskNotifyGiveFromISR from the code during which scheduling is suspended, and ignoring the result.

Yes, it should and you should call xTaskNotify instead.

Thanks.