Hi all,
Recently, I use Segger RTT SystemViewe to monitoring my project. I found there is something wrong after giving a semaphore to a task from a Timer ISR. As the following code shows:
One can see that an Timer Interrupt(ISR123) gave a semaphore to Sen_T. After that the Sen_T is blocked serveral microseconds.
The blocked time is uncertain.
It looks like your call to portYIELD_FROM_ISR() isn’t working. The one you posted doesn’t seem right – I don’t see xReturn defined anywhere. I think you meant this:
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
Also, importantly, you must initialize xHigherPriorityTaskWoken to pdFALSE.
Best if you clean up xHigherPriorityTaskWoken just a little bit more.
Function xSemaphoreGiveFromISR() cannot set xHigherPriorityTaskWoken to pdFALSE. It either sets xHigherPriorityTaskWoken to pdTRUE or leaves it unchanged. All of the FromISR() functions that can unblock a task follow the same pattern. Because of this pattern, your code should initialize xHigherPriorityTaskWoken to pdFALSE at the beginning of the ISR code that can wake a task.
In your specific case here, this change may not make a functional difference because every time the ISR runs you actually do wake a higher-priority task. But it’s good to get used to following the pattern so you’ll always induce a yield operation when needed, and only when needed, regardless of your task priorities and timing.
I would NOT make the woken flag a non-local variable, as it should NOT be shared among interrupts. Each interrupt should initialize its flag at start, so if an ISR gets interrupted after setting the flag, but before returning, you might miss that wakeup request.