Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 49

Arduino FreeRTOS Tutorial 1 - Creating

a FreeRTOS task to Blink LED in


Arduino Uno
EMBEDDED
ByRishabh Jain Mar 26, 20200

Fre
eRTOS Task for 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.
As FreeRTOS can run on 8-bit MCU so it can also be run on Arduino Uno board. We
have to just download the FreeRTOS library and then start implementing the code using
APIs. This tutorial is meant for a complete beginner, below are the topics, we will cover
in this Arduino FreeRTOS tutorial:  

1. How RTOS works


2. Some frequently used terms in RTOS
3. Installing FreeRTOS in Arduino IDE
4. How to create FreeRTOS Tasks with example

How RTOS works?


Before starting with RTOS working, let’s see what is a Task. Task is a piece of code that
is schedulable on the CPU to execute. So, if you want to perform some task, then it
should be scheduled using kernel delay or using interrupts. This work is done by
Scheduler present in the kernel. In a single-core processor, the scheduler helps tasks to
execute in a particular time slice but it seems like different tasks are executing
simultaneously. Every task runs according to the priority given to it.

Now, let’s see what happens in the RTOS kernel if we want to create a task for LED
blinking with a one-second interval and put this task on the highest priority.
Apart from the LED task, there will be one more task which is created by the kernel, it is
known as an idle task. The idle task is created when no task is available for execution.
This task always runs on the lowest priority i.e. 0 priority. If we analyze the timing graph
given above, it can be seen that execution starts with an LED task and it runs for a
specified time then for remaining time, the idle task runs until a tick interrupt occurs.
Then kernel decides which task has to be executed according to the priority of the task
and total elapsed time of the LED task. When 1 second is completed, the kernel chooses
the led task again to execute because it has a higher priority than the idle task, we can
also say that the LED task preempts the idle task. If there are more than two tasks with
the same priority then they will run in round-robin fashion for a specified time.

Below the state diagram as it shows the switching of the non-running task into
running state.
Every newly created task goes in Ready state (part of not running state). If the created
task (Task1) has the highest priority than other tasks, then it will move to running state. If
this running task preempts by the other task, then it will go back to the ready state again.
Else if task1 is blocked by using blocking API, then CPU will not engage with this task
until the timeout defined by the user.

If Task1 is suspended in running state using Suspend APIs, then Task1 will go to
Suspended state and it is not available to the scheduler again. If you resume Task1 in
the suspended state then it will go back to the ready state as you can see in the block
diagram.

This is the basic idea of how Tasks run and change their states. In this tutorial, we
will implement two tasks in Arduino Uno using FreeRTOS API.

Frequently used terms in RTOS


1. Task: It is a piece of code that is schedulable on the CPU to execute.

2. Scheduler: It is responsible for selecting a task from the ready state list to the running
state. Schedulers are often implemented so they keep all computer resources busy (as
in load balancing).

3. Preemption: It is the act of temporarily interrupting an already executing task with the
intention of removing it from the running state without its co-operation.

4. Context Switching: In priority-based preemption, the scheduler compares the priority


of running tasks with a priority of ready task list on every systick interrupt. If there is any
task in the list whose priority is higher than running task then context switch occurs.
Basically, in this process contents of different tasks get saved in their respective stack
memory.

5. Types of Scheduling policies:

1. Preemptive Scheduling: In this type of scheduling, tasks run with equal time
slice without considering the priorities.
2. Priority-based Preemptive: High priority task will run first.
3. Co-operative Scheduling: Context switching will happen only with the co-
operation of running tasks. Task will run continuously until task yield is called.
6. Kernel Objects: For signaling the task to perform some work, the synchronization
process is used. To perform this process Kernel objects are used. Some Kernel objects
are Events, Semaphores, Queues, Mutex, Mailboxes, etc. We will see how to use these
objects in upcoming tutorials.

From the above discussion, we have got some basic ideas about the RTOS concept and
now we can implement the FreeRTOS project in Arduino. So, let's get started by
installing FreeRTOS libraries in Arduino IDE.

Installing Arduino FreeRTOS Library


1. Open Arduino IDE and go to Sketch -> Include Library -> Manage Libraries.
Search for FreeRTOS and install the library as shown below.

You can download the library from github and Add the .zip file in Sketch-> Include
Library -> Add .zip file.

Now, restart the Arduino IDE. This library provides some example code, also that can be
found in File -> Examples -> FreeRTOS as shown below.
Here we will write the code from scratch to understand the working, later you can check
the example codes and use them.

Circuit Diagram
Below is the circuit diagram for creating Blinking LED task using FreeRTOS on Arduino:
Arduino FreeRTOS Example- Creating FreeRTOS tasks in
Arduino IDE
Let’s see a basic structure to write a FreeRTOS project.

1. First, include Arduino FreeRTOS header file as

#include <Arduino_FreeRTOS.h>

2. Give the function prototype of all functions that you are writing for execution which is
written as

void Task1( void *pvParameters );

void Task2( void *pvParameters );

..

….

3. Now, in void setup() function, create tasks and start the task scheduler.

For creating task, xTaskCreate() API is called in setup function with certain


parameters/arguments.

xTaskCreate( TaskFunction_t pvTaskCode, const char * const pcName, uint16_t


usStackDepth, void *pvParameters, UBaseType_t uxPriority, TaskHandle_t
*pxCreatedTask );
There are 6 arguments that should be passed while creating any task. Let’s see what
these arguments are

1. pvTaskCode: It is simply a pointer to the function that implements the task (in
effect, just the name of the function).
2. pcName: A descriptive name for the task. This is not used by FreeRTOS. It is
included purely for debugging purposes.
3. usStackDepth: Each task has its own unique stack that is allocated by the kernel
to the task when the task is created. The value specifies the number of words the
stack can hold, not the number of bytes. For example, if the stack is 32-bits wide
and usStackDepth is passed in as 100, then 400 bytes of stack space will be
allocated (100 * 4 bytes) in RAM. Use this wisely because Arduino Uno has only
2Kbytes of RAM.
4. pvParameters: Task input parameter (can be NULL).
5. uxPriority: Priority of the task ( 0 is the lowest priority).
6. pxCreatedTask: It can be used to pass out a handle to the task being created.
This handle can then be used to reference the task in API calls that, for example,
change the task priority or delete the task (can be NULL).
Example of task creation

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 function. Task3 function will be written as

void Taskprint(void *pvParameters)

int counter = 0;

while(1)

counter++;

Serial.println(counter);
vTaskDelay( 500 / portTICK_PERIOD_MS );

That’s it. We have successfully completed a FreeRTOS Arduino project for Arduino


Uno. You can find full code along with a video at the end of this tutorial.

Finally, connect two LEDs at the digital pin 7 and 8 and upload the code on your Arduino
board and open the Serial monitor. You will see a counter is running once in 500ms with
task name as shown below.

Also, observe the LEDs, they are blinking at different time intervals. Try to play with the
priority argument in the xTaskCreate function. Change the number and observe the
behavior on serial monitor and LEDs.

Now, you can understand the first two example codes in which analog read and digital
read tasks are created. In this way, you can make more advance projects using just
Arduino Uno and FreeRTOS APIs.

Code
#include <Arduino_FreeRTOS.h>
void TaskBlink1( void *pvParameters );
void TaskBlink2( void *pvParameters );
void Taskprint( void *pvParameters );
void setup() {
  // initialize serial communication at 9600 bits per second:
  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();
}
void loop()
{
}
void TaskBlink1(void *pvParameters)  {
  pinMode(8, OUTPUT);
  while(1)
 {
    Serial.println("Task1");
    digitalWrite(8, HIGH);   
    vTaskDelay( 200 / portTICK_PERIOD_MS ); 
    digitalWrite(8, LOW);    
    vTaskDelay( 200 / portTICK_PERIOD_MS ); 
 }
}
void TaskBlink2(void *pvParameters)  
{
  pinMode(7, OUTPUT);
  while(1)
 {
    Serial.println("Task2");
    digitalWrite(7, HIGH);   
    vTaskDelay( 300 / portTICK_PERIOD_MS ); 
    digitalWrite(7, LOW);   
    vTaskDelay( 300 / portTICK_PERIOD_MS ); 
 }
}
void Taskprint(void *pvParameters)  {
  int counter = 0;
  while(1)
 {
counter++;
  Serial.println(counter); 
  vTaskDelay(500 / portTICK_PERIOD_MS);    }
}

Video
#include <Arduino_FreeRTOS.h>
void TaskBlink1( void *pvParameters );
void TaskBlink2( void *pvParameters );
void Taskprint( void *pvParameters );
void setup() {
  // initialize serial communication at 9600 bits per second:
  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();
}
void loop()
{
}
void TaskBlink1(void *pvParameters)  {
  pinMode(8, OUTPUT);
  while(1)
 {
    Serial.println("Task1");
    digitalWrite(8, HIGH);   
    vTaskDelay( 200 / portTICK_PERIOD_MS ); 
    digitalWrite(8, LOW);    
    vTaskDelay( 200 / portTICK_PERIOD_MS ); 
 }
}
void TaskBlink2(void *pvParameters)  
{
  pinMode(7, OUTPUT);
  while(1)
 {
    Serial.println("Task2");
    digitalWrite(7, HIGH);   
    vTaskDelay( 300 / portTICK_PERIOD_MS ); 
    digitalWrite(7, LOW);   
    vTaskDelay( 300 / portTICK_PERIOD_MS ); 
 }
}
void Taskprint(void *pvParameters)  {
  int counter = 0;
  while(1)
 {
counter++;
  Serial.println(counter); 
  vTaskDelay(500 / portTICK_PERIOD_MS);    }
}

PART 2
Arduino FreeRTOS Tutorial 2- Using
Queues in Arduino FreeRTOS
EMBEDDED
ByRishabh Jain Apr 06, 20200
Arduino FreeRTOS using Queues
In the previous tutorial, we introduced FreeRTOS in Arduino Uno and created a task for
the blinking LED. Now, in this tutorial, we will dive more into advance concepts of RTOS
APIs and learn about communication between different tasks. Here we also learn about
Queue to transfer data from one task to another and demonstrate the working of
queue APIs by interfacing 16x2 LCD and LDR with the Arduino Uno.

Before discussing about Queues, let’s see one more FreeRTOS API which is helpful in
deleting the tasks when it is finished with the assigned work. Sometimes the task needs
to be deleted to free the allotted memory. In continuation of the previous tutorial, we will
use vTaskDelete() API function in the same code to delete one of the tasks. A task can
use the vTaskDelete() API function to delete itself, or any other task.

To use this API, you have to configure the FreeRTOSConfig.h file. This file is used to
tailor FreeRTOS according to the application. It is used to change the scheduling
algorithms and many other parameters. The file can be found in the Arduino Directory
which is generally available in the Documents folder of your PC. In my case, it is
available in \Documents\Arduino\libraries\FreeRTOS\src as shown below.
Now, open this file using any text editor and search for the #define
INCLUDE_vTaskDelete and make sure its value is ‘1’ (1 means enable and 0 means
disable). It is 1 by default but checks for it.

We will be using this config file frequently in our next tutorials for setting the parameters.

Now, let’s see how to delete a task.


Deleting a Task in FreeRTOS Arduino
To delete a task, we have to use the vTaskDelete() API function. It takes only one
argument.

vTaskDelete( TaskHandle_t pxTaskToDelete );

pxTaskToDelete: It is the handle of the task that is to be deleted. It is the same as the
6th argument of xTaskCreate() API. In the previous tutorial, this argument is set as NULL
but you can pass the address of the contents of the task by using any name. Let say if
you want to set task handle for Task2 which is declared as

TaskHandle_t any_name;

Example: TaskHandle_t xTask2Handle;

Now, in vTaskCreate() API set 6th argument as

xTaskCreate(TaskBlink2 , "task2" , 128 , NULL, 1 , &xTask2Handle );

The content of this task can be now accessed using the handle given by you.

Also, a task can delete itself by passing NULL in place of a valid task handle.

If we want to delete Task 3 from task 3 itself, you need to


write vTaskDelete( NULL ); inside the Task3 function but if you want to delete task 3
from task 2 then write vTaskDelete(xTask3Handle ); inside the task2 function.

In previous tutorial code, to delete Task2 from task2 itself, just


add vTaskDelete(NULL); in void TaskBlink2(void *pvParameters) function. Then the
above function will look like this

void TaskBlink2(void *pvParameters)

Serial.println(“Task2 is running and about to delete”);

vTaskDelete(NULL);

pinMode(7, OUTPUT);

while(1)

digitalWrite(7, HIGH);
vTaskDelay( 300 / portTICK_PERIOD_MS );

digitalWrite(7, LOW);

vTaskDelay( 300 / portTICK_PERIOD_MS );

Now, upload the code and observe the LEDs and Serial monitor. You will see that the
second LED is not blinking now and task2 is deleted after encountering the delete API.

So this API can be used to stop the execution of the particular task.

Now, let’s start with the Queue.

What is the Queue in FreeRTOS?


Queue is the data structure that can hold the finite number of fixed size elements and it
is operated in the FIFO scheme (First-in First-out). Queues provide a task-to-task, task-
to-interrupt, and interrupt-to-task communication mechanism.

The maximum number of elements queue can hold is called its “length”. Both the length
and the size of each element are set when the queue is created.

An example of how the queue is used for data transfer is illustrated well in FreeRTOS
documentation that can be found here. You can easily understand the given example.
After understanding the Queues, let’s try to understand the process of creating a queue
and try to implement it in our FreeRTOS code.

Creating a Queue in FreeRTOS


First, describe the problem statement that is to be implemented with the help of the
FreeRTOS queue and Arduino Uno.

We want to print the value of the LDR sensor on 16*2 LCD. So there are two tasks
now

1. Task1 is getting analog values of LDR.


2. Task2 is printing the analog value on LCD.
So, here queue plays its role because to send the data generated by task1 to task2. In
task1, we will send analog value to the queue and in task2, we will receive it from the
queue.

There are three functions to work with queues

1. Creating a Queue
2. Sending data to Queue
3. Receiving data from Queue
1. Creating a Queue
For creating queue, use xQueueCreate() function API. It takes two arguments.

xQueueCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize );

uxQueueLength: The maximum number of items that the queue being created can hold
at any one time.

uxItemSize: The size in bytes of each data item that can be stored in the queue.

If this function returns NULL then the queue is not created due to insufficient memory
and if it returns a non-NULL value, the queue is created successfully. Store this return
value to a variable to use it as a handle to access the queue as shown below.

QueueHandle_t queue1;

queue1 = xQueueCreate(4,sizeof(int));

This will create a 4 element queue in heap memory of int size (2 bytes of each block)
and store the return value to the queue1 handle variable.

2. Sending Data to Queue in FreeRTOS

To send the values to the queue, FreeRTOS has 2 variants of API for this purpose.

1. xQueueSendToBack(): Used to send data to the back (tail) of a queue.


2. xQueueSendToFront(): Used to send data to the front (head) of a queue.
Now, xQueueSend() is equivalent to, and exactly the same as, xQueueSendToBack().

All these APIs takes 3 arguments.

xQueueSendToBack( QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t


xTicksToWait );

xQueue: The handle of the queue to which the data is being sent (written). This variable
is the same as used to store the return value of xQueueCreate API.

pvItemToQueue: A pointer to the data to be copied into the queue.

xTicksToWait: The maximum amount of time the task should remain in the Blocked
state to wait for space to become available in the queue.
Setting xTicksToWait to portMAX_DELAY will cause the task to wait indefinitely (without
timing out), provided INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h else
you can use the macro pdMS_TO_TICKS() to convert a time specified in milliseconds
into a time specified in ticks.

3. Receiving Data from Queue in FreeRTOS

To receive (read) an item from a queue, xQueueReceive() is used. The item that is


received is removed from the queue.

This API also takes three arguments.

xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t


xTicksToWait );

First and third arguments are the same as sending API. Only the second argument is
different.

const pvBuffer: A pointer to the memory into which the received data will be copied.

Hope you understood the three APIs. Now, we will implement these APIs in the Arduino
IDE and try to solve the problem statement that we have described above.

Circuit Diagram

This is how it looks on the breadboard:


Implementing FreeRTOS Queue in Arduino IDE
Let’s start writing code for our application.

1. First, open Arduino IDE and include the Arduino_FreeRTOS.h header file. Now, if any
kernel object like queue is used then include the header file of it. As we are using 16*2
LCD so include the library for it also.

#include <Arduino_FreeRTOS.h>

#include <queue.h>

#include <LiquidCrystal.h>

2. Initialize a queue handle to store the contents of the queue. Also, initialize LCD pin
numbers.

QueueHandle_t queue_1;

LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

3. In void setup(), initialize LCD and serial monitor with 9600 baud rate. Create a queue
and two tasks using the respective APIs. Here we will create a queue of size 4 with
integer type. Create a task with equal priorities and later on try to play with this number.
Finally, start the scheduler as shown below.
void setup() {

Serial.begin(9600);

lcd.begin(16, 2);

queue_1 = xQueueCreate(4, sizeof(int));

if (queue_1 == NULL) {

Serial.println("Queue can not be created");

xTaskCreate(TaskDisplay, "Display_task", 128, NULL, 1, NULL);

xTaskCreate(TaskLDR, "LDR_task", 128, NULL, 1, NULL);

vTaskStartScheduler();

4. Now, make two functions TaskDisplay and TaskLDR. In TaskLDR function, read


analog pin A0 in a variable as we have LDR connected to the A0 pin of Arduino UNO.
Now send the value stored in the variable by passing it in the xQueueSend API and
send the task to block state after 1 second using vTaskDelay() API as shown below.

void TaskLDR(void * pvParameters) {

int current_intensity;

while(1) {

Serial.println("Task1");

current_intensity = analogRead(A0);

Serial.println(current_intensity);

xQueueSend(queue_1, &current_intensity, portMAX_DELAY);

vTaskDelay( 1000 / portTICK_PERIOD_MS );

5. Similarly, make a function for TaskDisplay and receive the values in a variable that is


passed to the xQueueReceive function. Also, xQueueReceive() returns pdPASS if the
data can be received successfully from the queue and returns errQUEUE_EMPTY if a
queue is empty.

Now, display the values to the LCD using lcd.print() function.

void TaskDisplay(void * pvParameters) {

int intensity = 0;

while(1) {

Serial.println("Task2");

if (xQueueReceive(queue_1, &intensity, portMAX_DELAY) == pdPASS) {

lcd.clear();

lcd.setCursor(0, 0);

lcd.print("Intensity:");

lcd.setCursor(11, 0);

lcd.print(intensity);

That’s it. We have finished the coding part of Queue implementation. Complete code
with a working Video can be found at the end.

Now, connect the LCD and LDR with Arduino UNO according to the circuit diagram
upload the code. Open the serial monitor and observe the tasks. You will see tasks are
switching and LDR values are changing according to the light intensity.
NOTE: Most of the libraries made for different sensors are not supported by the
FreeRTOS kernel due to delay function implementation inside the libraries. Delay makes
the CPU stop completely, therefore, the FreeRTOS kernel also stops working and code
will not execute further and it starts misbehaving. So, we have to make the libraries
delay-free to work with the FreeRTOS.

Code
#include <Arduino_FreeRTOS.h>
#include <queue.h>
#include <LiquidCrystal.h>
QueueHandle_t queue_1;
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);    //  RST E  D4 D5  D6 D7
void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
queue_1 = xQueueCreate(5, sizeof(int));
  if (queue_1 == NULL) {
    Serial.println("Queue can not be created");
 }
  xTaskCreate(TaskDisplay, "Display_task", 128, NULL, 1, NULL);
  xTaskCreate(TaskLDR, "LDR_task", 128, NULL, 1, NULL);
  vTaskStartScheduler();
}
void loop() {
}
void TaskDisplay(void * pvParameters) {
  int intensity = 0;
  while(1) {
    Serial.println("TaskDisplay");
    if (xQueueReceive(queue_1, &intensity, portMAX_DELAY) == pdPASS) {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Intensity:");
      lcd.setCursor(11, 0);
      lcd.print(intensity);
  }
 }
}
void TaskLDR(void * pvParameters) {
  int current_intensity; 
  while(1) {
    Serial.println("TaskLDR");
    current_intensity = analogRead(A0);
    Serial.println(current_intensity);
    xQueueSend(queue_1, &current_intensity, portMAX_DELAY);
    vTaskDelay( 1000 / portTICK_PERIOD_MS );
 }
}

Video
PART 3
Arduino FreeRTOS Tutorial 3- Using
Semaphore and Mutex in FreeRTOS
with Arduino
EMBEDDED
ByRishabh Jain Apr 09, 20200
Semaphore and Mutex in FreeRTOS with Arduino
In previous tutorials, we have covered the basics of FreeRTOS with Arduino and
the Queue kernel object in FreeRTOS Arduino. Now, in this third FreeRTOS tutorial, we
will learn more about FreeRTOS and its advance APIs, which can make you understand
the multi-tasking platform more deeply.

Semaphore and Mutex (Mutual Exclusion) are the kernel objects that are used for
synchronization, resource management and protecting resources from corruption. In the
first half of this tutorial, we will see the idea behind Semaphore, how and where to use
it. In the second half, we will continue with Mutex.

What is Semaphore?
In previous tutorials, we have discussed about task priorities and also get to know that a
higher priority task pre-empts a lower priority task so while execution of high priority task
there may be a possibility that data corruption can happen in lower priority task because
it is not executed yet and data is coming continuously to this task from a sensor which
causes data loss and malfunctioning of the whole application.

So, there is a need to protect resources from data loss and here Semaphore plays an
important role.

Semaphore is a signaling mechanism in which a task in a waiting state is signaled by


another task for execution. In other words, when a task1 finished its work, then it will
show a flag or increment a flag by 1 and then this flag is received by another task (task2)
showing that it can perform its work now. When task2 finished its work then the flag will
be decreased by 1.
So, basically, it is a “Give” and “Take” mechanism and semaphore is an integer variable
that is used to synchronize access to resources.

Types of Semaphore in FreeRTOS:

Semaphore is of two types.

1. Binary Semaphore
2. Counting Semaphore
1. Binary Semaphore: It has two integer values 0 and 1. It is somewhat similar to the
Queue of length 1. For example, we have two tasks, task1 and task2. Task1 sends data
to task2 so task2 continuously checks the queue item if there is 1, then it can read the
data else it has to wait until it becomes 1. After taking the data, task2 decrement the
queue and make it 0 That means task1 again can send the data to task2.

From the above example, it can be said that binary semaphore is used for
synchronization between tasks or between tasks and interrupt.

2. Counting Semaphore: It has values greater than 0 and can be thought of queue of
length more than 1. This semaphore is used for counting events. In this usage scenario,
an event handler will ‘give’ a semaphore each time an event occurs (incrementing the
semaphore count value), and a handler task will ‘take’ a semaphore each time it
processes an event (decrementing the semaphore count value).

The count value is, therefore, the difference between the number of events that have
occurred and the number that has been processed.

Now, let's see how to use Semaphore in our FreeRTOS code.

How to use Semaphore in FreeRTOS?


FreeRTOS supports different APIs for creating a semaphore, taking a semaphore and
giving a semaphore.

Now, there can be two types of APIs for the same kernel object. If we have to give
semaphore from an ISR, then normal semaphore API cannot be used. You should use
interrupt protected APIs.

In this tutorial, we will use binary semaphore because it is easy to understand and


implement. As interrupt functionality is used here, you need to use interrupt protected
APIs in ISR function. When we are saying synchronizing a task with an interrupt, it
means putting the task into Running state right after the ISR.

Creating a Semaphore:

To use any kernel object, we have to first create it. For creating a binary semaphore,
use vSemaphoreCreateBinary().

This API does not take any parameter and returns a variable of type
SemaphoreHandle_t. A global variable name sema_v is created to store the
semaphore.
SemaphoreHandle_t sema_v;

sema_v = xSemaphoreCreateBinary();

Giving a semaphore:

For giving a semaphore, there are two versions- one for interrupt and another one for the
normal task.

1. xSemaphoreGive(): This API takes only one argument which is the variable


name of semaphore like sema_v as given above while creating a semaphore. It can
be called from any normal task that you want to synchronize.
2. xSemaphoreGiveFromISR(): This is the interrupt protected API version of
xSemaphoreGive(). When we need to synchronize an ISR and normal task, then
xSemaphoreGiveFromISR() should be used from the ISR function.
Taking a semaphore:

To take a semaphore, use API function xSemaphoreTake(). This API takes two


parameters.

xSemaphoreTake( SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait );

xSemaphore: Name of the semaphore to be taken in our case sema_v.

xTicksToWait: This is the maximum amount of time that the task will wait in Blocked
state for the semaphore to become available. In our project, we will
set xTicksToWait to portMAX_DELAY to make the task_1 to wait indefinitely in Blocked
state until the sema_v is available.

Now, let's use these APIs and write a code to perform some tasks.

Here one push-button and two LEDs are interfaced. The push-button will act as an
interrupt button which is attached to pin 2 of Arduino Uno. When this button is pressed
an interrupt will be generated and an LED which is connected to pin 8 will be turned ON
and when you press it again it will be OFF.

So, when button is pressed xSemaphoreGiveFromISR() will be called from ISR function


and xSemaphoreTake() function will be called from TaskLED function.

To make the system look multitasking, connect other LEDs with pin 7 which will be in
always blinking state.

Semaphore Code Explanation


Let’s start writing code for by opening the Arduino IDE

1. First, include the Arduino_FreeRTOS.h header file. Now, if any kernel object is used


like queue semaphore then a header file must also be included for it.

#include <Arduino_FreeRTOS.h>
#include <semphr.h>

2. Declare a variable of type SemaphoreHandle_t to store the values of semaphore.

SemaphoreHandle_t interruptSemaphore;

3. In void setup(), create two tasks(TaskLED and TaskBlink)using the xTaskCreate() API
and then create a semaphore using xSemaphoreCreateBinary().Create a task with equal
priorities and later on try to play with this number. Also, Configure pin 2 as an input and
enable the internal pull-up resistor and attach the interrupt pin. Finally, start the
scheduler as shown below.

void setup() {

pinMode(2, INPUT_PULLUP);

xTaskCreate(TaskLed, "Led", 128, NULL, 0, NULL );

xTaskCreate(TaskBlink, "LedBlink", 128, NULL, 0, NULL );

interruptSemaphore = xSemaphoreCreateBinary();

if (interruptSemaphore != NULL) {

attachInterrupt(digitalPinToInterrupt(2), debounceInterrupt, LOW);

4. Now, implement the ISR function. Make a function and name it the same as the
second argument of attachInterrupt() function. To make the interrupt work properly, you
need to remove the debounce problem of the pushbutton using millis or micros function
and by adjusting the debouncing time. From this function,
call interruptHandler() function as shown below.

long debouncing_time = 150;

volatile unsigned long last_micros;

void debounceInterrupt() {

if((long)(micros() - last_micros) >= debouncing_time * 1000) {

interruptHandler();

last_micros = micros();
}

In interruptHandler() function, call xSemaphoreGiveFromISR() API.

void interruptHandler() {

xSemaphoreGiveFromISR(interruptSemaphore, NULL);

This function will give a semaphore to TaskLed to turn ON the LED.

5. Create a TaskLed function and inside the while loop, call xSemaphoreTake() API


and check if the semaphore is successfully taken or not. If it is equal to pdPASS (i.e 1)
then make the LED toggle as shown below.

void TaskLed(void *pvParameters)

(void) pvParameters;

pinMode(8, OUTPUT);

while(1) {

if (xSemaphoreTake(interruptSemaphore, portMAX_DELAY) == pdPASS) {

digitalWrite(8, !digitalRead(8));

6. Also, create a function to blink other LED connected to pin 7.

void TaskLed1(void *pvParameters)

(void) pvParameters;

pinMode(7, OUTPUT);
while(1) {

digitalWrite(7, HIGH);

vTaskDelay(200 / portTICK_PERIOD_MS);

digitalWrite(7, LOW);

vTaskDelay(200 / portTICK_PERIOD_MS);

7. The void loop function will remain empty. Don’t forget it.

void loop() {}

That’s it, complete code can be found at the end of this tutorial. Now, upload this code
and connect the LEDs and push-button with the Arduino UNO according to the circuit
diagram.

Circuit Diagram

After uploading the code, you will see an LED is blinking after 200ms and when the
button is pressed, immediately the second LED will glow as shown in the video given at
the end.
In this way, semaphores can be used in FreeRTOS with Arduino where it needs to
pass the data from one task to another without any loss.

Now, let’s see what is Mutex and how to use it FreeRTOS.

What is Mutex?
As explained above semaphore is a signaling mechanism, similarly, Mutex is a locking
mechanism unlike the semaphore that has separate functions for increment and
decrement but in Mutex, the function takes and gives in itself. It is a technique to avoid
the corruption of shared resources.

To protect the shared resource, one assigns a token card (mutex) to the resource.
Whoever has this card can access the other resource. Others should wait until the card
returned. In this way, only one resource can access the task and others wait for their
chance.

Let’s understand Mutex in FreeRTOS with the help of an example.

Here we have three tasks, One for printing data on LCD, second for sending LDR data
to LCD task and last task for sending Temperature data on LCD. So here two tasks are
sharing the same resource i.e. LCD. If the LDR task and temperature task send data
simultaneously then one of the data may be corrupted or lost.

So to protect the data loss, we need to lock the LCD resource for task1 until it finished
the display task. Then the LCD task will unlock and then task2 can perform its work.

You can observe the working of Mutex and semaphores in the below diagram.
How to use Mutex in FreeRTOS?
Mutexs are also used in the same way as semaphores. First, create it, then give and
take using respective APIs.

Creating a Mutex:

To create a Mutex, use xSemaphoreCreateMutex() API. As its name suggests that


Mutex is a type of Binary semaphore. They are used in different contexts and purposes.
A binary semaphore is for synchronizing tasks while Mutex is used for protecting a
shared resource.

This API does not take any argument and returns a variable of
type SemaphoreHandle_t. If the mutex cannot be
created, xSemaphoreCreateMutex() return NULL.

SemaphoreHandle_t mutex_v;

mutex_v = xSemaphoreCreateMutex();

Taking a Mutex:

When a task wants to access a resource, it will take a Mutex by


using xSemaphoreTake() API. It is the same as a binary semaphore. It also takes two
parameters.

xSemaphore: Name of the Mutex to be taken in our case mutex_v.

xTicksToWait: This is the maximum amount of time that the task will wait in Blocked
state for the Mutex to become available. In our project, we will
set xTicksToWait to portMAX_DELAY to make the task_1 to wait indefinitely in Blocked
state until the mutex_v is available.

Giving a Mutex:
After accessing the shared resource, the task should return the Mutex so that other
tasks can access it. xSemaphoreGive() API is used to give the Mutex back.

The xSemaphoreGive() function takes only one argument which is the Mutex to be given
in our case mutex_v.

Using the above APIs, Let’s implement Mutex in the FreeRTOS code using Arduino
IDE.

Mutex Code Explanation


Here the goal for this part is to use a Serial monitor as a shared resource and two
different tasks to access the serial monitor to print some message.

1. The header files will remain the same as a semaphore.

#include <Arduino_FreeRTOS.h>

#include <semphr.h>

2. Declare a variable of type SemaphoreHandle_t to store the values of Mutex.

SemaphoreHandle_t mutex_v;

3. In void setup(), initialize serial monitor with 9600 baud rate and create two
tasks(Task1 and Task2) using the xTaskCreate() API. Then create a Mutex
using xSemaphoreCreateMutex(). Create a task with equal priorities and later on try to
play with this number.

void setup() {

Serial.begin(9600);

mutex_v = xSemaphoreCreateMutex();

if (mutex_v == NULL) {

Serial.println("Mutex can not be created");

xTaskCreate(Task1, "Task 1", 128, NULL, 1, NULL);

xTaskCreate(Task2, "Task 2", 128, NULL, 1, NULL);

4. Now, make task functions for Task1 and Task2. In a while loop of task function, before
printing a message on the serial monitor we have to take a Mutex
using xSemaphoreTake() then print the message and then return the Mutex
using xSemaphoreGive(). Then give some delay.

void Task1(void *pvParameters) {

while(1) {

xSemaphoreTake(mutex_v, portMAX_DELAY);

Serial.println("Hi from Task1");

xSemaphoreGive(mutex_v);

vTaskDelay(pdMS_TO_TICKS(1000));

Similarly, implement Task2 function with a delay of 500ms.

5. Void loop() will remain empty.

Now, upload this code on Arduino UNO and open the serial monitor.

You will see messages are printing from task1 and task2.

To test the working of Mutex, just comment xSemaphoreGive(mutex_v); from any task.


You can see that the program hangs on the last print message.
This is how Semaphore and Mutex can be implemented in FreeRTOS with Arduino. For
more information on Semaphore and Mutex, you can visit the official documentation of
FreeRTOS.

Complete codes and video for Semaphore and Mutes are given below.

Code
1 CODE for Semaphore:

2  

#include <Arduino_FreeRTOS.h>
3
#include <semphr.h>
4
long debouncing_time = 150;
5
volatile unsigned long last_micros;
6
 
7
SemaphoreHandle_t interruptSemaphore;
8
 
9
void setup() {
10
  pinMode(2, INPUT_PULLUP);

11
  xTaskCreate(TaskLed,  "Led", 128, NULL, 0, NULL );
12 xTaskCreate(TaskBlink,  "LedBlink", 128, NULL, 0, NULL );

  interruptSemaphore = xSemaphoreCreateBinary();
13
  if (interruptSemaphore != NULL) {
14
    attachInterrupt(digitalPinToInterrupt(2), debounceInterrupt, LOW);
15
  }
16
}
17
 
18
void loop() {}
19
 
20
void interruptHandler() {

21
  xSemaphoreGiveFromISR(interruptSemaphore, NULL);

22 }

23  

24 void TaskLed(void *pvParameters)

25 {

26   (void) pvParameters;

  pinMode(8, OUTPUT);
27
  for (;;) {
28
    if (xSemaphoreTake(interruptSemaphore, portMAX_DELAY) == pdPASS) {
29
      digitalWrite(8, !digitalRead(8));
30
    }
31
  }
32
}

33 void TaskBlink(void *pvParameters)

34 {

35   (void) pvParameters;
36   pinMode(7, OUTPUT);

  for (;;) {
37
      digitalWrite(7, HIGH);
38
      vTaskDelay(200 / portTICK_PERIOD_MS);
39
      digitalWrite(7, LOW);
40
      vTaskDelay(200 / portTICK_PERIOD_MS);
41
  }
42
}

43
void debounceInterrupt() {

44   if((long)(micros() - last_micros) >= debouncing_time * 1000) {

45     interruptHandler();

46     last_micros = micros();

47   }

}
48

49  

CODE for Mutex:


50
#include <Arduino_FreeRTOS.h>
51
#include <semphr.h>
52
 
53
SemaphoreHandle_t mutex_v;
54
void setup() {
55
    Serial.begin(9600);

56     mutex_v = xSemaphoreCreateMutex();

57     if (mutex_v == NULL) {

58         Serial.println("Mutex can not be created");

59     }
60     xTaskCreate(Task1, "Task1", 128, NULL, 1, NULL);

    xTaskCreate(Task2, "Task2", 128, NULL, 1, NULL);


61
}
62
 
63
void Task1(void *pvParameters) {
64
    while(1) {
65
        xSemaphoreTake(mutex_v, portMAX_DELAY);
66
        Serial.println("Hi from Task1");
67
        xSemaphoreGive(mutex_v);

68
        vTaskDelay(pdMS_TO_TICKS(1000));

69     }

70 }

71  

72 void Task2(void *pvParameters) {

73     while(1) {

        xSemaphoreTake(mutex_v, portMAX_DELAY);
74
        Serial.println("Hi from Task2");
75
        xSemaphoreGive(mutex_v);
76
        vTaskDelay(pdMS_TO_TICKS(500));
77
    }
78
}
79
 
80
void loop() {

81 }

82

83
84

85

86

87

88

Video
CODE for Semaphore:
 
#include <Arduino_FreeRTOS.h>
#include <semphr.h>
long debouncing_time = 150;
volatile unsigned long last_micros;
 
SemaphoreHandle_t interruptSemaphore;
 
void setup() {
  pinMode(2, INPUT_PULLUP);
  xTaskCreate(TaskLed,  "Led", 128, NULL, 0, NULL );
xTaskCreate(TaskBlink,  "LedBlink", 128, NULL, 0, NULL );
  interruptSemaphore = xSemaphoreCreateBinary();
  if (interruptSemaphore != NULL) {
    attachInterrupt(digitalPinToInterrupt(2), debounceInterrupt, LOW);
  }
}
 
void loop() {}
 
void interruptHandler() {
  xSemaphoreGiveFromISR(interruptSemaphore, NULL);
}
 
void TaskLed(void *pvParameters)
{
  (void) pvParameters;
  pinMode(8, OUTPUT);
  for (;;) {
    if (xSemaphoreTake(interruptSemaphore, portMAX_DELAY) == pdPASS) {
      digitalWrite(8, !digitalRead(8));
    }
  }
}
void TaskBlink(void *pvParameters)
{
  (void) pvParameters;
  pinMode(7, OUTPUT);
  for (;;) {
      digitalWrite(7, HIGH);
      vTaskDelay(200 / portTICK_PERIOD_MS);
      digitalWrite(7, LOW);
      vTaskDelay(200 / portTICK_PERIOD_MS);
  }
}
void debounceInterrupt() {
  if((long)(micros() - last_micros) >= debouncing_time * 1000) {
    interruptHandler();
    last_micros = micros();
  }
}
 
CODE for Mutex:
#include <Arduino_FreeRTOS.h>
#include <semphr.h>
 
SemaphoreHandle_t mutex_v;
void setup() {
    Serial.begin(9600);
    mutex_v = xSemaphoreCreateMutex();
    if (mutex_v == NULL) {
        Serial.println("Mutex can not be created");
    }
    xTaskCreate(Task1, "Task1", 128, NULL, 1, NULL);
    xTaskCreate(Task2, "Task2", 128, NULL, 1, NULL);
}
 
void Task1(void *pvParameters) {
    while(1) {
        xSemaphoreTake(mutex_v, portMAX_DELAY);
        Serial.println("Hi from Task1");
        xSemaphoreGive(mutex_v);
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}
 
void Task2(void *pvParameters) {
    while(1) {
        xSemaphoreTake(mutex_v, portMAX_DELAY);
        Serial.println("Hi from Task2");
        xSemaphoreGive(mutex_v);
        vTaskDelay(pdMS_TO_TICKS(500));
    }
}
 
void loop() {
}

Tutorial
Understanding Real Time Operating
System (RTOS) and How to use it for
your next Embedded Design
EMBEDDED
BySunakshi Aug 29, 20190

Understanding Real
Time Operating System (RTOS)

Embedded systems have a wide range of application in all the electronic devices around
us, an evident example is the mini laptop that we carry around with us all the time, yes I
am referring to our mobile phones.

Whenever embedded system comes into picture it is always a combination of hardware


like Microcontrollers or Microprocessors and software like a firmware or Operating
system. An Operating System forms the base of all the electronics devices and
manages both the hardware and the software within any electronic device. The term
operating system is not only limited to Unix and Windows for computers but can also
extend to microcontrollers. One such operating system that can run on Microcontrollers
is called as Real time operating system. Here we will learn about RTOS
and applications of real time operating system.

What is RTOS?
Real time operating system popularly known as RTOS provides controller with the ability
to respond to input and complete tasks within a specific period of time based on priority.
On the first look, an RTOS might sound like just any other embedded program or
firmware, but it is built on the architecture of an Operating system. Hence, like any
operating system RTOS can allow multiple programs to execute at the same time
supporting multiplexing. As we know the core of a processor or controller can only
execute a single instruction at a time, but the RTOS has something called
the scheduler which decides which instruction to execute first and thus executes the
instructions of multiple programs one after the other. Technically an RTOS only creates
an illusion of multi-taking by executing paralleled instructions one at a time.

This makes RTOS suitable for various applications in real world. In RTOS for any input
whenever a logic has been evaluated which gives the corresponding output. This logic is
measured on the basis of not only the logical creativeness but also on the time duration
in which the specific task has been performed. If a system fails in performing task in that
specific duration of time it is known as system failure.

Why RTOS??
 Availability of drivers: There are many drivers available within RTOS, which
allows us to use them directly for various applications.
 Scheduled files: RTOS takes care of scheduling so instead of focusing on
scheduling any system we can simply focus on developing application. For example,
task scheduling files are used to define certain actions whenever a set of conditions
are met. RTOS uses certain advanced algorithms for scheduling typically running,
ready and blocked states which while running RTOS keeps more focus on developing
application rather than scheduling.  
 Flexibility of adding features: Within RTOS even if you are willing to add new
features , you can simply add it without disturbing the existing features

Difference between Real time Operating System &


Operating System
There are various differences between real time operating system and operating
systems like Windows, Linux etc. Let’s have a look at them one by one with the help of
table format:

S.No Operating System Real time System

Time sharing is the basis of execution Processes are executed on the basis of
1
of processes in operating system the order of their priority

Operating system acts as an interface


Real time system is designed to have its
 2 between the hardware and software of
execution for the real world problems
a system

Managing memory is not a critical issue Memory management is difficult as based on


3 when it comes to execution of the real time issue memory is allocated ,
operating system which itself is critical
Applications: Office , Data centers , Applications: Controlling aircraft or nuclear
4
System for home etc reactor , scientific research equipments

Examples : Microsoft Windows ,


5 Examples: Vx Works ,QNX , Windows CE
Linux ,OS

Types of RTOS
We can categorize real time operating system majorly into three parts namely

1. Hard real time operating system


2. Soft real time operating system
3. Firm real time operating system
1. Hard real time operating system

Let’s start understanding this type of operating system using an example, the live
example of it is flight control system. Within flight control system whatever tasks is given
by the pilot in the form of an input it should be performed on time. In a hard real time
Operating system, system failures can be tolerated. The features of hard RTOS are:

 To perform tasks on time


 Failure to meet deadline is fatal
 Guaranteed worse case response time
 Can lead to system failure
2. Soft real time operating system

Easiest example of using soft RTOS is online database, as within soft RTOS the
parameter we are more worried about is speed. Hence, the features of soft RTOS are:

 Tasks should be performed as fast as possible


 Late completion of tasks is undesirable but not fatal
 There is a possibility of performance degradation
 Cannot lead to system failure
3. Firm real-time operating system

Robot arm which is used to pick objects can be considered as among one of the
example of firm RTOS. Here, within this firm RTOS even if the process is delayed it’s
tolerated.

Benefits of using free RTOS


The following are the advantages of using RTOS in your applications.

 No firewall issues
 Low bandwidth for enhanced performance
 Improved security and privacy
 Low cost, due to reduction in hardware and software components used for
development
Some major issues related to RTOS
Now, despite of having many advantages for RTOS in real world application, it has
various disadvantages also. Some of the issues related to it are discussed here.

 Interrupts are normally used in programs to halt the executing program to divert
the flow to some other important part of the code. Here, within RTOS since quick
response time is required; it is recommended that interrupts should be disabled for
a minimum possible time.
 Since, the kernel should also respond for various events it is required to
have lesser size of kernel  so that it should fit properly within ROM
 Sophisticated features of RTOS should be removed as there is no concept of as
such virtual memory within it.

How to use RTOS


Now that you know what is RTOS and where you can use it, to get started with
RTOS you normally have to use the Tornado or the FreeRTOS development
environment. Let us take a brief look into both these development environment.

Tornado – VxWorks

Tornado is an integrated environment to develop real time related embedded


RTOS applications on the target system. Tornado consists of three basic elements
which are listed below.

1) VxWorks

2) Application building tools (compiler and associated programs)

3) Integrated development environment, which can manage, debug and monitor


VxWorks application
Torn
ado development environment

VxWorks is a networked real time operating system. To begin with VxWorks we should
have one development kit (target) along with one workstation. Here, development kit is
nothing but the target host or component which communicates with the target server on
the workstation. The target here connects tornado tools such as the shell and
the debugger. Therefore, using VxWorks we will configure and built the systems while
Tornado provides us a graphical user interface and command line tools for
configuration and build.

Very important point which comes into picture here is that while installing tornado within
your system the installation directory should use the pathnames as:
installDir/target. For example if you wish to store your tornado in C:\tornado on a
windows host the full pathname should be identified in that case as
installDir/target/h/vxworks.h.

Here, we will not discuss in detail regarding the features of Vx works (we will leave that
for next tutorial) but we will discuss how the development can be done using C++ within
Vxworks using WindRiver GNU.  WindRiver GNU helps us in providing a graphical
analysis regarding the interrupt involved during execution as well as the memory usage
report.
For example, the above stated view of WindRiver explains the associated processor
number along with the priority of tasks (tLowPri & tHighPri). Idle state i.e green color line
stated the time period for which processor is not in its working state, which is observed
to be after every few seconds.  t1 , t7, t8 & t9 are nothing but the various processors
used. Here, we are selecting only t7 processor.

Hence, this Windriver is capable of invoking both VxWorks and application module
subroutines. You can launch the Windriver application either form the tornado launch
tool bar (-> i button) later click on menu and then click on shell. Lastly, from the
command prompt type “>windsh target server”.

Now to program using C++ , it’s important to include  INCLUDE_CPLUS_DEMANGLER


component , this demangler component allows target shell symbols to return human
readable forms of C++  symbol names. Before , downloading C++ module to Vxworks
target  , follow process known as munching . Here, munching refers to additional host
processing step.

Compile C++ application source program and get for example hello.cpp file . Later run it
to munch on the .o and compile the generated ctdt.c file. Further, link the application with
ctdt.o to generate downloadable module , hello.out within VxWorks. The output after
executing this VxWorks will be a make file which will be using on some target .

Free RTOS

Generally, whenever we begin with RTOS we generally prefer Vx Works RTOS. But ,
here let’s have a discussion in brief regarding the Free RTOS , which can also be used
to by beginners to go through concept of real time operating system . Free RTOS is
developed by Richard Barry and FreeRTOS team ,also it is owned by Real time
engineers ltd but it is free to use and can be simply downloaded by clicking on the link
below

Download Free ROTS


Latest version of free RTOS being used at the time of this article is version 10, stated as
FreeRTOS V10.

The biggest advantage of free RTOS which makes it superior in terms of the other
RTOS is its platform independent behavior in terms of hardware i.e the c code which
we will be using to execute an operating system can run on various platforms having
different architecture. Therefore irrespective of whether you are using 8051
microcontroller or some latest ARM microcontroller the code which you wrote along with
the process of execution will be similar for both.

There are many other benefits of using free RTOS over Vx works and other RTOS
operating tools. Some of them can be stated as:

1. Provides easier testing


2. Promotes the concept of code reusability
3. Lesser idle time
4. Easy maintainability
5. Abstract out timing information
Also, the basic Kernel, where Kernel refers to the central component of an operating
system which is present within the free RTOS makes it accessible to use for various
applications. Since it is easy to attach expanded modules on operating systems to get its
more applications free RTOS becomes more powerful.

One of the examples of using free RTOS can be explained by using the concept of
combining Free RTOS with Nabto. Nabto is a free web device used to transfer the
information from the device to the browser.

Therefore on combining Free RTOS with Nabto makes it a small piece of C code as


explained in figure a. Now a days Internet of  Things (IOT) is in trend and every IOT
device we will be accessing has a unique URL over the internet and the technology
allows secure and extremely low bandwidth point to point connections. In the absence of
internet connectivity this combination can be helpful. Therefore, free RTOS is a popular
choice when it comes to implementing IOT.

You might also like