Ground Embedded KO Subscribe

Notes / RTOS

Priority inversion: when a low task blocks a high one

A high task stops because of a mutex held by a low task, and meanwhile a middle task takes the CPU. A Mars lander ran into this too.

GROUND EMBEDDED · NOTERTOS 06Priority inversionBUFFERhead →tail →write · read

Scenario

H (high)M (middle)L (low)H waitingL locksH wakesM runsL unlocksH runs
Priority inversion. H waits for the mutex L holds, but M pushes L aside, so H waits as long as M runs.
  1. L (low) takes the SPI mutex
  2. H (high) wakes, waits for the same mutex and goes Blocked
  3. M (middle) wakes. It is above L, so it preempts L
  4. While M runs for a long time, L cannot give the mutex back, and H waits indefinitely because of M

H has nothing to do with M and is still blocked by it. In 1997 Mars Pathfinder reset repeatedly because of this problem.

The fix: priority inheritance

H (high)M (middle)L (low)H waitingL locksH wakesH runsM runs
Priority inheritance. L rises briefly to H's priority, is not pushed aside by M, and returns the mutex quickly.

While H waits for a mutex that L holds, L's priority is temporarily raised to H's. Then M cannot preempt L, and L finishes quickly and returns the mutex. A FreeRTOS mutex (xSemaphoreCreateMutex) includes this feature, but a binary semaphore does not. Always use a mutex to protect a resource.

Avoiding it by design

  • Keep the sections that hold a mutex short
  • Give a shared resource to one owning task and have the others request through a queue
  • Priority ceiling protocol: on taking a resource, rise immediately to the priority of the highest task that uses it
3D LABRTOS Scheduler SimulationRun what this note explains and watch it respond.Open the lab →FREE PDFGet the 3 free ebooksIf you want to keep reading this topic as one book: BLDC motor control, serial communication and sensors at book length. PDFs are in Korean.Get them free →