
Hello everyone, I am the Intelligence Guy~
During the development of RTOS, you must have encountered the issue of priority inversion, where a low-priority task is preempted by a higher-priority task due to shared resource access. This contradicts the real-time performance of a preemptive kernel. The core of solving the priority inversion problem in RTOS lies inmanaging access to shared resources, especially the strategy for using mutexes. Currently, mainstream RTOSs have integrated optimization measures for priority inversion strategies, although each has its own variations. The main solutions to this problem are as follows:
1. Root Cause
Priority inversion refers to:
- Low-priority task (L) holds a mutex to access a shared resource.
- Medium-priority task (M) preempts L but does not need that resource.
- High-priority task (H) starts and waits for that lock, becoming blocked.
- M continues to run, causing H to be forced to wait for M and L, violating real-time constraints.
2. Various Mainstream Solutions
1. Priority Inheritance Protocol
The principle of its implementation is: when a high-priority task (H) is blocked because a low-priority task (L) holds the lock, L’s priority is temporarily raised to match that of H.
This allows the low-priority task to quickly complete and release the lock, preventing the medium-priority task (M) from preempting L. Most modern RTOSs (such as FreeRTOS, µC/OS) have built-in support for this. For example, FreeRTOS creates a mutex that supports priority inheritance, automatically triggering priority inheritance when requesting the lock.
2. Priority Ceiling Protocol
This solution allows for each mutex to have a preset priority ceiling, which automatically raises the priority of the task holding the lock to the ceiling value. The ceiling priority must be higher than the priority of all tasks that may request that lock. This avoids the dynamic adjustment of priority inheritance.
Thus, this solution can completely prevent inversion and has no risk of deadlock. For example, in VxWorks, you can use <span><span>pthread_mutexattr_setprioceiling()</span></span>
3. Time-Bound Protocol
This sets a maximum blocking time for tasks (<span><span>xBlockTime</span></span>), and if it times out, it either abandons the request or executes error handling. The core idea is to set a maximum blocking time for resource requests. When a high-priority task waits for a lock beyond a preset threshold, the system forcibly triggers a timeout handling mechanism to avoid indefinite blocking.
- Implementation:
// FreeRTOS example (in ticks)
const TickType_t timeout_ticks = pdMS_TO_TICKS(5); // 5ms timeout
if (xSemaphoreTake(mutex, timeout_ticks) == pdPASS) {
// Successfully acquired lock → access shared resource
xSemaphoreGive(mutex);
} else {
// Timeout handling branch
_handle_lock_timeout();
}
- Applicable Scenarios: Systems with strict response time constraints (e.g., automotive ECUs).
Although RTOS provides some API interfaces and strategies to optimize such issues, we can actually avoid these problems to some extent during the early stages of our design. The most important thing is to avoid high-priority tasks depending on low-priority resources by designing to circumvent lock dependency chains. Of course, you can minimize critical sections to shorten lock holding times; since locks introduce issues, you can also use lock-free data structures to avoid this problem.
Finally
I have collected some embedded learning materials. Reply with 【1024】 in the public account to find the download link!
Recommended good articles. Click the blue text to jump
☞ Collection | Comprehensive Programming of Linux Applications
☞ Collection | Learn Some Networking Knowledge
☞ Collection | Handwritten C Language
☞ Collection | Handwritten C++ Language
☞ Collection | Experience Sharing
☞ Collection | From Microcontrollers to Linux
☞ Collection | Power Control Technology
☞ Collection | Essential Mathematics for Embedded Systems
☞ Collection | MCU Advanced Collection
☞ Collection | Embedded C Language Advanced Collection