I need to stop task execution until event occurs. I detect this event in ISR. May I use vTaskSuspend(0) to suspend task and resume it later with vTaskResume() call from ISR. I’ve tried both cooperative and preemption modes, in both cases I’ve got similar results - the task does not work properly after resuming (in some cases stack is corrupted, other unexpected behaviour is also detected).
Before I dig in my code with bug search, I’d like to know is it legal to call vTaskResume from ISR. From what I saw in sources, it should be, but I didn’t found explicit statement which confirms this.
TaskResume can be used from an ISR provided the task being resumed has a priority less than the task that was interrupted.
The problem if the task being resumed has a priority higher than or equal to the current (interrupted) task is that a yield will be called. This cannot be done from an ISR. Each port provides a way of calling a yield at the end of the ISR function (portEND_SWITCHING_ISR macro in my case).
If you want to resume a task from an ISR then either block the task using a queue and unblock it using a queuesendfromisr() call but this is not efficient, or modify the code so that the vTaskResume() function does not call yield. If you want you can get vTaskResume to return a bool to say if a yield is required or not. This is the difference between queue send and queue send from isr.