embedded runtime_error ai_generated true

FreeRTOS: Mutex deadlock detected in task 'SensorTask' waiting for semaphore 0x2000ABCD, held by 'ControlTask' (blocked for 5000 ms)

ID: embedded/freertos-mutex-deadlock

Also available as: JSON · Markdown · 中文
88%Fix Rate
87%Confidence
1Evidence
2024-05-20First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
FreeRTOS Kernel V10.5.1 active
FreeRTOS Kernel V11.0.0 active
STM32Cube_FW_F4_V1.27.1 active

Root Cause

Two or more tasks are waiting indefinitely for mutexes held by each other, typically due to incorrect locking order or missing timeout in priority inversion scenarios.

generic

中文

两个或多个任务无限期等待对方持有的互斥锁,通常由于锁定顺序不正确或在优先级反转场景中缺少超时引起。

Official Documentation

https://www.freertos.org/Documentation/02-Kernel/02-API-reference/01-Queues/01-xQueueSemaphoreTake

Workarounds

  1. 90% success Implement a consistent lock ordering: always acquire mutexes in the same order (e.g., SensorMutex before ControlMutex) across all tasks.
    Implement a consistent lock ordering: always acquire mutexes in the same order (e.g., SensorMutex before ControlMutex) across all tasks.
  2. 85% success Add a timeout to semaphore takes (e.g., 100 ms) and release all held mutexes on timeout, then retry, to break deadlocks.
    Add a timeout to semaphore takes (e.g., 100 ms) and release all held mutexes on timeout, then retry, to break deadlocks.
  3. 80% success Use a recursive mutex if a single task may re-acquire the same mutex (e.g., via nested function calls).
    Use a recursive mutex if a single task may re-acquire the same mutex (e.g., via nested function calls).

中文步骤

  1. Implement a consistent lock ordering: always acquire mutexes in the same order (e.g., SensorMutex before ControlMutex) across all tasks.
  2. Add a timeout to semaphore takes (e.g., 100 ms) and release all held mutexes on timeout, then retry, to break deadlocks.
  3. Use a recursive mutex if a single task may re-acquire the same mutex (e.g., via nested function calls).

Dead Ends

Common approaches that don't work:

  1. 95% fail

    Deadlock is a synchronization issue, not a memory issue; larger stacks don't resolve lock ordering conflicts.

  2. 100% fail

    This hides the symptom but the system remains hung; tasks never progress.

  3. 85% fail

    Binary semaphores don't prevent priority inversion or deadlock; the same circular dependency persists.