GuideIntermediateRTOS

FreeRTOS Task Sizing Guide

Calculate worst-case stack depth, choose the right heap scheme, and detect overflow before it corrupts memory silently.

FreeRTOS Task Sizing Guide

This guide covers how to calculate worst-case stack depth for FreeRTOS tasks, choose the right heap allocation scheme, and detect stack overflow before it corrupts memory silently.

Why task stack sizing matters

FreeRTOS allocates each task a fixed stack at creation time. Overflow doesn't always crash immediately — it silently corrupts adjacent memory, producing bugs that are hard to reproduce and nearly impossible to bisect.

Step 1 — Estimate worst-case stack depth

For each task, trace the deepest call chain:

  1. Start from the task function entry point
  2. Add the stack frame of every nested call (local variables + return address + saved registers)
  3. Add the ISR epilogue overhead if the task can be preempted mid-call
  4. Add a 20–30% safety margin

Use uxTaskGetStackHighWaterMark() in development to measure actual peak usage and validate your estimate.

Step 2 — Choose the right heap scheme

| Scheme | Allocates | Frees | Use when | |---|---|---|---| | heap_1 | ✓ | ✗ | Static allocation only, no vTaskDelete | | heap_2 | ✓ | ✓ (no coalesce) | Fixed-size blocks, no fragmentation risk | | heap_3 | Wraps malloc/free | ✓ | Porting existing code | | heap_4 | ✓ | ✓ + coalesce | General use — most common choice | | heap_5 | ✓ | ✓ + non-contiguous | Multiple RAM regions |

heap_4 is the right default for most embedded Linux-free FreeRTOS projects.

Step 3 — Enable overflow detection

Add to FreeRTOSConfig.h:

#define configCHECK_FOR_STACK_OVERFLOW  2

Implement the hook:

void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName) {
    (void)xTask;
    /* Log pcTaskName, halt, or reset */
    configASSERT(0);
}

Mode 2 checks the stack watermark pattern on every context switch — small overhead, catches most overflows.

Common mistakes

  • Sizing for happy path only — recursive calls, printf/sprintf, and floating-point operations all consume more stack than they look
  • Forgetting ISR stack sharing — on Cortex-M, ISRs use the MSP, not the task stack; account for this separately
  • Using heap_3 in production — it re-enters malloc, which is not thread-safe without the mutex wrapper

Next Step

Ready for a full course path?

Use this resource as a starting point and continue with structured modules in Learn courses.