Bird
Raised Fist0
FreeRTOSprogramming~10 mins

Task starvation and priority inversion in FreeRTOS - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Task starvation and priority inversion
Start Scheduler
↓
Multiple Tasks Ready
↓
Check Priorities
↓
Highest Priority Task Runs
↓
Lower Priority Tasks Wait
↓
If Resource Held by Low Priority Task
↓
Priority Inversion Occurs
↓
Priority Inheritance Boosts Low Priority Task
↓
Low Priority Task Releases Resource
↓
Normal Priorities Resume
↓
Starvation Avoided or Occurs if No Inheritance
↓
Scheduler Continues
The scheduler runs the highest priority task ready. If a low priority task holds a resource needed by a high priority task, priority inversion happens. Priority inheritance temporarily boosts the low priority task to avoid starvation.
Execution Sample
FreeRTOS
Task HighPriority:
  Wait(Resource)
  Run Critical Section
  Release(Resource)

Task LowPriority:
  Acquire(Resource)
  Run Long Task
  Release(Resource)
Two tasks with different priorities share a resource; the low priority task holds it while the high priority task waits, causing priority inversion.
Execution Table
StepTask RunningResource StatePriority ActionNotes
1LowPriorityResource Acquired by LowPriorityLowPriority runsLowPriority starts and acquires resource
2HighPriorityResource Held by LowPriorityHighPriority blocked, waitingHighPriority tries to acquire resource but blocks
3LowPriorityResource HeldPriority Inheritance: LowPriority boostedLowPriority priority boosted to HighPriority level
4LowPriorityResource HeldLowPriority runs fasterLowPriority continues and finishes critical section
5LowPriorityResource ReleasedPriority restored to LowLowPriority releases resource, priority back to normal
6HighPriorityResource FreeHighPriority runsHighPriority acquires resource and runs
7IdleResource FreeNo tasks readyAll tasks done or waiting, scheduler idle
💡 HighPriority task acquires resource after LowPriority releases it, ending priority inversion
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3After Step 4After Step 5After Step 6Final
LowPriority PriorityLowLowLowBoosted to HighBoosted to HighRestored to LowLowLow
HighPriority StateReadyReadyBlockedBlockedBlockedReadyRunningDone
Resource StateFreeHeld by LowPriorityHeld by LowPriorityHeld by LowPriorityHeld by LowPriorityFreeAcquired by HighPriorityFree
Key Moments - 3 Insights
Why does the HighPriority task wait even though it has higher priority?
Because the resource it needs is held by the LowPriority task, so HighPriority blocks until the resource is free (see execution_table step 2).
How does priority inheritance help avoid starvation?
It temporarily raises the LowPriority task's priority to match HighPriority, letting it finish faster and release the resource (see execution_table step 3 and 4).
What happens if priority inheritance is not used?
The LowPriority task runs at low priority and may be delayed by other tasks, causing HighPriority to wait indefinitely (starvation).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table at step 3, what happens to the LowPriority task's priority?
AIt is boosted to HighPriority level
BIt stays low
CIt becomes idle
DIt is blocked
💡 Hint
Check the 'Priority Action' column at step 3 in the execution_table
At which step does the HighPriority task stop being blocked?
AStep 2
BStep 4
CStep 6
DStep 1
💡 Hint
Look at the 'HighPriority State' in variable_tracker and 'Task Running' in execution_table
If the LowPriority task never releases the resource, what happens to the HighPriority task?
AIt runs normally
BIt starves and never runs
CIt lowers its priority
DIt releases the resource itself
💡 Hint
Consider the blocking state of HighPriority in execution_table step 2 and the concept of starvation
Concept Snapshot
Task starvation happens when low priority tasks block high priority ones.
Priority inversion occurs when a low priority task holds a resource needed by a high priority task.
Priority inheritance temporarily boosts the low priority task's priority.
This helps avoid starvation and lets the high priority task run sooner.
FreeRTOS uses this to manage shared resources safely.
Full Transcript
In FreeRTOS, tasks have priorities. The scheduler runs the highest priority task ready. When a low priority task holds a resource needed by a high priority task, the high priority task waits, causing priority inversion. Priority inheritance boosts the low priority task's priority temporarily so it can finish and release the resource faster. This avoids starvation of the high priority task. The execution trace shows the low priority task acquiring the resource, the high priority task blocking, the priority boost, and finally the resource release and high priority task running. Without priority inheritance, the high priority task could wait forever if the low priority task is delayed.

Practice

(1/5)
1. What does task starvation mean in FreeRTOS?
easy
A. Some tasks never get CPU time because others run too much
B. All tasks get equal CPU time regardless of priority
C. Tasks run in a random order without priority
D. Tasks share CPU time only when a mutex is free

Solution

  1. Step 1: Understand task scheduling in FreeRTOS

    FreeRTOS schedules tasks based on priority, so higher priority tasks run more often.
  2. Step 2: Define task starvation

    Task starvation happens when low priority tasks never get CPU time because higher priority tasks keep running.
  3. Final Answer:

    Some tasks never get CPU time because others run too much -> Option A
  4. Quick Check:

    Task starvation = some tasks starve for CPU [OK]
Hint: Starvation means some tasks get no CPU time [OK]
Common Mistakes:
  • Confusing starvation with equal CPU sharing
  • Thinking tasks run randomly
  • Assuming mutex controls CPU time directly
2. Which FreeRTOS API is used to create a mutex that supports priority inheritance?
easy
A. xQueueCreate()
B. xSemaphoreCreateMutex()
C. vTaskDelay()
D. xTaskCreate()

Solution

  1. Step 1: Identify mutex creation functions

    FreeRTOS uses xSemaphoreCreateMutex() to create mutexes with priority inheritance.
  2. Step 2: Differentiate other APIs

    xQueueCreate() creates queues, vTaskDelay() delays tasks, and xTaskCreate() creates tasks, not mutexes.
  3. Final Answer:

    xSemaphoreCreateMutex() -> Option B
  4. Quick Check:

    Mutex with priority inheritance = xSemaphoreCreateMutex() [OK]
Hint: Mutex with priority inheritance uses xSemaphoreCreateMutex() [OK]
Common Mistakes:
  • Choosing xQueueCreate() for mutex
  • Confusing task creation with mutex creation
  • Using delay functions instead of mutex APIs
3. Given three tasks with priorities High (3), Medium (2), and Low (1). Low task holds a mutex needed by High task. What happens without priority inheritance?
medium
A. Medium task is blocked until High task finishes
B. Low task immediately releases the mutex
C. High task waits indefinitely while Medium task runs
D. High task preempts Low task and runs

Solution

  1. Step 1: Understand priority inversion scenario

    Low priority task holds mutex needed by High priority task, so High task blocks waiting.
  2. Step 2: Effect without priority inheritance

    Medium priority task runs, preventing Low task from running and releasing mutex, causing High task to wait indefinitely.
  3. Final Answer:

    High task waits indefinitely while Medium task runs -> Option C
  4. Quick Check:

    Priority inversion without inheritance = High task blocked [OK]
Hint: Without inheritance, medium task blocks low task, blocking high task [OK]
Common Mistakes:
  • Assuming low task releases mutex immediately
  • Thinking high task preempts low task despite mutex
  • Believing medium task is blocked
4. Identify the problem in this FreeRTOS code snippet causing priority inversion:
void lowTask(void *pvParameters) {
  xSemaphoreTake(mutex, portMAX_DELAY);
  // long processing
  xSemaphoreGive(mutex);
  vTaskDelete(NULL);
}

void highTask(void *pvParameters) {
  xSemaphoreTake(mutex, portMAX_DELAY);
  // quick processing
  xSemaphoreGive(mutex);
  vTaskDelete(NULL);
}
medium
A. Mutex created without priority inheritance support
B. High task does not take the mutex
C. Low task never releases the mutex
D. Tasks have the same priority

Solution

  1. Step 1: Analyze mutex usage in code

    Both tasks take and give the mutex correctly, so no misuse in code logic.
  2. Step 2: Check for priority inversion cause

    If mutex was created without priority inheritance, low task holding mutex blocks high task causing priority inversion.
  3. Final Answer:

    Mutex created without priority inheritance support -> Option A
  4. Quick Check:

    Priority inversion fix needs mutex with priority inheritance [OK]
Hint: Check if mutex supports priority inheritance to fix inversion [OK]
Common Mistakes:
  • Assuming high task does not take mutex
  • Thinking low task never releases mutex
  • Believing tasks have same priority
5. How can you prevent task starvation and priority inversion in a FreeRTOS system with multiple tasks sharing resources?
hard
A. Use busy-wait loops in low priority tasks to keep CPU busy
B. Assign all tasks the same priority to avoid conflicts
C. Avoid using any synchronization primitives like mutexes
D. Use mutexes with priority inheritance and design balanced task priorities

Solution

  1. Step 1: Understand causes of starvation and inversion

    Starvation happens when low priority tasks never run; inversion when low priority blocks high priority.
  2. Step 2: Apply solutions in FreeRTOS

    Using mutexes with priority inheritance prevents inversion; balanced priorities avoid starvation.
  3. Final Answer:

    Use mutexes with priority inheritance and design balanced task priorities -> Option D
  4. Quick Check:

    Priority inheritance + balanced priorities prevent issues [OK]
Hint: Combine priority inheritance mutexes with balanced priorities [OK]
Common Mistakes:
  • Setting all tasks to same priority causing inefficiency
  • Avoiding mutexes causing race conditions
  • Using busy-wait wastes CPU and worsens starvation
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard