dcrocker wrote on Monday, September 10, 2018:
I had some strange behaviourwhen trying to use these functions. My main task (task1) was doing this:
vTaskSuspend(task2handle);
... // store some variables that task2 will read
vTaskResume(task2handle);
task2 has a higher priority than task1, and task2 spends most of its time waiting for an interrupt, by calling ulTaskNotifyTake. The ISR does this:
BaseType_t higherPriorityTaskWoken = pdFALSE;
vTaskNotifyGiveFromISR(task2handle, &higherPriorityTaskWoken);
portYIELD_FROM_ISR(higherPriorityTaskWoken);
What I find it that if task1 runs in a loop making the suspend/resume call and doing other stuff as well, but never blocking, task2 doesn’t run. If I put a delay call in the task1 loop, then task2 runs sporadically. If I replace the vTaskSuspend call by taskENTER_CRITICAL() and vTaskResume by taskEXIT_CRITICAL() then the program runs correctly, even without the delay call in the task1 loop.
There is one more task in the system: task3, which has the same priority as task2 and also spends most of its time either waiting for an interrupt or delaying.
What am I doing wrong? I was expecting vTaskSuspend and vTaskResume to behave similarly to taskENTER_CRITICAL() and taskEXIT_CRITICAL() with respect to when task2 does and doesn’t run. In particular, if the interrupt occurs when task2 has been suspended by the call to vTaskSuspend(task2handle), I was expecting task2 to be scheduled when task1 makes the vTaskResume(task2handle) call. Or do I need to take some special action to tell the scheduler to schedule task2 if this happens, the same way I have to in the ISR?
I’m using FreeRTOS 10.0.0 built for ARM_CM4F.