Implementation of the Priority Inheritance Protocol (PIP) in a Preemptive Real-Time Kernel
This project, developed for a course miniproject (Spring 2025), focuses on converting an existing fixed-priority preemptive Real-Time Operating System (RTOS) kernel into a dynamic-priority system to solve the critical Priority Inversion Problem.
We implemented the Priority Inheritance Protocol (PIP) by modifying the Mutex API and the core kernel scheduler to support dynamic priority promotion/demotion.
The project is configured for command-line compilation and debugging using VS Code, providing an alternative to the Eclipse IDE environment.
The following tools are required (on OSX arm) for development, compilation, and emulation:
- Visual Studio Code (VS Code)
- Extensions: C/C++ Extension Pack, Cortex-Debug
- ARM Toolchain: GCC and GDB (
arm-none-eabi-gcc) - QEMU: ARM system emulator
- Console Client: Netcat (
nc) ortelnet(for serial output)
brew install --cask gcc-arm-embedded
brew install qemuThe project uses a standard Makefile to manage the build process. This includes the correct linker script (kernel/ld.x) and compiler flags specifically for the Cortex-M7 target.
From the project root (mi11_ntr_full_p25_emu/), run:
make clean
make allThe debugging setup is designed to bypass the restrictive Cortex-Debug internal server. Instead, it connects GDB directly to QEMU via TCP, mirroring the "OpenOCD (via pipe)" method often used in Eclipse.
tasks.json: Contains a background task namedlaunch-qemu. This task executes the necessary QEMU command to emulate the target, opening the GDB port (3333) and the Serial port (1234).launch.json: Defines acppdbgconfiguration namedDebug QEMU via GDB. This configuration usesarm-none-eabi-gdband connects tolocalhost:3333. It ensures that thelaunch-qemutask runs first via thepreLaunchTasksetting.
-
Select the
Debug QEMU via GDBconfiguration in VS Code's Run and Debug tab. -
After QEMU starts, open a separate terminal and connect to the serial port to view the kernel's chronogram output:
nc localhost 1234The test program (noyau_test_mutex.c) is designed to use three tasks to simulate priority inversion, thereby demonstrating the effectiveness of the PIP implementation.
- Prio 16 (Prio 2): High Priority Task
- Prio 32 (Prio 4): Medium Priority Task
- Prio 48 (Prio 6): Low Priority Task
In this scenario, the low-priority task (Prio 48) holds the mutex. When the high-priority task (Prio 16) attempts to acquire the mutex and waits, the medium-priority task (Prio 32) preempts the low-priority task. This effectively extends the delay for the high-priority task indefinitely, showcasing the priority inversion problem.
With PIP enabled, when Task 16 blocks while waiting for the mutex, Task 48 immediately inherits priority 16. This ensures that Task 48 runs ahead of Task 32, allowing it to quickly release the critical resource and resolve the priority inversion.
Leopold C. (@leopoldch) Alexandre Eberhardt (@alexandreeberhardt)

