Skip to content

QUICK_FIX_FREERTOS

github-actions[bot] edited this page Oct 18, 2025 · 1 revision

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?

  1. Check stack size:

    // In platformio.ini
    build_flags = -DCONFIG_ARDUINO_LOOP_STACK_SIZE=8192
  2. Reduce connections:

    // In configuration.hpp or your sketch
    #define MAX_CONN 4  // Reduce from 10
  3. Enable detailed logging:

    #define CORE_DEBUG_LEVEL 4
  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)

Clone this wiki locally