Skip to content
Martine Lenders edited this page Oct 31, 2016 · 30 revisions

How to port RIOT to a new target

This page will give you an overview on how to proceed if you want port RIOT to a new platform. You will get an overview on the controller and board specific interfaces that need to be implemented and also some of the common pitfalls and misconceptions will be pointed out.

General requirements

Though RIOT supports C++ it needs to be guaranteed for portability that RIOT also builds with just a C compiler. Because of that it is required, that your port also fulfills this guarantee. This is why your port has to be provided in C (and if need be Assembly language) only.

Assumptions

This guide assumes that the port is done in a 'gcc' environment making use of the 'newlib'. In case some other (or none at all) C standard library is used, the part describing the system calls is to be adapted accordingly.

Things to do first:

  • know the name of your board and CPU (e.g. arduino-due/sam3x8e or msba2/lpc2387)
  • know your silicon (get all documentation available)
  • check you have the right toolchain
  • get header files for CPU register definitions (you don't want to define them by hand)
  • get the memory mapping, start addresses and sizes of flash and RAM memory
  • how to get your binary on the device
  • how to interact with the device (which /dev/tty* port)
  • test steps above by building - flashing - running - interacting with an example known to work

The RIOT architecture

Platform independent

  • RIOT/core
  • RIOT/sys
  • RIOT/drivers

Platform dependent

  • RIOT/cpu
    Containing controller specific code
  • RIOT/boards
    Containing board specific code, as pin definitions etc

The core interfaces

CPU interfaces that have to be implemented

The interfaces that have to be implemented in the CPU specific code are defined in RIOT/core/include/arch/. These cover functions that are essential for the kernel to work like interrupt handling and thread management but also provides interfaces for timers and a generic IO function and power mode management.

List of files:

atomic_arch.h
irq_arch.h
lpm_arch.h
reboot_arch.h
thread_arch.h

Implementing these interfaces is mandatory but not limited to these.

For ARM CortexM* MCUs the most interfaces are already implemented and only leave you with

lpm_arch.h

Documentation can be found here

Interfaces to the board

Board specific implementations and definition should lie in its own directory in RIOT/boards/$BOARDNAME. These should cover e.g. GPIO definitions, UART configurations and configurations providing CPU frequency and timer resolutions needed.
Mandatory however are:

  • Definitions of macros to control LEDs on the board:
#define LED0_ON        ....
#define LED0_OFF       ....
#define LED0_TOGGLE    ....
#define LED1_ON          ....
#define LED1_OFF         ....
#define LED1_TOGGLE      ....
  • Definition of the CPU frequency:
#define F_CPU   (24000000UL)
  • Implementation of board_init function which gets call immediately after startup code and before kernel initialization.
void board_init(void)
{
    ....
}

Also, for each board there has to be a Makefile.include providing information on the development environment. This covers the toolchain and its flags, the tool used to flash the binary and defines the CPU used for this board. Examples can be found in RIOT/boards/

Recommended file structure:

BOARDNAME                               CPUNAME
     |                                     |
     +->include                            +->include
     |     |                               |     |
     |     +---->board.h                   |     +---->cpu.h
     |     +---->periph_conf.h             |     +---->cpu-conf.h
     +->board.c                            |     +---->hwtimer_cpu.h
     +->Makefile                           |     +---->[cpu-specific-headers]
     +->Makefile.include                   +->cpu.c
                                           +->atomic_arch.c
                                           +->hwtimer_arch.c
                                           +->io_arch.c
                                           +->irq_arch.c
                                           +->lpm_arch.c
                                           +->reboot_arch.c
                                           +->thread_arch.c
                                           +->[syscalls.c]
                                           +->[startup.c|S]
                                           +->[linkerscript.ld]
                                           +->Makefile
                                           +->Makefile.include
                                           +->periph
                                                 |
                                                 +-->gpio.c
                                                 +-->timer.c
                                                 +-->uart.c
                                                 +-->...

Low-level Peripheral Driver Interface

Work is in progress to unify interfaces for drivers of peripheral hardware modules. This will increase portability and provides consistent usage of drivers. To follow the progress watch RIOT/drivers/include/periph/

Steps to take

  1. Create file and folder structure
  2. write/find linkerscript.ld for your CPU
  3. implement CPU initialisation (cpu.c)
  4. implement LED* macros in board.h
  5. implement UART driver
  6. implement timer driver and map to hwtimer (hwtimer will be replaced by xtimer with #3520)
  7. implement stack setup and context switching in thread_arch.c
  8. implement remaining CPU/core interfaces
  9. Congratulations, you have got a basic port
Clone this wiki locally