There was a thread about this recently. You might want to look it up.
It can be that you block waiting to get a semaphore. The semaphore becomes available and unblocks the task. Because of the prioritization of your tasks the unblocked task although now able to run does not run before another task has again taken the semaphore. When the unblocked task does run it finds the semaphore already gone again and returns false.
There are a couple of ways around this. Change the prioritisation of your tasks so this cannot happen. Change the test to see if a switch should happen to say a switch occurs if a woken task has a priority greater or equal to the current task (by default a switch is performed if the woken task is *greater* than the current task only). Finally put the call to xSemaphoreTake within a while statement as: