I tried calling ulTaskNotifyTake(pdTRUE, portMAX_DELAY) after calling vTaskSuspendAll(); It happened that the ulTaskNotifyTake() returned immediately as per timeout.
Ok, after reading the vTaskSuspendAll() page I remembered I couldn’t do that. But I did get some questions:
If vTaskSuspendAll() suspends the scheduler but not the interrupts, why keep the RTOS ticks pending?
The behavior of vTaskSuspendAll() I wanted it to wait and exit after a call to vTaskNotifyGiveFromISR() from an interrupt. What I could expect was that an assert would be triggered due to an attempted context switch (caused by ulTaskNotifyTake) with a suspended scheduler. What happens is none of this. Is that correct?
The call to ulTaskNotifyTake() takes place inside a function called from other parts of the code, and for a sequence of events it can happen that this function is called with suspended scheduler. How can I get around the problem?
As a general rule API functions that can cause a context switch cannot
be called from a critical section or with the scheduler suspended as the
context switch cannot actually happen, which results in logic errors.
From your post I think you realise this already.
If a context switch is attempted from an interrupt then the context
switch should be held pending until such time that the scheduler is
unsuspended. That mechanism works by placing the task that was
unblocked into a ‘pending ready’ list, then moving all tasks from the
‘pending ready’ list into their appropriate ‘ready’ list in the
unsuspend function. It is not clear to me, but are you saying that
mechanism is not working in the case of a task notification?
As a general rule API functions that can cause a context switch cannot
be called from a critical section or with the scheduler suspended as the
context switch cannot actually happen, which results in logic errors.
what does it means by “logic errors”? Should this case be
reported/protected with configASSERT?
unsuspend function. It is not clear to me, but are you saying that
mechanism is not working in the case of a task notification?
If the scheduler isn’t running, then a task can not block as that requires the sceduler to switch to another task to run. From the documentation of vTaskSuspendAll():
API functions that have the potential to cause a context switch (for example, vTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler is suspended.
As a general rule API functions that can cause a context switch cannot
be called from a critical section or with the scheduler suspended as the
context switch cannot actually happen, which results in logic errors.