Bird
Raised Fist0
FreeRTOSprogramming~7 mins

Priority inheritance behavior in FreeRTOS

Choose your learning style10 modes available
Introduction

Priority inheritance helps avoid delays caused by lower priority tasks holding resources needed by higher priority tasks.

When multiple tasks share a resource and have different priorities.
To prevent a low priority task from blocking a high priority task for too long.
When using mutexes to protect shared data in FreeRTOS.
To avoid priority inversion problems in real-time systems.
Syntax
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.

Examples
This example shows how a low priority task inherits a higher priority when holding a mutex needed by a higher priority task.
FreeRTOS
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);
Shows basic mutex take and give with priority inheritance handled automatically.
FreeRTOS
// Creating a mutex
SemaphoreHandle_t xMutex = xSemaphoreCreateMutex();

// In Task:
if(xSemaphoreTake(xMutex, (TickType_t)10) == pdTRUE) {
    // Access shared resource
    xSemaphoreGive(xMutex);
}
Sample Program

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.

FreeRTOS
#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;
}
OutputSuccess
Important Notes

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.

Summary

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

(1/5)
1. What is the main purpose of priority inheritance in FreeRTOS?
easy
A. To increase the priority of all tasks equally
B. To prevent low priority tasks from blocking high priority tasks for too long
C. To allow tasks to run in a random order
D. To disable task scheduling temporarily

Solution

  1. 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.
  2. 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.
  3. Final Answer:

    To prevent low priority tasks from blocking high priority tasks for too long -> Option B
  4. Quick Check:

    Priority inheritance prevents blocking = A [OK]
Hint: Priority inheritance helps high priority tasks run faster [OK]
Common Mistakes:
  • Thinking it raises all tasks' priorities
  • Confusing it with disabling scheduling
  • Believing it randomizes task order
2. Which FreeRTOS synchronization primitive automatically supports priority inheritance?
easy
A. Semaphore (binary)
B. Event group
C. Mutex
D. Queue

Solution

  1. Step 1: Identify synchronization primitives

    FreeRTOS offers semaphores, mutexes, queues, and event groups for task synchronization.
  2. Step 2: Check which supports priority inheritance

    Mutexes in FreeRTOS implement priority inheritance automatically to avoid priority inversion.
  3. Final Answer:

    Mutex -> Option C
  4. Quick Check:

    Mutex = priority inheritance support [OK]
Hint: Mutexes handle priority inheritance automatically [OK]
Common Mistakes:
  • Choosing binary semaphore which lacks priority inheritance
  • Confusing queues or event groups with mutexes
  • Assuming all synchronization primitives support priority inheritance
3. Consider three tasks: High, Medium, and Low priority. Low holds a mutex needed by High. Medium is ready to run. What happens when priority inheritance is enabled?
medium
A. Medium task runs before Low and High
B. Low task is blocked until Medium finishes
C. High task runs immediately, ignoring mutex
D. Low task inherits High priority, runs before Medium

Solution

  1. Step 1: Analyze priority inversion scenario

    Low priority task holds mutex needed by High priority task, but Medium priority task is ready.
  2. Step 2: Effect of priority inheritance

    Low task temporarily inherits High priority, so it runs before Medium to release mutex faster.
  3. Final Answer:

    Low task inherits High priority, runs before Medium -> Option D
  4. Quick Check:

    Priority inheritance boosts Low task priority = B [OK]
Hint: Low task runs at High priority to unblock High task [OK]
Common Mistakes:
  • Assuming Medium runs before Low despite inheritance
  • Thinking High runs without mutex
  • Believing Low is blocked by Medium
4. You wrote code using a binary semaphore to protect a shared resource, but high priority tasks are blocked too long. What is the likely issue?
medium
A. Binary semaphore does not support priority inheritance
B. Mutex was not created properly
C. High priority tasks are not using the semaphore
D. Task priorities are all equal

Solution

  1. Step 1: Identify synchronization primitive used

    Binary semaphore is used to protect shared resource.
  2. Step 2: Check priority inheritance support

    Binary semaphores do not support priority inheritance, causing priority inversion issues.
  3. Final Answer:

    Binary semaphore does not support priority inheritance -> Option A
  4. Quick Check:

    Binary semaphore lacks priority inheritance = A [OK]
Hint: Use mutex, not binary semaphore, for priority inheritance [OK]
Common Mistakes:
  • Assuming binary semaphore supports priority inheritance
  • Blaming task priorities without checking synchronization
  • Ignoring mutex creation correctness
5. In a system with tasks A (priority 3), B (priority 2), and C (priority 1), task C holds a mutex needed by A. Task B is CPU intensive. How does FreeRTOS priority inheritance help avoid priority inversion here?
hard
A. Task C temporarily inherits priority 3, preempting B to release mutex faster
B. Task B inherits priority 3 to run before C and A
C. Task A runs without waiting for mutex
D. Task C is blocked until B finishes

Solution

  1. 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.
  2. 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.
  3. Final Answer:

    Task C temporarily inherits priority 3, preempting B to release mutex faster -> Option A
  4. Quick Check:

    Priority inheritance boosts C to A's priority = C [OK]
Hint: Low priority task inherits high priority to beat medium task [OK]
Common Mistakes:
  • Thinking medium priority task inherits high priority
  • Assuming high priority task runs without mutex
  • Believing low priority task is blocked by medium task
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