Starting Programming with FreeRTOS for Beginners

                            Starting Programming with FreeRTOS for Beginners


ESP32 is a low-cost, low-power microcontroller with built-in Wi-Fi and Bluetooth capabilities, making it a popular choice for IoT and home automation projects. Combining the capabilities of the ESP32 with the power of the FreeRTOS real-time operating system can open up a whole new world of possibilities for your projects. In this blog, we will explore how to start programming with FreeRTOS on the ESP32 using the Arduino IDE.

Prerequisites

Setting up the Arduino IDE: The first step in getting started with FreeRTOS on the ESP32 is to set up the Arduino IDE. You can download the latest version of the Arduino IDE for free from the Arduino website. Once the Arduino IDE is installed, you will need to add the ESP32 board to the IDE. This can be done by going to the "File" menu and selecting "Preferences" then adding the following link to the "Additional Boards Manager URLs:" https://dl.espressif.com/dl/package_esp32_index.json"

Installing the ESP32 Board in Arduino IDE: Next, you will need to install the ESP32 board files in the Arduino IDE. This can be done by going to the "Tools" menu and selecting "Board" then "Boards Manager." Search for "esp32" and select the "esp32 by Espressif Systems" and click on "install" button.

Installing the FreeRTOS library: To start using FreeRTOS on the ESP32, you will need to install the FreeRTOS library for the ESP32 in the Arduino IDE. This can be done by going to the "Sketch" menu and selecting "Include Library" then "Manage Libraries." Search for "freertos" and install the library.

Setting up the ESP32 board: Once the ESP32 board files and the FreeRTOS library are installed, you can connect your ESP32 board to your computer using a USB cable. Select the correct board and port in the Arduino IDE under "Tools."

Creating Tasks: To start using FreeRTOS in your sketch, you will need to create tasks. Tasks are small blocks of code that run concurrently with each other, allowing for multitasking. To create a task, you will need to define a function that contains the code for the task and then use the xTaskCreate function to create the task.

Starting the FreeRTOS scheduler: Once your tasks are set up, you will need to start the FreeRTOS scheduler by adding the line "vTaskStartScheduler();" at the end of your sketch. The FreeRTOS scheduler is responsible for managing and running your tasks.

Uploading and testing your sketch: Now your sketch is ready to run with FreeRTOS on the ESP32. You can upload the sketch to your board and see the output on the serial monitor of the Arduino IDE.

Sample code for FreeRTOS and the ESP32

Here is a simple example of how to create a task using FreeRTOS on the ESP32 with the Arduino IDE:

//#include <Arduino_FreeRTOS.h>

// Function that will run as a task

void taskFunction( void * pvParameters ){

    for(;;){

        // code to be executed by the task

        // This could be reading a sensor, controlling an output, etc.

        Serial.println("Hello from task!");

        vTaskDelay(1000 / portTICK_PERIOD_MS); // delay for 1 second

    }

}


void setup() {

    Serial.begin(115200);

    // Create the task

    xTaskCreate(taskFunction, "Task Name", configMINIMAL_STACK_SIZE, NULL, 1, NULL);

}


void loop() {

    // nothing goes here, all the work is done in the tasks

}


This example creates a task called "taskFunction" which will execute the code inside the for loop. The task will run indefinitely and print "Hello from task!" to the serial monitor every second. It is important to notice that you must use the "vTaskDelay" function to make a task wait for some time, instead of using the "delay" function, as the latter will block all the tasks from running.

Also, the xTaskCreate function creates the task and it receives various parameters such as the name of the task, stack size, task parameter and priority.

Details about the Functions used in the code

xTaskCreate(taskFunction, "Task Name", configMINIMAL_STACK_SIZE, NULL, 1, NULL): This function creates the task and assigns it the task function, a name, a stack size, a parameter and a priority.

taskFunction(void *pvParameters): This function is the task that you want to run. The void *pvParameters is used to pass in parameters to the task if needed, in this example it is not used so it is passed in as NULL.

Serial.begin(115200): This function sets the data rate in bits per second (baud) for serial data transmission.

Serial.println("Hello from task!"): This function sends a message to the serial port, to be sent out the serial port. In this case it's used to print a message to the serial monitor.

vTaskDelay(1000 / portTICK_PERIOD_MS) : this function makes the task wait for a specified amount of time, in this case it is set to 1000 milliseconds (1 second). Instead of using the standard delay() function, this function must be used in FreeRTOS as it does not block other tasks from executing.

xTaskCreate is the function responsible to create the task, it receives several parameters like the task function name, the stack size, parameter, and task priority. Once the task is created the scheduler vTaskStartScheduler() will be responsible to manage and run the task.

Sample code for FreeRTOS and the ESP32 with two tasks

Here is an example of how to create two tasks using FreeRTOS on the ESP32 with the Arduino IDE:

// Function for the first task

void task1Function(void *pvParameters){

    for(;;){

        Serial.println("Hello from task 1!");

        vTaskDelay(1000 / portTICK_PERIOD_MS); // delay for 1 second

    }

}

// Function for the second task

void task2Function(void *pvParameters){

    for(;;){

        Serial.println("Hello from task 2!");

        vTaskDelay(2000 / portTICK_PERIOD_MS); // delay for 2 seconds

    }

}

void setup() {

    Serial.begin(115200);

    // Create the first task

    xTaskCreate(task1Function, "Task 1", configMINIMAL_STACK_SIZE, NULL, 1, NULL);

    // Create the second task

    xTaskCreate(task2Function, "Task 2", configMINIMAL_STACK_SIZE, NULL, 2, NULL);

    // Start the FreeRTOS scheduler

    vTaskStartScheduler();

}

void loop() {

    // nothing goes here, all the work is done in the tasks

}

In this example, we have two tasks, "task1Function" and "task2Function", which will run concurrently. The first task runs a loop that prints "Hello from task 1!" to the serial monitor every second, and the second task runs a loop that prints "Hello from task 2!" to the serial monitor every 2 seconds.

The xTaskCreate function creates both tasks, and each one is given a name, a stack size, a parameter and a priority. The scheduler vTaskStartScheduler() will be responsible to manage and run the task. The priority of task1 is set to 1 and the priority of task2 is set to 2. The priority value determines the order in which the tasks are executed. In this case, task1 has a higher priority than task2, so it will be executed first. In case both tasks have the same priority, they will be executed in a round-robin fashion.

It's worth noting that this is just a simple example and in real-world scenarios, you may need to use other FreeRTOS functionality such as mutexes, semaphores, and message queues to synchronize and communicate between tasks. These can be particularly useful when working with shared resources that may be accessed by multiple tasks.

Additionally, you might want to consider using the vTaskDelayUntil() instead of vTaskDelay() if you need to maintain accurate time intervals, especially in systems where the processing load is subject to change.

In any case, keep in mind that using FreeRTOS on ESP32 requires a good understanding of the concepts of real-time operating systems. It is recommended to read the documentation and do some tutorials before starting your projects.

It's important to notice that, this is just a simple example, and depending on your project requirements you may need to use other functions provided by the FreeRTOS library, like semaphores, message queues, and event groups, among others. Also, remember that the FreeRTOS is a complex library and requires a good understanding of the concepts of real-time operating systems, so it's recommended to read the documentation and do some tutorials before starting your projects.

Post a Comment

Previous Post Next Post