You are on page 1of 30

RIOT-Lab

How to use RIOT in the IoT-Lab

Oliver "Oleg" Hahm

INRIA

November 7, 2014

O. Hahm (INRIA) RIOT-Lab November 7, 2014 1 / 29


Agenda

1 Start the RIOT

2 Using RIOT

3 Writing an Application for RIOT

4 Reading a Sensor

5 Join the RIOT

Slides are online available at http://riot-os.org/files/riotlab-tutorial.pdf.

O. Hahm (INRIA) RIOT-Lab November 7, 2014 2 / 29


Start the RIOT

Agenda

1 Start the RIOT

2 Using RIOT

3 Writing an Application for RIOT

4 Reading a Sensor

5 Join the RIOT

O. Hahm (INRIA) RIOT-Lab November 7, 2014 3 / 29


Start the RIOT Prepare your Toolchain

Recommended Build Environment

For the IoT-Lab nodes we recommend to use gcc-arm-embedded toolchain.


It can be found on https://launchpad.net/gcc-arm-embedded.
A quick guide to install the proper toolchain can be found in the RIOT wiki:
http://wiki.riot-os.org/Setup-a-Build-Environment
See also http://wiki.riot-os.org/Board%3A-IoT-LAB_M3 for particular information
on RIOT on the IoT-Lab nodes.
For the native port you have to install 32bit libraries.
See http://wiki.riot-os.org/Family%3A-native#toolchains

O. Hahm (INRIA) RIOT-Lab November 7, 2014 4 / 29


Start the RIOT GitHub

Obtain the Code

git clone https://github.com/RIOT-OS/RIOT.git


or download the zipped version:
https://github.com/RIOT-OS/RIOT/archive/master.zip

For this tutorial please clone also


https://github.com/RIOT-OS/applications

O. Hahm (INRIA) RIOT-Lab November 7, 2014 5 / 29


Start the RIOT Understanding RIOT

The Architecture

O. Hahm (INRIA) RIOT-Lab November 7, 2014 6 / 29


Start the RIOT Understanding RIOT

The Folder Structure

RIOT
boards
iot-lab_M3
core
cpu
cortex-m3_common
stm32f1
dist
doc
drivers
at86rf231
isl29020
examples
hello-world
pkg
libcoap
sys
net
network_layer
sixlowpan
tests

O. Hahm (INRIA) RIOT-Lab November 7, 2014 7 / 29


Start the RIOT Understanding RIOT

Best Practice for RIOT programming

Dos
Use static memory
Select the priorities carefully
Minimize stack usage with DEVELHELP and CREATE_STACKTEST
Use threads

Donts
Don’t use threads

Don’t use the POSIX wrapper if implementing something from scratch


Consult the Wiki: http://wiki.riot-os.org
...and the API documentation: http://doc.riot-os.org

O. Hahm (INRIA) RIOT-Lab November 7, 2014 8 / 29


Start the RIOT Understanding RIOT

Best Practice for RIOT programming

Dos
Use static memory
Select the priorities carefully
Minimize stack usage with DEVELHELP and CREATE_STACKTEST
Use threads
Increase flexibility, modularity, and robustness by using IPC.
Donts
Don’t use threads
Try not to use more than one thread per module.
Don’t create threads for one-time tasks.
Don’t use the POSIX wrapper if implementing something from scratch
Consult the Wiki: http://wiki.riot-os.org
...and the API documentation: http://doc.riot-os.org

O. Hahm (INRIA) RIOT-Lab November 7, 2014 8 / 29


Using RIOT

Agenda

1 Start the RIOT

2 Using RIOT

3 Writing an Application for RIOT

4 Reading a Sensor

5 Join the RIOT

O. Hahm (INRIA) RIOT-Lab November 7, 2014 9 / 29


Using RIOT Working with an Example

Compile and run on native


Let’s prepare a simple, virtual network:
[ RIOT ] # cpu / native / tapsetup . sh create 2
creating tapbr0 ...
creating tap0 ...
creating tap1 ...

Now we build and start the first virtual node.


[ RIOT ] # cd examples / default /
[ default ] # make all term
Building application default for native w / MCU native .
" make " -C / home / oleg / git / RIOT / cpu / native
...
RIOT native board initialized .
RIOT native hardware initi alizat ion complete .

kernel_init () : This is RIOT ! ( Version : 2014.05 -1314 - gace8a - zoidberg )


kernel_init () : jumping into first task ...
...
Welcome to RIOT !
> help
help
Command Description
---------------------------------------
reboot Reboot the node
id Gets or sets the node ’ s id .

O. Hahm (INRIA) RIOT-Lab November 7, 2014 10 / 29


Using RIOT Working with an Example

Setup the second Node

Ok, how about a second node?


Therefore, we specify the tap interface to use by (re-)using the PORT environment variable. We
can use any created tap interface from the previous step. (Default is tap0.) Once the node has
started, we configure its radio address.
[ default ] # PORT = tap1 make term
Welcome to RIOT !
> addr 23
[ transceiver ] trying to set address 23
[ transceiver ] got address : 23

We do the same on the first node and configure it to address 42.

O. Hahm (INRIA) RIOT-Lab November 7, 2014 11 / 29


Using RIOT Working with an Example

Connecting the two Nodes

It’s time to send our first packet (assuming that the first node is still running and configured to
address 42.):
> txtsnd 42 riotlab
[ transceiver ] Sending packet of length 8 to 42: riotlab
[ transceiver ] Packet sent : 60

On the first node we should see something like:


Got radio packet :
Length : 8
Src : 23
Dst : 42
LQI : 0
RSSI : 0
72 69 6 F 74 6 C 61 62 0

O. Hahm (INRIA) RIOT-Lab November 7, 2014 12 / 29


Using RIOT Working with an Example

Using the same example on the real hardware

Running the same example on a real node is very similar.


We use the environment variable BOARD to specify the target platform – and maybe PORT for the
serial port.
[ default ] # BOARD = iot - lab_M3 make all flash term
Building application default for iot - lab_M3 w / MCU stm32f1 .
" make " -C / home / oleg / git / RIOT / cpu / stm32f1
...
wrote 55296 bytes from file RIOT / examples / default / bin / iot - lab_M3 / default .
hex
in 2.454112 s (22.004 KiB / s )
...
shutdown command invoked
RIOT / dist / tools / pyterm / pyterm -p / dev / ttyUSB2 -b 500000
INFO # Connect to serial port / dev / ttyUSB2
Welcome to pyterm !
Type ’/ exit ’ to exit .
help
INFO # > help
INFO #
INFO # Command Description
INFO # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
INFO # reboot Reboot the node
INFO # id Gets or sets the node ’ s id .

O. Hahm (INRIA) RIOT-Lab November 7, 2014 13 / 29


Using RIOT Working with an Example

...and on the Testbed

Call just BOARD=iot-lab_M3 make all to build the binary (elf and hex are built).
Flash the nodes like usual (using the IoT-Lab web interface).
If you want use it somewhat more comfortable than using netcat, you can use the
same tool which is used for a locally connected node: pyterm.
You can find it in dist/tools/pyterm.
For example, run pyterm -ts m3-7:20000 on grenoble.iot-lab.info.

O. Hahm (INRIA) RIOT-Lab November 7, 2014 14 / 29


Using RIOT Using a Custom Application

The Shell in a Nutshell

For this step we will use sixlowapp application from


https://github.com/RIOT-OS/applications.
You can configure RIOT to provide you with some default system shell commands.
All available shell commands and some online help are shown by calling help:

> help
help
Command Description
---------------------------------------
nc RIOT netcat - arbitrary UDP connections and listens
ping Send an ICMPv6 echo request to another node
reboot Reboot the node
id Gets or sets the node ’ s id .
ps Prints information about running threads .
addr Gets or sets the address for the transceiver
eui64 Gets or sets the EUI -64 for the transceiver
chan Gets or sets the channel for the transceiver
txtsnd Sends a text message to a given node via the transceiver
pan Gets or sets the pan id for the transceiver
monitor Enables or disables address checking for the transceiver
ifconfig Configures a network interface

The selection of commands depends on the configuration of your application (and may vary a
little bit for different platforms).

O. Hahm (INRIA) RIOT-Lab November 7, 2014 15 / 29


Using RIOT Using a Custom Application

Let’s communicate

The sixlowapp application provides you with two custom (application defined) shell commands:
1 ping: The famous ICMP diagnosis tool.
2 nc: A very basic variation of netcat for arbitrary UDP connections.
After we flashed two nodes, we’ll have to find out their IPv6 addresses using ifconfig:
> ifconfig
INFO #
INFO # Iface 0 HWaddr : 0 xa86c Channel : 11 PAN ID : 0 x0001
INFO # EUI -64: 4d -5 e - fd -8 e -47 -3 c -5 f -80
INFO # Source address mode : short
INFO # Transceivers :
INFO # * at86rf231
INFO # inet6 addr : fe80 :: ff : fe00 : a86c /128 scope : local
INFO # inet6 addr : ff02 ::1: ff00 : a86c /128 scope : local [
multicast ]
INFO # inet6 addr : ff02 ::1/128 scope : local [ multicast ]
INFO #

Now we can try to ping the other node:


> ping fe80 :: ff : fe00 : f01e
INFO # ping fe80 :: ff : fe00 : f01e
INFO # Echo reply from fe80 :: ff : fe00 : f01e received , rtt : 0.0340 s

O. Hahm (INRIA) RIOT-Lab November 7, 2014 16 / 29


Using RIOT Using a Custom Application

Virtualize your Network

If you run this example in native, you can also monitor the traffic with Wireshark.
The dissector can be found in dist/tools/wireshark_dissector.
There’s a python framework to setup arbitrary topologies using defined loss-rates:
http://wiki.riot-os.org/Virtual-riot-network

O. Hahm (INRIA) RIOT-Lab November 7, 2014 17 / 29


Writing an Application for RIOT

Agenda

1 Start the RIOT

2 Using RIOT

3 Writing an Application for RIOT

4 Reading a Sensor

5 Join the RIOT

O. Hahm (INRIA) RIOT-Lab November 7, 2014 18 / 29


Writing an Application for RIOT Setting up the Application

The Makefile

To create your own RIOT example, you need only two files:
1 A C (or C++) file with a main function
2 A Makefile
You can find a template for a Makefile in dist/Makefile.
# Giving your application a name
APPLICATION = riotlab1
# Choosing a default platform
BOARD ?= native
# Specifying the RIOT folder
RIOTBASE ?= $ ( CURDIR ) /../../ RIOT
# Some helpful compiler flags
CFLAGS += - DSCHEDSTATIST I C S - DDEVELHELP
# Quieten the building process
QUIET ?= 1
# Modules to include :
USEMODULE += posix
USEMODULE += vtimer
# Let RIOT ’ s build system take care of the rest
include $ ( RIOTBASE ) / Makefile . include

O. Hahm (INRIA) RIOT-Lab November 7, 2014 19 / 29


Writing an Application for RIOT Setting up the Application

The main() Function

The only mandatory thing in your application is a main function with this prototype:
int main(void)

Standard C libraries can be used and parts of POSIX are ble through a wrapper within RIOT.
# include < stdio .h >
# include < unistd .h >

# define WAIT_USEC (1000 * 1000)

int main ( void )


{
puts ( " Hello ! " ) ;
usleep ( WAIT_USEC ) ;
puts ( " Good night ! " ) ;

return 0;
}

O. Hahm (INRIA) RIOT-Lab November 7, 2014 20 / 29


Writing an Application for RIOT Setting up the Application

Doing it the RIOT way

Instead of POSIX functions is usually advisable (and more efficient) to just use the native RIOT
functions:

# include < stdio .h >


# include " vtimer . h "

int main ( void )


{
puts ( " Let ’s throw a brick ! " ) ;
vtimer_usleep ( SEC_IN_USEC ) ;
puts ( " System terminated " ) ;

return 0;
}

O. Hahm (INRIA) RIOT-Lab November 7, 2014 21 / 29


Writing an Application for RIOT Some helpful Features

Starting the Shell

# include " posix_io . h "


# include " shell . h "
# include " shell_commands . h "
# include " board_uart0 . h "

...
const sh ell_command_t sh ell_c ommand s [] = {
{ " ping " , " Send an ICMPv6 echo request to another node " ,
s i x l o w a p p _s e n d _ p i n g } ,
{ NULL , NULL , NULL }
};
...

/* Open the UART0 for the shell */


posix_open ( uart0_handler_pid , 0) ;

/* initialize the shell */


shell_t shell ;
shell_init (& shell , shell_commands , UART0_BUFSIZE , uart0_readc , uart0_putc
);

/* start the shell loop */


shell_run (& shell ) ;

O. Hahm (INRIA) RIOT-Lab November 7, 2014 22 / 29


Writing an Application for RIOT Some helpful Features

...and 6LoWPAN

kernel_pid_t monitor_pid =
thread_create ( monitor_stack_buffer , sizeof ( m o n i t o r _ s t a c k _ b u f f e r ) ,
PRIORITY_MAIN - 2 , CREATE_STACKTEST , sixlowapp_monitor ,
NULL , " monitor " ) ;
i p v 6 _ r e g i s t e r _ p a c k e t _ h a n d l e r ( monitor_pid ) ;
...
while (1) {
msg_receive (& m ) ;
if ( m . type == I P V 6 _ P A C K E T _ R E C E I V E D ) {
ipv6_buf = ( ipv6_hdr_t *) m . content . ptr ;
if ( ipv6_buf - > nextheader == I P V 6 _ P R O T O _ N U M _ I C M P V 6 ) {
icmpv6_hdr_t * icmpv6_buf =
( icmpv6_hdr_t *) &(( uint8_t *) ipv6_buf ) [( IPV6_HDR_LEN ) ];
if ( icmpv6_buf - > type == I C M P V 6 _ T Y P E _ E C H O _ R E P L Y ) {
if ( _wa i t i n g _ f o r _ p o n g ) {
msg_t m ;
m . type = I C M P _ E C H O _ R E P L Y _ R C V D ;
_w a i t i n g _ f o r _ p o n g = 0;
msg_send (& m , _waiter_pid , false ) ;
}
}
}
}
}

O. Hahm (INRIA) RIOT-Lab November 7, 2014 23 / 29


Writing an Application for RIOT Up to the Transport Layer

Starting a UDP Server

sock = s o c ke t _b a se _ so c ke t ( PF_INET6 , SOCK_DGRAM , IPPROTO_UDP ) ;

memset (& sa , 0 , sizeof ( sa ) ) ;


sa . sin6_family = AF_INET ;
sa . sin6_port = HTONS ( s i x l o w a p p _ n e t c a t _ l i s t e n _ p o r t ) ;

if ( -1 == socket_base_b i n d ( sock , & sa , sizeof ( sa ) ) ) {


printf ( " Error bind failed !\ n " ) ;
s o c k e t_b as e_c los e ( sock ) ;
s i x l o w a p p _ n e t c a t _ l i s t e n _ p o r t = 0;
continue ;
}

printf ( " Listening for incoming UDP connection at port % " PRIu16 " \ n " ,
sixlowapp_netcat_listen_port );
int32_t recsize = s o c k e t _ b a s e _ r e c v f r o m ( sock , ( void *) buffer_main ,
UDP_BUFFER_SIZE , 0 , & sa , & fromlen ) ;

if ( recsize < 0) {
printf ( " ERROR : recsize < 0!\ n " ) ;
}

printf ( " UDP packet received , payload : % s \ n " , buffer_main ) ;

so c k e t _ b as e_c los e ( sock ) ;

O. Hahm (INRIA) RIOT-Lab November 7, 2014 24 / 29


Reading a Sensor

Agenda

1 Start the RIOT

2 Using RIOT

3 Writing an Application for RIOT

4 Reading a Sensor

5 Join the RIOT

O. Hahm (INRIA) RIOT-Lab November 7, 2014 25 / 29


Reading a Sensor Get your Hands dirty

Now it’s up to you

Your task is now to extend the sixlowapp example.


Check the documentation for the sensor API, e.g. for the light sensor:
http://doc.riot-os.org/group__driver__isl29020.html
Initialize all four sensors in the beginning of the application.
Extend the netcat command to send optionally measured sensor data.
Print the measurements on the receiving side.

O. Hahm (INRIA) RIOT-Lab November 7, 2014 26 / 29


Join the RIOT

Agenda

1 Start the RIOT

2 Using RIOT

3 Writing an Application for RIOT

4 Reading a Sensor

5 Join the RIOT

O. Hahm (INRIA) RIOT-Lab November 7, 2014 27 / 29


Join the RIOT Getting Support

Where to get help

Mailing Lists
devel@riot-os.org
users@riot-os.org
IRC on irc.freenode.org, #riot-os
Regular video conferencing meetings

O. Hahm (INRIA) RIOT-Lab November 7, 2014 28 / 29


The Last Slide™ Q&A

Thank you!
Any questions?

O. Hahm (INRIA) RIOT-Lab November 7, 2014 29 / 29

You might also like