0
0
AutocadHow-ToBeginner · 4 min read

How to Use FreeRTOS with Arduino: Simple Guide and Example

To use FreeRTOS with Arduino, install the FreeRTOS library via the Arduino Library Manager, then create tasks using xTaskCreate() and start the scheduler with vTaskStartScheduler(). This lets you run multiple functions at the same time on your Arduino board.
📐

Syntax

FreeRTOS uses tasks to run code concurrently. The main functions are:

  • xTaskCreate(): Creates a new task with a function to run.
  • vTaskStartScheduler(): Starts the FreeRTOS scheduler to run tasks.
  • vTaskDelay(): Pauses a task for a set time.

Each task is a function with a specific signature that runs in a loop.

c
BaseType_t xTaskCreate(
  TaskFunction_t pvTaskCode,    // Pointer to the task function
  const char * const pcName,    // Name of the task (for debugging)
  const uint16_t usStackDepth,  // Stack size in words
  void *pvParameters,           // Parameters passed to the task
  UBaseType_t uxPriority,       // Task priority
  TaskHandle_t *pvCreatedTask   // Handle to the created task
);

void vTaskStartScheduler(void);

void vTaskDelay(const TickType_t xTicksToDelay);
💻

Example

This example creates two tasks that blink two LEDs at different speeds using FreeRTOS on Arduino.

arduino
#include <Arduino.h>
#include <FreeRTOS.h>

#define LED1 13
#define LED2 12

void TaskBlink1(void *pvParameters) {
  pinMode(LED1, OUTPUT);
  while (1) {
    digitalWrite(LED1, HIGH);
    vTaskDelay(500 / portTICK_PERIOD_MS); // Delay 500 ms
    digitalWrite(LED1, LOW);
    vTaskDelay(500 / portTICK_PERIOD_MS);
  }
}

void TaskBlink2(void *pvParameters) {
  pinMode(LED2, OUTPUT);
  while (1) {
    digitalWrite(LED2, HIGH);
    vTaskDelay(200 / portTICK_PERIOD_MS); // Delay 200 ms
    digitalWrite(LED2, LOW);
    vTaskDelay(200 / portTICK_PERIOD_MS);
  }
}

void setup() {
  xTaskCreate(TaskBlink1, "Blink1", 128, NULL, 1, NULL);
  xTaskCreate(TaskBlink2, "Blink2", 128, NULL, 1, NULL);
  vTaskStartScheduler();
}

void loop() {
  // Empty. Tasks run independently.
}
Output
LED on pin 13 blinks every 1 second (0.5s ON, 0.5s OFF). LED on pin 12 blinks every 0.4 seconds (0.2s ON, 0.2s OFF).
⚠️

Common Pitfalls

Common mistakes when using FreeRTOS with Arduino include:

  • Not calling vTaskStartScheduler(), so tasks never run.
  • Using delay() inside tasks instead of vTaskDelay(), which blocks the scheduler.
  • Creating tasks with too small stack size, causing crashes.
  • Trying to use loop() for code when using FreeRTOS; it should be empty or minimal.
arduino
/* Wrong way: Using delay() inside a FreeRTOS task blocks all tasks */
void TaskWrong(void *pvParameters) {
  while (1) {
    digitalWrite(LED_BUILTIN, HIGH);
    delay(1000); // Blocks scheduler
    digitalWrite(LED_BUILTIN, LOW);
    delay(1000);
  }
}

/* Right way: Use vTaskDelay() to yield control */
void TaskRight(void *pvParameters) {
  while (1) {
    digitalWrite(LED_BUILTIN, HIGH);
    vTaskDelay(1000 / portTICK_PERIOD_MS); // Non-blocking delay
    digitalWrite(LED_BUILTIN, LOW);
    vTaskDelay(1000 / portTICK_PERIOD_MS);
  }
}
📊

Quick Reference

Summary tips for using FreeRTOS with Arduino:

  • Install FreeRTOS library from Arduino Library Manager.
  • Create tasks with xTaskCreate().
  • Start multitasking with vTaskStartScheduler().
  • Use vTaskDelay() for timing inside tasks.
  • Keep loop() empty or minimal when using FreeRTOS.

Key Takeaways

Install the FreeRTOS library and create tasks with xTaskCreate() to run multiple functions concurrently.
Always start the scheduler with vTaskStartScheduler() to begin multitasking.
Use vTaskDelay() inside tasks instead of delay() to avoid blocking other tasks.
Keep the Arduino loop() function empty or minimal when using FreeRTOS.
Allocate enough stack size for each task to prevent crashes.