What I understand is that a task does not enter the Blocked state only when ‘vTaskDelay()’ is called. Instead, a task goes into the Blocked state whenever it is waiting for something, such as a delay, mutex, semaphore, queue, or any event.
For example:
If Task A calls ‘vTaskDelay()’, then Task A enters the Blocked state waiting for time to expire, while Task B can continue executing or remain in the Ready state.
If a low-priority Task A holds a mutex, and a higher-priority Task B tries to take that mutex, then Task B enters the Blocked state until Task A releases it (even though Task B has higher priority).
If Task A has taken a semaphore, and a higher-priority Task B tries to take the same semaphore, then Task B will enter the Blocked state if the semaphore is not available.
If Task A is expected to send data to a queue, and a higher-priority Task B tries to receive from that queue when it is empty, then Task B enters the Blocked state until Task A sends data.
my understanding is that task priority does not affect whether a task enters the Blocked state even a high-priority task will be blocked if the required resource is unavailable.
So, ‘vTaskDelay()’ is just one of the ways to move a task to the Blocked state, not the only condition.
Could you please confirm if this understanding is correct?
I am trying to understand when task priority actually matters in FreeRTOS. Specifically, I want to understand the interaction between Task A and Task C in these scenarios.
If Task A (low priority) is holding a mutex, and Task C (high priority) becomes ready but does not need that mutex, then Task C should preempt Task A and run immediately (not blocked).
If Task A (low priority) has taken a semaphore, and Task C (high priority) does not need that semaphore, then Task C should also preempt Task A and run immediately (not blocked).
If Task A (low priority) is working with a queue, and Task C (high priority) does not depend on that queue, then Task C should again preempt Task A and run immediately (not blocked).
From my understanding, since Task C (high priority) is not waiting for any resource in these cases, it should remain in the Ready state and preempt Task A (low priority) due to higher priority.
The basic rule is that the Scheduler will run the highest-priority task that is “ready” to run (not blocking or suspended). If two tasks have the same priority, the task that hasn’t been run for the longest time will be chosen.
The Scheduler will be run in the following conditions:
The current task becomes not-ready for some reason.
The Tick Interrupt occurs
Something happens that makes ready a task of a higher priority than the current task, either by the action of the current task or an interrupt.
So, one prerequisite to all your conditions was that something had to be making Task C not-ready, and that just went away, or it would have been running already.