Min menu

Pages

project 14:Creating a FreeRTOS task to Blink LED in Arduino Uno

Arduino FreeRTOS Tutorial 1 - Creating a FreeRTOS task to Blink LED in Arduino Uno


The OS present inside the embedded devices is called an RTOS (Real-Time Operating System). In embedded devices, real-time tasks are critical where timing plays a very important role. Real-time tasks are Time Deterministic means the response time to any event is always constant so that it can be guaranteed that any particular event will occur at a fixed time. RTOS is designed to run applications with very precise timing and a high degree of reliability. RTOS also helps in multi-tasking with a single core.
We already covered a tutorial on how to use RTOS in embedded systems where you can know more about RTOS, the difference between general-purpose OS and RTOS, different types of RTOS, etc.
In this tutorial, we will start with FreeRTOS. FreeRTOS is a class of RTOS for embedded devices which is small enough to be run on 8/16-bit microcontrollers, although its use is not limited to these microcontrollers. It is a completely open-source and it’s code is available on github. If we know some basic concepts of RTOS, then it is very easy to use FreeRTOS because it has well-documented APIs which can be directly used in the code without knowing the backend part of the coding. Complete FreeRTOS documentation can be found here.



xTaskCreate(task1,"task1",128,NULL,1,NULL);
 xTaskCreate(task2,"task2",128,NULL,2,NULL);  
Here, Task2 has higher priority and hence executes first.
4. After creating the task, start the scheduler in a void setup using vTaskStartScheduler(); API.
5. Void loop() function will remain empty as we don’t want to run any task manually and infinitely. Because task execution is now handled by Scheduler.
6. Now, we have to implement task functions and write the logic that you want to execute inside these functions. The function name should be the same as the first argument of xTaskCreate() API.
void task1(void *pvParameters)  
{
while(1) {
..
..//your logic
}
}
7. Most of the code needs delay function to stop the running task but in RTOS it is not suggested to use Delay() function as it stops the CPU and hence RTOS also stops working. So FreeRTOS has a kernel API to block the task for a specific time.
vTaskDelay( const TickType_t xTicksToDelay );
This API can be used for delay purposes. This API delay a task for a given number of ticks. The actual time for which the task remains blocked depends on the tick rate. The constant portTICK_PERIOD_MS can be used to calculate real-time from the tick rate.
This means if you want a delay of 200ms, just write this line
vTaskDelay( 200 / portTICK_PERIOD_MS );
So for this tutorial, we will use these FreeRTOS APIs to implement three tasks.
APIs to be used:
  1. xTaskCreate();
  2. vTaskStartScheduler();
  3. vTaskDelay();
Task to be created for this tutorial:
  1. LED blink at Digital pin 8 with 200ms frequency
  2. LED blink at Digital pin 7 with 300ms frequency
  3. Print numbers in serial monitor with 500ms frequency.

FreeRTOS Task Implementation in Arduino IDE

1. From the above basic structure explanation, include the Arduino FreeRTOS header file. Then make function prototypes. As we have three tasks, so make three functions and it’s prototypes.
#include <Arduino_FreeRTOS.h>
void TaskBlink1( void *pvParameters );
void TaskBlink2( void *pvParameters );
void Taskprint( void *pvParameters );
2. In void setup() function, initialize serial communication at 9600 bits per second and create all three tasks using xTaskCreate() API. Initially, make the priorities of all tasks as ‘1’ and start the scheduler.
void setup() {
Serial.begin(9600);
xTaskCreate(TaskBlink1,"Task1",128,NULL,1,NULL);
xTaskCreate(TaskBlink2,"Task2 ",128,NULL,1,NULL);
xTaskCreate(Taskprint,"Task3",128,NULL,1,NULL);   
vTaskStartScheduler();
}
3. Now, implement all three functions as shown below for task1 LED blink.
void TaskBlink1(void *pvParameters) 
{
pinMode(8, OUTPUT);
while(1)
{
digitalWrite(8, HIGH);   
vTaskDelay( 200 / portTICK_PERIOD_MS ); 
digitalWrite(8, LOW);    
vTaskDelay( 200 / portTICK_PERIOD_MS ); 
}
}
Similarly, implement TaskBlink2 functionTask3 function will be written as
void Taskprint(void *pvParameters)  
{
int counter = 0;
while(1)
{
counter++;
Serial.println(counter);
vTaskDelay( 500 / portTICK_PERIOD_MS ); 
}
}
reaction: