Creating your first RIOT project

Andreas "Paul" Pauli edited this page Aug 25, 2015 · 36 revisions
Clone this wiki locally

Please note that this HOWTO assumes you're working on a Linux PC.

Preparation

First, make sure you've installed the dependencies for building RIOT on your native platform:

  • RIOT only needs a c compiler that can handle gnu99, gcc and clang are known to work!
  • for x86-64 (64 bit) operation systems, you'll need at least glibc-dev and libgcc in the 32 bit edition
  • the bridge-utils package

Then, you'll need to clone the RIOT repository

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

Now you can create your own project directory in RIOT/examples/. In this tutorial, we'll do this by copying the default project folder, which can easily be used as a template to base your own project on.

cd RIOT/examples
cp -R default my_project
cd my_project

From this directory, you will compile everything you need, including the RIOT OS itself– one small make and everything is ready.

Let's take a look at the contents of our new my_project directory:

The Makefile

We'll only go through the lines that could be relevant to you.

APPLICATION = default

This is your project's name and also the name of the executable that will contain your application. In our case, you will want to change this line to

APPLICATION = my_project

Next, you will find the line

BOARD ?= native

This specifies the board for which you want to compile my_project. native means that my_project will be compiled to run on your desktop PC.

# This has to be the absolute path to the RIOT base directory:
RIOTBASE ?= $(CURDIR)/../..

Your project will be compiled to run as a normal program in your Linux operating system. To enable this, your compiler needs to know where the code for the OS lives. If you've set up the correct file structure, you won't need to adjust this path.

main.c

shell_init(&shell, NULL, UART0_BUFSIZE, shell_readc, shell_putchar);
shell_run(&shell);

This is the heart of your main.c file. If you run your compiled project later on, you'll notice that you will be greeted by an interactive shell. The two function calls above will start the shell. To extend the default commands with custom ones, you will have to pass a struct with name, description and pointers to your custom functions. my_project doesn't do this just yet, so let's add a little "Hello World".

Instead of NULL, we'll have to pass an array of shell_command_ts, each containing the command name, command description and the function that the command should call, as well as an all-null line to terminate the list like so:

int hello_world(int argc, char **argv) {
    /* Suppress compiler errors */
    (void)argc;
    (void)argv;
    printf("hello world!\n");
    return 0;
}

const shell_command_t shell_commands[] = {
    {"hello", "prints hello world", hello_world},
    { NULL, NULL, NULL }
};

int main(void)
{
    …

    shell_init(&shell, shell_commands, UART0_BUFSIZE, shell_readc, shell_putchar);
    shell_run(&shell);
}

Since you will most likely run the shell over the default UART of your board, RIOT provides two helpful functions to initialize the shell over this UART without having to implement the shell_readc and shell_putc yourself. You can use them by putting a USEMODULE += uart0 in your application Makefile and calling shell_init as follows:

shell_init(&shell, NULL, UART0_BUFSIZE, uart0_readc, uart0_putc);

setting up the network

If you want to do any networking, you'll need to create the virtual interfaces that your RIOT instances will use to communicate:

Your RIOT instances will be able to communicate with each other with the help of tap devices, one per RIOT. To enable this, a tapbridge connecting these tap devices has to be created using the tapsetup script.

2014.12: ../../cpu/native/tapsetup.sh create
Newer:   ../../dist/tools/tapsetup/tapsetup -c

This will set up a bridge for two tap devices to communicate over. This is enough for now, but if you want to use more than two devices later on, remember to append the number of devices you need to the command above.

After you are done with experimenting you can use the following line to delete the tap interfaces:

2014.12: ../../cpu/native/tapsetup.sh delete
Newer:   ../../dist/tools/tapsetup/tapsetup -d

running your first project

Now we are finally ready to roll. Make sure that you are in the my_project directory and type

make

Your compiler will read all the information it needs from the Makefile to build an executable file for you. When it is done compiling, you should see something like this:

text      data      bss     dec     hex filename
56879     602    109732  167213   28d2d /home/RIOT/examples/default/bin/native/default.elf

You can now run your project by executing

./bin/native/my_project.elf tap0

This will start a RIOT instance running my_project as an application in a thread on your Linux machine. This RIOT instance is connected to the tap device tap0. In another terminal window, you can start the next instance, connected to the next tap device:

./bin/native/my_project.elf tap1

etc. etc.
You should see the following output:

RIOT native interrupts/signals initialized.
RIOT native uart0 initialized.
LED_GREEN_OFF
LED_RED_ON
RIOT native board initialized.
RIOT native hardware initialization complete.

kernel_init(): This is RIOT!
Scheduler...[OK]
kernel_init(): jumping into first task...
UART0 thread started.
uart0_init() [OK]
native rtc initialized
Native LTC4150 initialized.
Welcome to RIOT!
>  

Type help for help. Play around a little. Press ctrl+c to exit. Try sending a message from one RIOT instance to the other with the txtsnd command (0 is a broadcast address). Check if the hello command you added earlier works as expected.
Happy Hacking!