FreeRTOS for IoT: Real-Time Operating System on ESP32 and STM32
Home Blog FreeRTOS for IoT: Real-Time Operating System on ESP32 and STM32
Firmware Firmware FreeRTOS RTOS

FreeRTOS for IoT: Real-Time Operating System on ESP32 and STM32

📅 October 2025 ⏳ 3 min read FSS Engineering Team
MCU

FreeRTOS task scheduler — concurrent sensor, BLE, OTA, and watchdog tasks on a single ESP32-S3

FreeRTOS is the de-facto RTOS for IoT. ESP-IDF ships FreeRTOS built-in; STM32CubeMX generates FreeRTOS integration. Mastering it separates firmware that survives 3 years in production from firmware that only works in the lab.

Task Architecture

// FreeRTOS task design — IoT device

void sensor_task(void *p) {
    TickType_t last = xTaskGetTickCount();
    while (1) {
        sensor_data_t d = {.temp=read_temp(), .hum=read_hum()};
        xQueueSend(sensor_q, &d, portMAX_DELAY);
        vTaskDelayUntil(&last, pdMS_TO_TICKS(5000));
    }
}
void ble_task(void *p) {
    sensor_data_t d;
    while (1) {
        xQueueReceive(sensor_q, &d, portMAX_DELAY);
        ble_transmit(&d);
        xSemaphoreGive(watchdog_sem);
    }
}

Stack Overflow Detection

// FreeRTOSConfig.h

#define configCHECK_FOR_STACK_OVERFLOW 2
void vApplicationStackOverflowHook(TaskHandle_t t, char *name) {
    ESP_LOGE(TAG, "STACK OVERFLOW: %s", name);
    esp_restart();
}
💡 Stack sizing
Use uxTaskGetStackHighWaterMark() during testing to measure actual peak stack per task. Add 20% headroom. Never guess — measure under real-world workloads including worst-case BLE callbacks.

Inter-Task Communication Patterns

Beyond basic queues, FreeRTOS provides event groups, stream buffers, and message buffers. Event groups are ideal for coordinating multiple tasks around a set of conditions — for example, an OTA task that waits until both a WiFi connection flag and a time synchronisation flag are set before downloading a firmware update. A single xEventGroupWaitBits() call replaces a complex polling loop.

Stream buffers are optimised for byte-stream data from interrupts — a UART receive ISR writing to a stream buffer that a parsing task reads from. The ISR never blocks; the parser blocks until data is available. This pattern handles variable-length sensor data packets efficiently without dynamic memory allocation.

Watchdog Integration

A hardware watchdog that is not properly integrated with FreeRTOS is worse than useless — it will trigger randomly when a legitimate task takes longer than expected, causing unnecessary device restarts. ESP-IDF’s task watchdog (TWDT) monitors individual tasks, not the entire system. Configure it to monitor your highest-priority tasks and feed it in each task’s main loop.

// Task watchdog — monitor critical tasks

esp_task_wdt_init(30, true);       // 30s timeout, panic on trigger
esp_task_wdt_add(sensor_task_h);   // monitor sensor task
esp_task_wdt_add(ble_task_h);      // monitor BLE task

// In each task's main loop:
esp_task_wdt_reset();              // feed watchdog

Memory Management in FreeRTOS

Dynamic memory allocation (pvPortMalloc) in FreeRTOS uses a heap. ESP-IDF provides multiple heap implementations — heap_4 is the default, with first-fit allocation and coalescing of free blocks. For production firmware, avoid dynamic allocation in ISRs entirely, and minimise allocation after system initialisation. Fragmentation over days of continuous operation can cause allocation failures that are nearly impossible to reproduce in testing.

Use static allocation for queues, semaphores, and task stacks where predictability matters. FreeRTOS supports fully static allocation (no heap at all) via configSUPPORT_STATIC_ALLOCATION — useful for safety-critical applications where memory exhaustion must be provably impossible.

Porting Between ESP32 and STM32

FreeRTOS APIs are identical on ESP32 (via ESP-IDF) and STM32 (via STM32CubeMX). Task creation, queue operations, and synchronisation primitives all have the same function signatures. If you design your application layer against FreeRTOS APIs and abstract hardware access behind a HAL, porting between MCU families is a matter of days rather than weeks. At FSS we maintain shared firmware components — MQTT client, OTA manager, sensor drivers — that run unchanged on both platforms.

Building an IoT product?

FSS is a full-stack IoT engineering team — hardware, firmware, cloud, and mobile in one place.

Our IoT capabilities →

Related articles

Building something connected?

FSS Technology designs and builds IoT products from silicon to cloud — embedded firmware, custom hardware, and Azure backends.

Talk to our team →