embedded runtime_error ai_generated true

FreeRTOS: mutex deadlock detected on handle 0x2000ABCD, task 'SensorTask' blocked indefinitely

ID: embedded/freertos-mutex-deadlock-detected

Also available as: JSON · Markdown · 中文
90%Fix Rate
88%Confidence
1Evidence
2025-01-10First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
FreeRTOS 10.5.1 active
CMISIS-RTOS2 2.1.3 active
ARM GCC 11.3.1 active

Root Cause

Circular dependency between two tasks holding and waiting for mutexes, or a task attempts to take a mutex it already holds without recursive mutex type.

generic

中文

两个任务持有并等待互斥锁形成循环依赖,或任务尝试获取已持有的互斥锁但未使用递归互斥锁类型。

Official Documentation

https://www.freertos.org/Documentation/RTOS_book.html

Workarounds

  1. 95% success Use recursive mutex (xSemaphoreCreateRecursiveMutex) instead of standard mutex if same task needs to take mutex multiple times. Replace all xSemaphoreTake() with xSemaphoreTakeRecursive().
    Use recursive mutex (xSemaphoreCreateRecursiveMutex) instead of standard mutex if same task needs to take mutex multiple times. Replace all xSemaphoreTake() with xSemaphoreTakeRecursive().
  2. 90% success Implement mutex lock ordering: ensure all tasks acquire mutexes in the same global order (e.g., always lock sensor mutex before display mutex). Add assert checks using configUSE_MUTEX_DEADLOCK_DETECTION.
    Implement mutex lock ordering: ensure all tasks acquire mutexes in the same global order (e.g., always lock sensor mutex before display mutex). Add assert checks using configUSE_MUTEX_DEADLOCK_DETECTION.

中文步骤

  1. Use recursive mutex (xSemaphoreCreateRecursiveMutex) instead of standard mutex if same task needs to take mutex multiple times. Replace all xSemaphoreTake() with xSemaphoreTakeRecursive().
  2. Implement mutex lock ordering: ensure all tasks acquire mutexes in the same global order (e.g., always lock sensor mutex before display mutex). Add assert checks using configUSE_MUTEX_DEADLOCK_DETECTION.

Dead Ends

Common approaches that don't work:

  1. Increase task stack size to avoid blocking 95% fail

    Deadlock is caused by mutex logic, not stack overflow; larger stack does not resolve circular wait.

  2. Reduce mutex timeout value to force task to give up 80% fail

    Reducing timeout may cause task to abandon operation prematurely, leading to data corruption or incomplete processing.