Setting up RIOT-OS on Arduino – An Operating System for Internet of Things

Getting Started with Arduino and RIOT-OS

When we talk about embedded projects, Arduino comes first in our mind. But why Arduino? Because Arduino is a Single-core Microcontroller, which is available in the market at a very low price. And besides, there are various supported sensor/actuator boards available, which we can use as a plug and play. Here at IoTDesignPro, we have also built many IoT projects with Arduino, you can check them out if interested.

 

But when it comes to applications with time complexity, where we have to execute multiple tasks in real-time, we start doubting. Is Arduino good for this project or should we change it? What will we do? Here, RIOT comes as a rescue. 

 

You might be thinking what is RIOT? Well, RIOT is not a complicated thing, in fact, it is a real-time operating system for embedded systems that comes with various libraries, to help us to complete the IoT operation as well. In short, we call RIOT-OS “the friendly operating system for IoT”. We already covered the tutorial on “What and How to use RIOT-OS in Embedded Devices” where we can know more about the RIOT-OS.

 

In this tutorial, we are Getting Started with Arduino and RIOT-OS, and Setting up RIOT-OS on Arduino. We will demonstrate a LED blink operation into another task on Arduino using RIOT-OS.

 

Components Required

  1. Arduino Uno/Nano (I use Arduino Nano)
  2. LED (I use Red LED)
  3. 220Ω Resistor
  4. BreadBoard
  5. Jumper Wires
  6. Latest Release RIOT-OS SDK
  7. Any IDE which supports the C Makefile project.
  8. USB Cable
  9. I use Ubuntu 16.04 for developing the application. (RIOT-OS currently support on Linux/MAC-OS)

 

Hardware Connection of the LED with Arduino Nano

The complete connection diagram of the set-up is shown below. You just have to follow the figure to make the connections to see the LED blink.

Arduino Nano Circuit

 

Code Explanation

In this project, we use RIOT-OS to make a LED blink with an interval of 1sec from an independent thread.

Those libraries mentioned below are included at the beginning of the code.

//Include Libraries
#include <stdio.h>
#include "thread.h"        // Use for Create the Thread
#include "xtimer.h"        // Use for create the delay
#include "periph/gpio.h"    // Use for GPIO operations

 

Next, define a “#define” variable with the name of “EXTERNAL_LED”, for accessing the LED which is connected with the Arduino-Nano GPIO-A5. But in the RIOT OS, all module pins are mapped with their PORT & PIN. If the microcontroller’s PORTs are called by “PORT-A, PORT-B, PORT-C, …..” or “PA, PB, PC, …..” or “P0, P1, P2, …..”, then in RIOT OS, those PORTs are assigned with the number like “0, 1, 2, …..” and so on. So, when we need access to GPIO-A5, which is mapped with the atmega328p pin "PC5", then we need to call the GPIO_PIN(PORT, PIN)  function, where the port=0 and pin=5.

// Arduino-Nano On-Board LED connected with "A5" which mapped with atmega328p pin "PC5"
#define EXTERNAL_LED GPIO_PIN(2,5)

 

Now, create a stack for a task and implement the task function to do the Led blink process independently with the interval of 1sec.

#define DELAY_SEC        1    // 1sec
char task1_stack[THREAD_STACKSIZE_MAIN];
/**
 *
 */
void *Task1(void *arg)
{
    (void) arg;
    printf("Create Task1 Thread for Blink the External LED from the %s board.\n", RIOT_BOARD);
    gpio_init (EXTERNAL_LED, GPIO_OUT);
    while(1){
        puts("Task1\r\n");
        gpio_write (EXTERNAL_LED, 1);
        xtimer_sleep(DELAY_SEC);
        gpio_write (EXTERNAL_LED, 0);
        xtimer_sleep(DELAY_SEC);
    }
    return NULL;
}

 

In the main() loop, we create the thread using thread_create() function.

/**
 *
 */
int main(void)
{
#if 1
    printf("You are running RIOT on a(n) %s board.\n", RIOT_BOARD);
    printf("This board features a(n) %s MCU.\n", RIOT_MCU);
#endif
   thread_create(task1_stack,                         /* stack array pointer */
            sizeof(task1_stack),                            /* stack size */
            THREAD_PRIORITY_MAIN - 1,            /* thread priority */
            THREAD_CREATE_WOUT_YIELD | THREAD_CREATE_STACKTEST,        /* thread configuration flag, usually By default, the thread starts immediately */
            Task1,                                                 /* thread handler function */
            NULL,                                                 /* argument of thread_handler function */
            "task1"                                                /* thread_name */
            );            
    while(1){        
        puts("--> I'm Main \n");
        xtimer_sleep(2);
    }
    return 0;
}

 

Testing and Debugging RIOT Communication Process

Once the circuit and code are complete, we build and tested code with the help of these commands.

So, in this case, we use Ubuntu 20.04.2 LTS-64bit, and to create the development environment, we need to install the prerequisite before setting up the RIOT OS.

sudo apt-get update && sudo apt-get upgrade

Setting up RIOT-OS on Arduino

sudo apt-get install build-essential cppcheck git make gcc pkg-config autoconf automake libtool libusb-dev libusb-1.0-0-dev libhidapi-dev libftdi-dev g++-multilib gcc-multilib python3-serial curl doxygen graphviz pcregrep python python3 python3-flake8 unzip wget

RIOT-OS on Arduino

sudo add-apt-repository ppa:npalix/coccinelle
sudo apt-get install coccinelle

RIOT Communication Process

 

After installing all requirements, we can set up the RIOT-OS. For that, we need to create a workspace folder for download and git clone the latest release of RIOT-OS. To do this, follow these steps:

cd $HOME
mkdir riot_workspace
cd riot_workspace/
git clone git://github.com/RIOT-OS/RIOT.git
cd RIOT/
git checkout 2021.01

RIOT Communication Process

 

Now it’s time to set up the Hardware Toolchain, for Arduino.

sudo apt-get install gcc-avr avr-libc avrdude 

 

After setup, the RTOS-OS for Arduino, it’s time to compile the code. For Build/Compile the code, we need to call the make command along with the BOARD argument.

In our case, we used an Arduino-Nano Dev Board, so the board’s value is “arduino-nano”. If you use a different board, then please check the path [$HOME/riot_workspace/RIOT/boards] for the supported Arduino board’s list.

make BOARD=arduino-nano

Debugging RIOT Communication Process

 

For flashing the code into the Arduino Nano, we need to call the flash command.

make BOARD=arduino-nano PORT=/dev/ttyUSB0 flash

Debugging RIOT Communication Process

 

After flashing the code, we need to call the term command to check the log output on the screen.

make BOARD=arduino-nano PORT=/dev/ttyUSB0 term

RTOS Arduino

[Note: If any error occurs like “Permission denied: '/dev/ttyUSB0'” then call this command to resolve this “sudo chmod a+rw /dev/ttyUSB0”]

Arduino with LED

You will get more information about RIOT-OS and Arduino from their Tutorials and documentation. Link: Doc.RIOT-OS.org/arduino & RIOT-OS.github.io/riot-basics

Code

/*
 * Copyright (C) 2013 INRIA
 *
 * This file is subject to the terms and conditions of the GNU Lesser
 * General Public License v2.1. See the file LICENSE in the top level
 * directory for more details.
 */
/**
 * Project Name: arduino_riot_blink_led
 * Created on: 8-May-2021
 * Author: Noyel Seth (noyelseth@gmail.com)
 */
//Include Libraries
#include <stdio.h>
#include "thread.h"        // Use for Create the Thread
#include "xtimer.h"        // Use for create the delay
#include "periph/gpio.h"    // Use for GPIO operations
// Arduino-Nano On-Board LED connected with "A5" which mapped with atmega328p pin "PC5"
#define EXTERNAL_LED    GPIO_PIN(2,5)
#define DELAY_SEC        1    // 1sec
char task1_stack[THREAD_STACKSIZE_MAIN];
/**
 *
 */
void *Task1(void *arg)
{
    (void) arg;
    printf("Create Task1 Thread for Blink the External LED from the %s board.\n", RIOT_BOARD);
    gpio_init (EXTERNAL_LED, GPIO_OUT);
    while(1){
        puts("Task1\n");
        gpio_write (EXTERNAL_LED, 1);
        xtimer_sleep(DELAY_SEC);
        gpio_write (EXTERNAL_LED, 0);
        xtimer_sleep(DELAY_SEC);
    }
    return NULL;
}
/**
 *
 */
int main(void)
{    
#if 1
    printf("You are running RIOT on a(n) %s board.\n", RIOT_BOARD);
    printf("This board features a(n) %s MCU.\n", RIOT_MCU);
#endif
   thread_create(task1_stack,                         /* stack array pointer */
            sizeof(task1_stack),                            /* stack size */
            THREAD_PRIORITY_MAIN - 1,            /* thread priority */
            THREAD_CREATE_WOUT_YIELD | THREAD_CREATE_STACKTEST,        /* thread configuration flag, usually By default, the thread starts immediately */
            Task1,                                                 /* thread handler function */
            NULL,                                                 /* argument of thread_handler function */
            "task1"                                                /* thread_name */
            );            
    while(1){        
        puts("--> I'm Main \n");
        xtimer_sleep(1); // 1sec delay
    }
    return 0;
}

Video