Priority inheritance helps avoid delays caused by lower priority tasks holding resources needed by higher priority tasks.
Priority inheritance behavior in FreeRTOS
xSemaphoreCreateMutex(); // Use xSemaphoreTake() and xSemaphoreGive() to lock and unlock the mutex // FreeRTOS automatically handles priority inheritance for mutexes
Priority inheritance is automatic when using FreeRTOS mutexes.
Use mutexes (not binary semaphores) to get priority inheritance behavior.
SemaphoreHandle_t xMutex = xSemaphoreCreateMutex(); // Task A (low priority) takes the mutex xSemaphoreTake(xMutex, portMAX_DELAY); // Task B (high priority) tries to take the mutex and blocks xSemaphoreTake(xMutex, portMAX_DELAY); // Task A inherits Task B's priority until it gives the mutex xSemaphoreGive(xMutex);
// Creating a mutex SemaphoreHandle_t xMutex = xSemaphoreCreateMutex(); // In Task: if(xSemaphoreTake(xMutex, (TickType_t)10) == pdTRUE) { // Access shared resource xSemaphoreGive(xMutex); }
This program creates two tasks with different priorities sharing a mutex. The low priority task takes the mutex first. When the high priority task tries to take it, the low priority task inherits the higher priority until it releases the mutex. The printed messages show the order of events.
#include "FreeRTOS.h" #include "task.h" #include "semphr.h" #include <stdio.h> SemaphoreHandle_t xMutex; void vLowPriorityTask(void *pvParameters) { while(1) { if(xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE) { printf("Low priority task took the mutex\n"); // Simulate work vTaskDelay(pdMS_TO_TICKS(2000)); printf("Low priority task giving the mutex\n"); xSemaphoreGive(xMutex); vTaskDelay(pdMS_TO_TICKS(1000)); } } } void vHighPriorityTask(void *pvParameters) { vTaskDelay(pdMS_TO_TICKS(500)); // Delay to let low priority task take mutex first while(1) { printf("High priority task trying to take mutex\n"); if(xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE) { printf("High priority task took the mutex\n"); xSemaphoreGive(xMutex); vTaskDelay(pdMS_TO_TICKS(1000)); } } } int main(void) { xMutex = xSemaphoreCreateMutex(); if(xMutex == NULL) { printf("Mutex creation failed\n"); return 1; } xTaskCreate(vLowPriorityTask, "LowPriority", 1000, NULL, 1, NULL); xTaskCreate(vHighPriorityTask, "HighPriority", 1000, NULL, 3, NULL); vTaskStartScheduler(); // Should never reach here for(;;); return 0; }
Priority inheritance only works with mutexes, not with binary semaphores.
Always use portMAX_DELAY or a suitable timeout when taking mutexes to avoid deadlocks.
Priority inheritance helps prevent priority inversion but can increase complexity in scheduling.
Priority inheritance prevents low priority tasks from blocking high priority tasks too long.
FreeRTOS handles priority inheritance automatically when using mutexes.
Use mutexes to protect shared resources and avoid priority inversion problems.
Practice
Solution
Step 1: Understand priority inversion problem
Priority inversion happens when a low priority task holds a resource needed by a high priority task, causing delays.Step 2: Role of priority inheritance
Priority inheritance temporarily raises the low priority task's priority to the high priority task's level to reduce blocking time.Final Answer:
To prevent low priority tasks from blocking high priority tasks for too long -> Option BQuick Check:
Priority inheritance prevents blocking = A [OK]
- Thinking it raises all tasks' priorities
- Confusing it with disabling scheduling
- Believing it randomizes task order
Solution
Step 1: Identify synchronization primitives
FreeRTOS offers semaphores, mutexes, queues, and event groups for task synchronization.Step 2: Check which supports priority inheritance
Mutexes in FreeRTOS implement priority inheritance automatically to avoid priority inversion.Final Answer:
Mutex -> Option CQuick Check:
Mutex = priority inheritance support [OK]
- Choosing binary semaphore which lacks priority inheritance
- Confusing queues or event groups with mutexes
- Assuming all synchronization primitives support priority inheritance
Solution
Step 1: Analyze priority inversion scenario
Low priority task holds mutex needed by High priority task, but Medium priority task is ready.Step 2: Effect of priority inheritance
Low task temporarily inherits High priority, so it runs before Medium to release mutex faster.Final Answer:
Low task inherits High priority, runs before Medium -> Option DQuick Check:
Priority inheritance boosts Low task priority = B [OK]
- Assuming Medium runs before Low despite inheritance
- Thinking High runs without mutex
- Believing Low is blocked by Medium
Solution
Step 1: Identify synchronization primitive used
Binary semaphore is used to protect shared resource.Step 2: Check priority inheritance support
Binary semaphores do not support priority inheritance, causing priority inversion issues.Final Answer:
Binary semaphore does not support priority inheritance -> Option AQuick Check:
Binary semaphore lacks priority inheritance = A [OK]
- Assuming binary semaphore supports priority inheritance
- Blaming task priorities without checking synchronization
- Ignoring mutex creation correctness
Solution
Step 1: Understand task priorities and mutex ownership
Task C (low priority) holds mutex needed by Task A (high priority), while Task B (medium priority) is CPU intensive.Step 2: Apply priority inheritance behavior
Task C inherits Task A's high priority (3) temporarily, allowing it to preempt Task B and release the mutex quickly.Final Answer:
Task C temporarily inherits priority 3, preempting B to release mutex faster -> Option AQuick Check:
Priority inheritance boosts C to A's priority = C [OK]
- Thinking medium priority task inherits high priority
- Assuming high priority task runs without mutex
- Believing low priority task is blocked by medium task
Ready to prove it?
Pass the test and this pattern moves unknown
