Sunday, April 15, 2018

Arduino FreeRTOS - How to use Arduino with Real Time operating systems

What is RTOS?

All computers and processors have the same rule, in one processor core only one process can be running at any given time.


So how could computers and processors support multitasking?


The operating system running on the processor has a dedicated part that called the Scheduler.

It can handle times for many tasks by given every task a bit of time.

By rapidly switching between all different tasks the overall process seems as if the processor is multitasking all those processes.

In embedded systems (like Arduino or any other system) there must be a system for handling those times between different tasks.
So there must be a predefined priority for each task.

Due to the fact that most embedded systems are controlling tasks that touch our real world and life, there must by a system for that prioritization issue.

In Arduino, setup() and loop() functions don’t support multi-tasking effectively.





How can we use Arduino with FreeRTOS?

You can use Arduino with a widely known Real-time Operating System like FreeRTOS by adding libraries that can fit inside your Arduino board and smoothly manage timing for all your tasks.

Starting from Arduino IDE version 1.6.8 you can find FreeRTOS library in library manager under the Type: “Contributed” and the Topic: “Timing”.

After you add the FreeRTOS library into your sketch, the empty sketch should look like this.



Then you can add any program or example from Arduino IDE.

Here, the blink example is used combined with Analog_Read using multitasking from FreeRTOS.



Code
#include 

// define two tasks for Blink & AnalogRead
void TaskBlink( void *pvParameters );
void TaskAnalogRead( void *pvParameters );

// the setup function runs once when you press reset or power the board
void setup() {

  // Now set up two tasks to run independently.
  xTaskCreate(
    TaskBlink
    ,  (const portCHAR *)"Blink"   // A name just for humans
    ,  128  // Stack size
    ,  NULL
    ,  2  // priority
    ,  NULL );

  xTaskCreate(
    TaskAnalogRead
    ,  (const portCHAR *) "AnalogRead"
    ,  128 // This stack size can be checked & adjusted by reading Highwater
    ,  NULL
    ,  1  // priority
    ,  NULL );

  // Now the task scheduler, which takes over control of scheduling individual tasks, is automatically started.
}

void loop()
{
  // Empty. Things are done in Tasks.
}

/*--------------------------------------------------*/
/*---------------------- Tasks ---------------------*/
/*--------------------------------------------------*/

void TaskBlink(void *pvParameters)  // This is a task.
{
  (void) pvParameters;

  // initialize digital pin 13 as an output.
  pinMode(13, OUTPUT);

  for (;;) // A Task shall never return or exit.
  {
    digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
    vTaskDelay( 1000 / portTICK_PERIOD_MS ); // wait for one second
    digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
    vTaskDelay( 1000 / portTICK_PERIOD_MS ); // wait for one second
  }
}

void TaskAnalogRead(void *pvParameters)  // This is a task.
{
  (void) pvParameters;

  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);

  for (;;)
  {
    // read the input on analog pin 0:
    int sensorValue = analogRead(A0);
    // print out the value you read:
    Serial.println(sensorValue);
    vTaskDelay(1);  // one tick delay (15ms) in between reads for stability
  }
}



Source: Arduino Website







No comments: