Porting Contiki Crash Course - PowerPoint PPT Presentation

Kista sweden 26 27 march 2007 l.jpg
1 / 54

Kista, Sweden 26-27 March 2007 Porting Contiki Crash Course Porting Contiki Contiki is designed to be easy to port Porting the base system is instant No architecture-dependent code Stuff that needs porting: The clock module I/O (network drivers, serial driver, sensors, …) ELF loader

I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.

Download Presentation

Porting Contiki Crash Course

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript

Kista sweden 26 27 march 2007 l.jpg

Kista, Sweden

26-27 March 2007

Porting ContikiCrash Course

Porting contiki l.jpg

Porting Contiki

  • Contiki is designed to be easy to port

  • Porting the base system is instant

    • No architecture-dependent code

  • Stuff that needs porting:

    • The clock module

    • I/O (network drivers, serial driver, sensors, …)

    • ELF loader

    • Multi-threading

    • Possible C compiler-quirks

    • Makefiles

This presentation l.jpg

This presentation

  • I will present the ideal Contiki port

  • Not all ports look exacly like this

  • Ports under development typically do not look like this

  • However, we should aim for it

  • Having this structure in mind during porting makes things easier

Overview l.jpg


  • Directory structure

  • The native port

  • The clock module

  • contiki-conf.h

  • Network drivers

  • Sensors

  • Integrating into the Contiki build system

  • ELF loader

  • Multi-threading

Directory structure l.jpg

Directory structure

Directory structure6 l.jpg

Directory structure

  • Two directories are of importance

    • cpu/

    • platform/

  • cpu/ contains code common to all platforms with the same microcontroller

  • platform/ contains platform specific code

  • Example: platform/sky, platform/esb, and cpu/msp430

The native port l.jpg

The native port

The native port8 l.jpg

The native port

  • The simplest port; can be used as a template

  • ls platform/native

    • Makefile.native

    • clock.c

    • contiki-conf.h

    • contiki-main.c

    • dev/

The native port contd l.jpg

The native port (contd)

  • Makefile.native

    • For integration into the Contiki build system, must have the name Makefile.(platform name)

  • clock.c

    • Architecture-specific clock code

  • contiki-conf.h

    • Configuration options

  • contiki-main.c

    • main(): boot-up code and the main loop

  • dev/

    • Device drivers

Other subdirectories used in platform subdirs l.jpg

Other subdirectories used in platform/ subdirs

  • apps/

    • Platform-specific applications

    • Example: platform/sky/apps/burn-nodeid.c

  • net/

    • Platform-specific network code/drivers

    • Example: platform/esb/net/tr1001-rime.c

The clock module l.jpg

The clock module

The clock module12 l.jpg

The clock module

  • The clock module is hardware-specific

    • Generic header file in core/sys/clock.h

  • clock.c can be either in platform/ or in cpu/

    • Example: platform/ for native, cpu/ for MSP430 ports

  • Three functions

    • clock_init()

    • clock_time()

    • clock_delay()

Clock init l.jpg


  • Initializes the clock module

    • Called by the boot-up code

    • Configures hardware timers, interrupts

Clock time l.jpg


  • Should return an increasing tick counter

  • The tick typically is increased in an interrupt handler

    • Implemented in clock.c

  • Interrupt handler must wake up CPU if there are etimers pending

    • etimer_request_poll()

Example cpu msp430 clock c l.jpg

Example: cpu/msp430/clock.c

static volatile clock_time_t count = 0;

interrupt(TIMERA1_VECTOR) timera1 (void) {

if(TAIV == 2) {

TACCR1 += INTERVAL; /* Set next hw interrupt */

++count; /* Increase tick counter */

/* If there are pending etimers, poll etimer process,

wake up CPU. */

if(etimer_pending() &&

(etimer_next_expiration_time() - count - 1) >







clock_time_t clock_time(void) {

return count; /* Return tick count */


Clock delay l.jpg


  • Delay for a platform-specific amount of time

  • This function is only used by device drivers and other low-level code

Example cpu msp430 clock c17 l.jpg

Example: cpu/msp430/clock.c


* Delay the CPU for a multiple

* of 2.83 us.


void clock_delay(unsigned int i) {

asm("add #-1, r15");

asm("jnz $-2");


Workplan l.jpg


  • Copy exiting clock.c (cpu/msp430/dev/clock.c)

    • Modify

  • Look at application notes for CPU to see how timer interrupt works

The future of the clock module l.jpg

The future of the clock module

  • Periodic ticking is inefficient

  • The clock module might be replaced by the rtimer module in the future

    • The rtimer code will have to be backed by code similar to the current clock.c code

Contiki conf h l.jpg


Contiki conf h21 l.jpg


  • Found in platform/(name of platform)

  • Example: platform/native/contiki-conf.h

  • Contains platform-specific configuration options

    • C compiler configuration

    • C types

    • uIP configuration

    • Clock configuration: clock_time_t, CLOCK_CONF_SECOND

  • Sometimes used as a kitchen sink

  • Workplan: copy platform/native/contiki-conf.h

Network device drivers l.jpg

Network device drivers

Network device drivers23 l.jpg

Network device drivers

  • Two operations:

    • Send out packet

    • Receive packets

  • Driver design:

    • Split code into three files

      • Hardware-specific code

      • Interface between uIP and hw specific code

      • Interface between Rime and hw specific code

Example core dev simple cc2420 c l.jpg

Example: core/dev/simple-cc2420.c

/* Initialize driver */

void simple_cc2420_init(void);

/* Setup a function to be called when a packet has arrived */

void simple_cc2420_set_receiver(void (* recv)(void));

/* Read arrived packet into a buffer */

int simple_cc2420_read(u8_t *buf, u8_t bufsize);

/* Send a packet from a buffer */

int simple_cc2420_send(const u8_t *data, u8_t len);

Example core dev simple cc2420 c25 l.jpg

Example: core/dev/simple-cc2420.c

  • Hardware driver does not add any headers

  • Only handles reception/sending of raw bytes

  • Any 802.15.4 headers (optional) could be handled by upper layer module

    • Add function for switching on CC2420 address decoding

Example core dev simple cc2420 rime c l.jpg

Example: core/dev/simple-cc2420-rime.c

  • Uses the hardware-specific code in simple-cc2420.c to send and receive packets

  • No hardware-specific code outside of lowest level driver

Core dev simple cc2420 rime c l.jpg


static void receiver(void) {

u8_t len;


len = simple_cc2420_read(rimebuf_dataptr(),


if(len > 0) {





void simple_cc2420_rime_init(void) {



void rime_driver_send(void) {




The equivalent uip driver l.jpg

The equivalent uIP driver

static void receiver(void) {

u8_t len;

len = simple_cc2420_read(uip_buf,


if(len > 0) {

uip_len = len;




void simple_cc2420_rime_init(void) {



int simple_cc2420_uip_send(void) {




Overall comments l.jpg

Overall comments

  • Keep things simple

  • Keep low-level code in a seprate file

  • As little low-level code as possible

  • Create simple interfaces between the low-level code and Rime/uIP driver

  • Workplan:

    • Copy existing driver (simple-cc2420, tr1001)

    • Modify

Sensors l.jpg


Sensor drivers in contiki l.jpg

Sensor drivers in Contiki

  • When a sensor changes an event is broadcast to all processes

    • Button press, PIR movement detected, …

  • Generic code for sending events in core/lib/sensors.c

  • Low-level code in separate file

Example platform sky dev button sensor c l.jpg

Example: platform/sky/dev/button-sensor.c

HWCONF_PIN(BUTTON, 2, 7); /* Button is on port 2, pin 7 */

HWCONF_IRQ(BUTTON, 2, 7); /* Connect this to an interrupt */

static void init(void) {

timer_set(&debouncetimer, 0);

BUTTON_IRQ_EDGE_SELECTD(); /* Trigger interrupt on down flank */

BUTTON_SELECT(); /* Select this pin */

BUTTON_MAKE_INPUT(); /* Make button pin an input pin */


static int irq(void) {

if(BUTTON_CHECK_IRQ()) { /* Is this why we got an interrupt? */

if(timer_expired(&debouncetimer)) {

timer_set(&debouncetimer, CLOCK_SECOND / 4);

sensors_changed(&button_sensor); /* Send event to all processes */

return 1;



return 0;


/* … more stuff here … */


init, irq, activate, deactivate, active,

value, configure, status);

In platform sky contiki sky main c l.jpg

In platform/sky/contiki-sky-main.c

#include "dev/button-sensor.h"


/* … */

int main(void) {

/* … */

process_start(&sensors_process, NULL);


/* … */


Workplan34 l.jpg


  • Copy platform/sky/dev/button-dev.c

  • Modify

The future of the sensor api l.jpg

The future of the sensor API

  • Works well for digital sensors

  • Does not work that well for analog sensors

  • May need to be updated in the future

Integrating into the contiki build system l.jpg

Integrating into the Contiki build system

Platform specific makefile l.jpg

Platform-specific Makefile

  • platform/name/Makefile.name

  • Included by top-level Makefile.include

    • Never invoked directly

    • Not supposed to run “make” in platform directory

  • Makefile specifies source files, directories, …

  • Usually includes CPU-specific Makefile

    • cpu/name/Makefile.name

Example platform sky makefile sky l.jpg

Example: platform/sky/Makefile.sky

# …

CONTIKI_TARGET_DIRS = . dev apps net

# …


# …

include $(CONTIKI)/cpu/msp430/Makefile.msp430

# …

Cpu specific makefile l.jpg

CPU-specific Makefile

  • cpu/name/Makefile.name

  • Definitions for CPU-specific source files

  • Definitions for rules for C compiler

    • CFLAGS, CC

  • Definition of vpath

    • Where (GNU) make looks for .c files

Example cpu x86 makefile x86 l.jpg

Example: cpu/x86/Makefile.x86

CONTIKI_SOURCEFILES += mtarch.c elfloader-stub.c

### Compiler definitions

CC = gcc

LD = gcc

AS = as

OBJCOPY = objcopy

STRIP = strip



-I$(CONTIKI)/platform/$(TARGET) \

${addprefix -I,$(APPDIRS)} $(APP_INCLUDES) \


-Wall -g -I. -I/usr/local/include


LDFLAGS = -Wl,-Map=contiki.map,-export-dynamic

# …

Integrating into build system l.jpg

Integrating into build system

  • Keep things simple

  • Copy entire platform/native directory

    • Modify

  • Copy entire cpu/x86 directory

    • Modify

Elf loader l.jpg

ELF loader

Elf loader43 l.jpg

ELF loader

  • Only needs porting for new CPUs

  • Designed for portability

  • Ported to MSP430, AVR, x86, ARM7

Elf loader architecture specific interface l.jpg

ELF loader architecture-specific interface

/* Allocate RAM for data and bss segments */

void *elfloader_arch_allocate_ram(int size);

/* Allocate ROM for text segment (code) */

void *elfloader_arch_allocate_rom(int size);

/* Relocate one relocation entry. */

void elfloader_arch_relocate(int fd,

unsigned int sectionoffset,

char *sectionaddr,

struct elf32_rela *rela,

char *addr);

/* Write code to previously allocated ROM */

void elfloader_arch_write_rom(int fd,

unsigned short textoff,

unsigned int size,

char *mem);

Workplan45 l.jpg


  • Copy core/loader/elfloader-stub.c

    • Modify

  • Look at core/loader/elfloader-msp430.c, elfloader-avr.c, elfloader-x86.c

  • Need knowledge of the ELF format for the CPU

The future of the elf loader l.jpg

The future of the ELF loader

  • The current interface cannot nicely hold multiple allocations

    • But Contiki itself supports it

  • API change will be needed

  • Current ELF loader does not properly process relocation entries

    • New ELF loader code on the way

Multi threading library l.jpg

Multi-threading library

Multi threading library48 l.jpg

Multi-threading library

  • Must be ported to new CPUs

  • But: not used very often

    • Porting often not required

  • Split into two parts (Contiki-style)

    • mt.c

    • mtarch.c

Mtarch api l.jpg

mtarch API

/* Thread structure */

struct mtarch_thread;

/* Initialize the architecture-specific code */

void mtarch_init(void);

/* Remove & clean up */

void mtarch_remove(void);

/* “Start” a thread (setup its stack) */

void mtarch_start(struct mtarch_thread *thread,

void (* function)(void *data),

void *data);

/* Switch to the specified thread */

void mtarch_exec(struct mtarch_thread *thread);

/* Yield the current thread */

void mtarch_yield(void);

/* Stop preemption */

void mtarch_pstop(void);

/* Start preemption */

void mtarch_pstart(void);

Example cpu msp430 mtarch c l.jpg

Example: cpu/msp430/mtarch.c

void mtarch_start(struct mtarch_thread *t,

void (*function)(void *), void *data) {

t->sp = &t->stack[MTARCH_STACKSIZE - 1];

*t->sp = (unsigned short)mt_exit;


*t->sp = (unsigned short)function;


/* Space for registers. */

t->sp -= 11;


static struct mtarch_thread *running;

void mtarch_exec(struct mtarch_thread *t) {

running = t;


running = NULL;


void mtarch_yield(void) {



Example cpu msp430 mtarch c51 l.jpg

Example: cpu/msp430/mtarch.c

static void sw(void) {

sptmp = running->sp;

__asm__("push r4"); /* Push all registers on the current stack */

__asm__("push r5");

__asm__("push r6");

__asm__("push r7");

__asm__("push r8");

__asm__("push r9");

__asm__("push r10");

__asm__("push r11");

__asm__("push r12");

__asm__("push r13");

__asm__("push r14");

__asm__("push r15");

__asm__("mov.w r1,%0" : "=r" (running->sp)); /* Switch stack pointer to new stack */

__asm__("mov.w %0,r1" : : "m" (sptmp));

__asm__("pop r15"); /* Pop all registers from the new stack */

__asm__("pop r14");

__asm__("pop r13");

__asm__("pop r12");

__asm__("pop r11");

__asm__("pop r10");

__asm__("pop r9");

__asm__("pop r8");

__asm__("pop r7");

__asm__("pop r6");

__asm__("pop r5");

__asm__("pop r4");


Potential problems with mtarch c l.jpg

Potential problems with mtarch.c

  • C compiler specific

    • Different compilers behave differently

    • Different compiler versions behave differently

Workplan53 l.jpg


  • Copy cpu/msp430/mtarch.c

    • Modify

  • Google and see how existing threading libraries for your CPU push and pop the stack

Conclusions l.jpg


  • Contiki designed to be portable

  • No architecture-specific code out in Contiki base

    • Two directories: cpu/ and platform/

  • To begin porting, copy & modify the platform/native code

  • Login