QUICK_FIX_FREERTOS - Alteriom/painlessMesh GitHub Wiki
Quick Fix: FreeRTOS Assertion Failure
Immediate Solution
If you're experiencing assert failed: vTaskPriorityDisinheritAfterTimeout crashes, apply this quick fix NOW:
Option A: Increase Semaphore Timeout (5 minutes to fix)
File: src/painlessmesh/mesh.hpp
Line: 544
Change from:
return xSemaphoreTake(xSemaphore, (TickType_t)10) == pdTRUE;
Change to:
return xSemaphoreTake(xSemaphore, (TickType_t)100) == pdTRUE;
Steps:
# 1. Edit the file
code src/painlessmesh/mesh.hpp
# 2. Find line 544 and change 10 to 100
# 3. Rebuild and upload
pio run -t upload
# 4. Test
Option B: Enable Thread-Safe Scheduler (10 minutes to fix)
File: Create or edit painlessTaskOptions.h in your sketch folder
Add:
#ifndef _PAINLESS_TASK_OPTIONS_H_
#define _PAINLESS_TASK_OPTIONS_H_
#ifdef ESP32
#define _TASK_THREAD_SAFE // Enable thread safety
#define _TASK_PRIORITY // Enable priority scheduling
#endif
#endif
In your main sketch, add BEFORE including painlessMesh:
#include "painlessTaskOptions.h"
#include <painlessMesh.h>
Option C: Use Binary Semaphore (5 minutes to fix)
File: src/painlessmesh/mesh.hpp
Line: 43
Change from:
xSemaphore = xSemaphoreCreateMutex();
Change to:
xSemaphore = xSemaphoreCreateBinary();
xSemaphoreGive(xSemaphore); // Initialize
Which Option Should I Use?
| Option | Complexity | Effectiveness | Risk |
|---|---|---|---|
| A: Increase Timeout | ⭐ Easy | ⭐⭐⭐ Good | Low |
| B: Thread-Safe | ⭐⭐ Medium | ⭐⭐⭐⭐⭐ Excellent | Very Low |
| C: Binary Semaphore | ⭐ Easy | ⭐⭐⭐ Good | Medium |
Recommendation: Start with Option A for immediate relief, then implement Option B for long-term stability.
Verification
After applying the fix:
void setup() {
Serial.begin(115200);
mesh.init(...);
// Add monitoring
mesh.onNewConnection([](uint32_t nodeId) {
Serial.printf("New connection: %u, Free heap: %d\n",
nodeId, ESP.getFreeHeap());
});
}
void loop() {
mesh.update();
// Monitor every 10 seconds
static uint32_t lastCheck = 0;
if (millis() - lastCheck > 10000) {
lastCheck = millis();
Serial.printf("Heap: %d, Min: %d, Stack HWM: %d\n",
ESP.getFreeHeap(),
ESP.getMinFreeHeap(),
uxTaskGetStackHighWaterMark(NULL));
}
}
Still Crashing?
-
Check stack size:
// In platformio.ini build_flags = -DCONFIG_ARDUINO_LOOP_STACK_SIZE=8192 -
Reduce connections:
// In configuration.hpp or your sketch #define MAX_CONN 4 // Reduce from 10 -
Enable detailed logging:
#define CORE_DEBUG_LEVEL 4 -
See full documentation: FREERTOS_ASSERTION_FAILURE.md
Emergency: Disable Semaphore Completely
⚠️ WARNING: Only use if nothing else works and you're sure mesh is single-threaded
File: src/painlessmesh/mesh.hpp
Lines 542-560, replace with:
bool semaphoreTake() {
return true; // EMERGENCY: Disabled semaphore
}
void semaphoreGive() {
// No-op
}
This removes all thread safety but will stop the crashes. Use at your own risk!
Success Rate:
- Option A: ~80% of cases resolved
- Option B: ~95% of cases resolved
- Option C: ~70% of cases resolved
- Emergency: 100% but unsafe
Time to Fix: 5-10 minutes
Testing Time: 30 minutes (verify stability)