# FreeRTOS: xSemaphoreTakeRecursive failed on mutex 0x2000A000, mutex already taken by same task

- **ID:** `embedded/freertos-mutex-recursive-take`
- **Domain:** embedded
- **Category:** assertion_error
- **Verification:** ai_generated
- **Fix Rate:** 90%

## Root Cause

A recursive mutex was taken by a task that already holds it without a corresponding recursive give, exhausting the nesting count.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| FreeRTOS v10.5.1 | active | — | — |
| ARM GCC v12.2.1 | active | — | — |

## Workarounds

1. **Ensure every xSemaphoreTakeRecursive is paired with an equal number of xSemaphoreGiveRecursive calls. Use a debug macro to track nesting count.** (95% success)
   ```
   Ensure every xSemaphoreTakeRecursive is paired with an equal number of xSemaphoreGiveRecursive calls. Use a debug macro to track nesting count.
   ```
2. **Refactor code to avoid recursive mutex acquisition by using a single entry point that acquires the mutex once and calls nested functions without re-acquiring.** (85% success)
   ```
   Refactor code to avoid recursive mutex acquisition by using a single entry point that acquires the mutex once and calls nested functions without re-acquiring.
   ```

## Dead Ends

- **Replace recursive mutex with a standard mutex** — A standard mutex will cause a deadlock if the same task tries to take it again, as it does not support recursive acquisition. (90% fail)
- **Increase the configMAX_RECURSIVE_MUTEX_DEPTH value** — The depth is limited by task stack and memory; increasing it may mask the underlying nesting bug, leading to stack overflow later. (60% fail)
- **Add a delay before taking the mutex again** — Does not resolve the logic error; the mutex is already held, so delay only wastes CPU cycles without fixing the nesting count. (80% fail)
