kista sweden 26 27 march 2007 l.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
Porting Contiki Crash Course PowerPoint Presentation
Download Presentation
Porting Contiki Crash Course

Loading in 2 Seconds...

play fullscreen
1 / 54

Porting Contiki Crash Course - PowerPoint PPT Presentation


  • 4278 Views
  • Uploaded on

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

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

PowerPoint Slideshow about 'Porting Contiki Crash Course' - niveditha


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
porting contiki
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
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
Overview
  • 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 structure6
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 port8
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
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
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 module12
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
clock_init()
  • Initializes the clock module
    • Called by the boot-up code
    • Configures hardware timers, interrupts
clock time
clock_time()
  • 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
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) >

MAX_TICKS) {

etimer_request_poll();

LPM4_EXIT;

}

}

}

clock_time_t clock_time(void) {

return count; /* Return tick count */

}

clock delay
clock_delay()
  • 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
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
Workplan
  • 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
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 h21
contiki-conf.h
  • 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 drivers23
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
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
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
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
core/dev/simple-cc2420-rime.c

static void receiver(void) {

u8_t len;

rimebuf_clear();

len = simple_cc2420_read(rimebuf_dataptr(),

RIMEBUF_SIZE);

if(len > 0) {

rimebuf_set_datalen(len);

rime_input();

}

}

void simple_cc2420_rime_init(void) {

simple_cc2420_set_receiver(receiver);

}

void rime_driver_send(void) {

simple_cc2420_send(rimebuf_hdrptr(),

rimebuf_totlen());

}

the equivalent uip driver
The equivalent uIP driver

static void receiver(void) {

u8_t len;

len = simple_cc2420_read(uip_buf,

UIP_BUFSIZE);

if(len > 0) {

uip_len = len;

tcpip_input();

}

}

void simple_cc2420_rime_init(void) {

simple_cc2420_set_receiver(receiver);

}

int simple_cc2420_uip_send(void) {

simple_cc2420_send(&uip_buf[UIP_LLH_LEN],

uip_len);

}

overall comments
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
sensor drivers in contiki
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
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 … */

SENSORS_SENSOR(button_sensor, BUTTON_SENSOR,

init, irq, activate, deactivate, active,

value, configure, status);

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

#include "dev/button-sensor.h"

SENSORS(&button_sensor);

/* … */

int main(void) {

/* … */

process_start(&sensors_process, NULL);

button_sensor.activate();

/* … */

}

workplan34
Workplan
  • Copy platform/sky/dev/button-dev.c
  • Modify
the future of the sensor api
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
platform specific makefile
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
Example: platform/sky/Makefile.sky

# …

CONTIKI_TARGET_DIRS = . dev apps net

# …

CONTIKI_TARGET_SOURCEFILES +=

# …

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

# …

cpu specific makefile
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
Example: cpu/x86/Makefile.x86

CONTIKI_SOURCEFILES += mtarch.c elfloader-stub.c

### Compiler definitions

CC = gcc

LD = gcc

AS = as

OBJCOPY = objcopy

STRIP = strip

CFLAGSNO = -I. -I$(CONTIKI) -I$(CONTIKI)/core \

-I$(CONTIKI_CPU) \

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

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

-DWITH_UIP -DWITH_ASCII \

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

CFLAGS += $(CFLAGSNO) -O

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

# …

integrating into build system
Integrating into build system
  • Keep things simple
  • Copy entire platform/native directory
    • Modify
  • Copy entire cpu/x86 directory
    • Modify
elf loader43
ELF loader
  • Only needs porting for new CPUs
  • Designed for portability
  • Ported to MSP430, AVR, x86, ARM7
elf loader architecture specific interface
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
Workplan
  • 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
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 library48
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
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
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;

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

--t->sp;

/* Space for registers. */

t->sp -= 11;

}

static struct mtarch_thread *running;

void mtarch_exec(struct mtarch_thread *t) {

running = t;

sw();

running = NULL;

}

void mtarch_yield(void) {

sw();

}

example cpu msp430 mtarch c51
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
Potential problems with mtarch.c
  • C compiler specific
    • Different compilers behave differently
    • Different compiler versions behave differently
workplan53
Workplan
  • Copy cpu/msp430/mtarch.c
    • Modify
  • Google and see how existing threading libraries for your CPU push and pop the stack
conclusions
Conclusions
  • 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