freeRTOS debug

Your sketch is written for ESP32 but you’re compiling it for ESP8266, and that’s why it’s failing.

Why

SemaphoreHandle_t, xSemaphoreCreateBinary(), xSemaphoreGive(), xSemaphoreTake(), and portMAX_DELAY are FreeRTOS API calls.

ESP32 Arduino comes with FreeRTOS by default.

ESP8266 Arduino does not use FreeRTOS — so those types and functions don’t exist unless you add a separate RTOS layer.

✅ When is it a Good Time to Use FreeRTOS?

FreeRTOS is a real-time operating system designed for microcontrollers. It lets you split your application into multiple tasks that run seemingly in parallel.


🧠 Use FreeRTOS When:

1. 🧵 You Need to Run Multiple Tasks Concurrently

  • Example: Reading sensor data, updating a display, and handling WiFi at the same time.
  • Each task can run independently using xTaskCreate().

2. ⏱️ You Require Real-Time Responsiveness

  • Critical tasks (e.g., handling motor feedback or interrupts) can be given higher priority.
  • Guarantees predictable response time.

3. 🕓 You Need Precise Timing or Scheduling

  • Use vTaskDelay(), xTimerCreate(), etc., to run tasks at specific intervals.
  • Better than using delay() or busy-wait loops.

4. 📶 You Have Asynchronous Events to Handle

  • Great for UART, I2C, network communication, button presses, etc.
  • Use queues, semaphores, and event groups for clean async handling.

5. 🔄 You Want to Structure a Large Project Cleanly

  • Modular task-based design.
  • Easier to manage and debug than a giant loop() function.

6. 📦 You're Using ESP32 or STM32 with Multiple Cores or Peripherals

  • ESP32 has dual-core (PRO & APP cores).
  • FreeRTOS lets you pin tasks to cores, assign priority, and manage memory better.

🧊 Not Always Necessary If:

Situation Recommendation
Simple blink or sensor reading No need for FreeRTOS
Single function, low resource Use loop() and interrupts
Ultra-low-power apps May be better without RTOS

✅ Example: Good Use Case (ESP32 with Camera, Webserver, Sensors)

  • 📷 Task 1: Camera image capture
  • 🌐 Task 2: Web server and WiFi communication
  • 🌡️ Task 3: Sensor data read and logging
  • 🎯 Task 4: OTA update check

All these tasks can run smoothly in parallel using FreeRTOS, each with its own stack and priority.


🚀 Summary

Feature Why FreeRTOS Helps
Multitasking Run multiple functions in parallel
Real-time priority Critical tasks get CPU first
Precise scheduling Timers, delays, and periodic execution
Clean architecture Organized, modular task-based design
Event handling Easy async using semaphores & queues

Let me know if you'd like a simple FreeRTOS project example!

Use FreeRTOS primitives:

Queue: for passing sensor/audio/display data between tasks

Semaphore: to lock I2C bus or protect shared resources

Timer: for periodic updates (e.g., sensor every 1s)

🧩 Inter-Task Communication

✅ 1. SSD1306 (I2C)

Use Adafruit SSD1306 or u8g2 with I2C.

Share I2C bus with BMP280.

Protect with mutex semaphore.

xSemaphoreTake(i2c_mutex, portMAX_DELAY); // update display xSemaphoreGive(i2c_mutex);

✅ 2. BMP280 Sensor (I2C)

Read temperature & pressure every 1–2 seconds.

Send data to DisplayTask via queue.

Example Queues and Semaphores:

QueueHandle_t sensor_data_queue;
QueueHandle_t display_msg_queue;
SemaphoreHandle_t i2c_mutex;

Sensor to Display Queue Message:

typedef struct {
    float temperature;
    float pressure;
} sensor_data_t

Pseudocode Overview

void SensorTask(void *pvParams) {
    sensor_data_t data;
    while (1) {
        xSemaphoreTake(i2c_mutex, portMAX_DELAY);
        data = read_bmp280();
        xSemaphoreGive(i2c_mutex);

        xQueueSend(sensor_data_queue, &data, 0);
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

void DisplayTask(void *pvParams) {
    sensor_data_t data;
    while (1) {
        if (xQueueReceive(sensor_data_queue, &data, portMAX_DELAY)) {
            xSemaphoreTake(i2c_mutex, portMAX_DELAY);
            update_display(data.temperature, data.pressure);
            xSemaphoreGive(i2c_mutex);
        }
    }
}

cores

xTaskCreatePinnedToCore(task1, "Task1", 2048, NULL, 1, NULL, 0);  // Run on Core 0
xTaskCreatePinnedToCore(task2, "Task2", 2048, NULL, 1, NULL, 1);  // Run on Core 1

Core 0: PRO_CPU (usually handles Wi-Fi, BT stack)

Core 1: APP_CPU (often used for your application)

compare

Feature / RTOS FreeRTOS Zephyr RTOS ThreadX (Azure RTOS) Bare-Metal (No RTOS)
License MIT (Permissive, Free) Apache 2.0 (Permissive, Free) Microsoft EULA (Free, but limited) None
Footprint Very Small (<10 KB) Medium (~50–100 KB) Small (~10–20 KB) Very Small
Real-Time Yes (preemptive, deterministic) Yes (configurable RT, preemptive) Yes (deterministic RTOS) Depends on implementation
Ease of Use Simple API, easy learning curve More complex, powerful config system Easy API, good documentation Full control but more effort
Hardware Support Very wide (ARM, RISC-V, etc.) Very wide + device trees Good (mainly ARM, RISC-V, x86) Manual per-device work
Task Management Yes (tasks, priorities) Yes (threads, priorities, SMP) Yes (threads, priorities) Manual state machine
Synchronization Semaphores, mutexes, queues Semaphores, FIFOs, message queues Semaphores, mutexes, event flags Manual implementation
File System Support External (e.g., FatFs) Native FS (e.g., LittleFS, FatFS) With Azure FileX Manual or third-party
Networking External (e.g., lwIP) Native (TCP/IP stack, 6LoWPAN) Azure NetX Duo (IPv4/IPv6) External, complex to integrate
Power Management Basic, user-implemented Advanced (built-in PM framework) Good (some MCU-specific features) Manual
Security/IoT AWS IoT support (via Amazon RTOS) Secure boot, crypto, OTA, TLS Azure IoT support, TLS, OTA Manual, very limited
Trace & Debug Tools: SystemView, Tracealyzer Zephyr logging & tracing NetX, ThreadX tracing tools Manual logging
Community Support Huge, mature ecosystem Growing fast, backed by Linux Foundation Good, backed by Microsoft None (solo dev)

example 3

FreeRTOS Example Explanations

✅ In short:

  • Queue examples → show how to pass data safely.
  • Mutex/Notifications → show synchronization methods.
  • AnalogRead/Blink → show multitasking with hardware.
  • TaskStatus/Utilities → show debugging and monitoring.
  • Interrupts → show ISR to task communication.

1. AnalogRead_DigitalRead

  • Shows how to create tasks that perform analog input and digital output.
  • One task periodically reads an analog pin (ADC).
  • Another task toggles a digital pin (e.g., LED).
  • Demonstrates how multiple tasks run independently without blocking.

2. ArrayQueue

  • Demonstrates using a FreeRTOS queue to pass an array of data between tasks.
  • For example: Task A fills an array → sends via queue → Task B receives and processes.
  • Useful for handling data buffers (sensor readings, UART packets).

3. Assert

  • Shows how configASSERT() works in FreeRTOS.
  • Asserts help catch programming errors (e.g., stack overflow, bad API usage).
  • Example demonstrates failing conditions to show how assert is triggered.

4. Blink_AnalogRead

  • Combines two common Arduino tasks:
    • One task blinks an LED.
    • Another task reads analog input.
  • Demonstrates that FreeRTOS allows both to run concurrently without delay() blocking.

5. GoldilocksAnalogueTestSuite

  • Specific test suite for the Goldilocks Analogue board (Arduino-compatible with audio-grade ADC/DAC).
  • Shows how to use FreeRTOS tasks with more advanced ADC/DAC hardware.
  • Mostly relevant if you use that hardware.

6. IntegerQueue

  • Demonstrates using a queue of integers between producer/consumer tasks.
  • Example: one task generates numbers, another task prints them.
  • Basic introduction to queues in FreeRTOS.

7. Interrupts

  • Shows how FreeRTOS interacts with hardware interrupts.
  • Example: An ISR (interrupt service routine) gives a semaphore or sends data to a queue.
  • Demonstrates safe communication between interrupts and tasks.

8. Mutex

  • Demonstrates a mutex (mutual exclusion lock).
  • Ensures only one task at a time accesses a shared resource (like Serial or an I²C bus).
  • Prevents data corruption when multiple tasks try to use the same peripheral.

9. Notifications

  • Shows how to use task notifications instead of semaphores/queues.
  • Lightweight way to signal a task from another task or from an ISR.
  • Example: ISR notifies a task when a button is pressed.

10. StructArray

  • Demonstrates passing an array of structs between tasks.
  • Useful when you have structured data (like sensor packets).
  • Similar to ArrayQueue, but with custom struct types.

11. StructQueue

  • Demonstrates using a queue of structs.
  • Example: Task A sends a struct {temperature, humidity, timestamp} to Task B.
  • More real-world than IntegerQueue because data usually comes in structs.

12. TaskStatus

  • Demonstrates retrieving task runtime statistics.
  • Uses FreeRTOS APIs (uxTaskGetSystemState, vTaskGetRunTimeStats) to show:
    • Task names
    • CPU usage %
    • Stack high-water marks
  • Useful for debugging and optimization.

13. TaskUtilities

  • Shows helper functions that make FreeRTOS task management easier.
  • Examples: delaying tasks (vTaskDelay), checking stack usage, suspending/resuming tasks.
  • A "toolbox" demo for common task patterns.

example 2

queues + shared state

  struct ControlData {
      uint16_t throttle;
      uint16_t steering;
      uint16_t battery_mv;
  };

  // Shared global (protected with mutex if multiple tasks write to it)
  volatile ControlData control;

✅ Recommendation: Use FreeRTOS with 3–4 tasks (ELRS, motors, ADC, BLE) + one shared struct. It gives you the best modularity and avoids blocking.

ELRS Task (high priority)

  • Reads UART (CRSF packets).
  • Parses channel values.
  • Updates control.throttle and control.steering.

Motor Control Task (medium/high priority)

  • Runs periodically (e.g. every 10–20 ms).
  • Reads latest control.throttle / steering.
  • Writes PWM to motors (non-blocking).

Battery ADC Task (low priority / slow loop)

  • Reads ADC every 500–1000 ms.
  • Updates control.battery_mv.

BLE Task (lowest priority)

  • Takes control.battery_mv and updates BLE advertising packet.
  • Runs every 1–2 seconds.

simple example 1

#include "FreeRTOS.h"
#include "task.h"
#include <stdio.h>

void vTask1(void *pvParameters) {
    while (1) {
        printf("Task 1 running\n");
        vTaskDelay(pdMS_TO_TICKS(1000));  // Delay 1000 ms
    }
}

void vTask2(void *pvParameters) {
    while (1) {
        printf("Task 2 running\n");
        vTaskDelay(pdMS_TO_TICKS(2000));  // Delay 2000 ms
    }
}

int main(void) {
    xTaskCreate(vTask1, "Task1", 128, NULL, 1, NULL);
    xTaskCreate(vTask2, "Task2", 128, NULL, 1, NULL);

    vTaskStartScheduler();  // Start FreeRTOS
    while (1);
}

ref