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 ofvTaskDelay(), 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.