Upload
vunguyet
View
216
Download
2
Embed Size (px)
Citation preview
Introduction to Contiki
Introduction to ContikiKristof Van Laerhoven, Embedded Systems, Uni Freiburg [email protected]
Introduction to Contiki
Contiki
• Operating System ê memory-efficient: 2 kB RAM, 40 kB ROM typically* ê provides IP support (its uIPv6 stack is IPv6 Ready) ê supports multi-threading, Protothreads ê runs on many embedded platforms (AVR, MSP430, MSB430, ESB, Apple II, C64,
Atari Jaguar, Tandy CoCo, Casio PocketViewer, Sharp Wizard, PC 6001, and many many others) ê comes with advanced simulators ⇒ Perfect for wireless sensor networks
• Written in C, under BSD License • Used in industry:
ê freighter ships, satellites, oil drilling equipment, digital TV decoders
• Started by Adam Dunkels, SICS (Sweden), now thingsquare ê Developers from companies (SAP, Cisco, Atmel, NewAE, …) and
universities (SICS, TU Munich, …)2
Introduction to Contiki
Contiki: An operating system for Sensor Nodes
• Operating System’s main functions? ê File System? ê Virtual Memory? ê Resource Allocations?
• WSNs: Limited capabilities • ~MHz processing • 1-10K of RAM • 10-100K of ROM • kbps networking
• Energy-efficient management of node components • Processor, radio, sensors, actuators
3
TelosB: • MSP430 • 8MHz Microcontroller • 10KB SRAM • 48KB ROM • 802.15.4 Radio
example
Introduction to Contiki
Programming Models and Concurrency Support
• Sequential (no parallelism)
• Event-driven
• Multi-threaded
4
Poll sensor Process sensor data
Poll Radio Process radio packet
CPU
RadioMemory
Sensor
Handle sensor process
Handle radio process
Introduction to Contiki
Programming Models and Concurrency Support
• Event-driven model: • Code only runs within event handlers • On an event occurrence:
kernel invokes handler code • Event handler runs till completion:
explicit return;
5
Kernel
Event Handler 1
Event Handler 2
Event Handler 3
Introduction to Contiki
Programming Models and Concurrency Support
• Multi-threaded model: • Threads blocked, waiting for
events • Kernel unblocks thread when
event occurs • Thread runs until next blocking
statement (or preempted)
• Each thread requires own stack − RAM usage not negligible:
For a node with 2KB, 100 bytes is ~5%!
6
Kernel
Thread 1 Thread 2
Introduction to Contiki
Contiki’s Concurrency Support
• Contiki’s kernel is event-based • most programs run directly on top of
the kernel • Multi-threading implemented as a library • Threads only used if explicitly needed
(e.g., long computations) • Preemption possible
thus responsive • Protothreads
(coming up!)
7
Thread 1 Thread 2
Kernel
Event Handler 1
Event Handler 2
Event Handler 3
Introduction to Contiki
Contiki’s Protothreads
8
Radio on
t0
tawake
twait_max tsleep
Radio off
Communication left…
Example: A hypothetical sensor network MAC protocol (A. Dunkels)
Introduction to Contiki
Contiki’s Protothreads
9
Radio on
t0
tawake
twait_max tsleep
Radio off
Communication left…
Example: A hypothetical sensor network MAC protocol (A. Dunkels)
1. Turn radio on.2. Wait until t = t_0 + t_awake.3. If communication has not
completed, wait until it has completed or t = t_0 + t_awake + t_wait_max.
4. Turn the radio off. Wait until t = t_0 + t_awake + t_sleep.
5. Repeat from step 1.
Introduction to Contiki
Contiki’s Protothreads
10
Event-driven implementation:enum {ON, WAITING, OFF} state;
void eventhandler() { if(state == ON) { if(expired(timer)) { timer = t_sleep; if(!comm_complete()) { state = WAITING; wait_timer = t_wait_max; } else { radio_off(); state = OFF; } } } else if(state == WAITING) { if(comm_complete() || expired(wait_timer)) { state = OFF; radio_off(); } } else if(state == OFF) { if(expired(timer)) { radio_on(); state = ON; timer = t_awake; } } }
int protothread(struct pt *pt) { PT_BEGIN(pt); while(1) { radio_on(); timer = t_awake; PT_WAIT_UNTIL(pt, expired(timer)); timer = t_sleep; if(!comm_complete()) { wait_timer = t_wait_max; PT_WAIT_UNTIL(pt, comm_complete() || expired(wait_timer)); } radio off(); PT_WAIT_UNTIL(pt, expired(timer)); } PT_END(pt); }
Protothread implementation:
Introduction to Contiki 11
Contiki’s Protothreads: 6-line Implementation
struct pt { unsigned short lc; };
#define PT_INIT(pt) pt->lc = 0 #define PT_BEGIN(pt) switch(pt->lc) { case 0: #define PT_EXIT(pt) pt->lc = 0; return 2 #define PT_WAIT_UNTIL(pt, c) pt->lc = __LINE__; case __LINE__: \ if(!(c)) return 0 #define PT_END(pt) } pt->lc = 0; return 1
Protothreads implemented using the C switch statement
Introduction to Contiki 12
Contiki’s Protothreads: 6-line Implementation
int a_protothread(struct pt *pt) { PT_BEGIN(pt); PT_WAIT_UNTIL(pt, condition1); if(something) { PT_WAIT_UNTIL(pt, condition2); } PT_END(pt); }
int a_protothread(struct pt *pt) { switch(pt->lc) { case 0: pt->lc = 5; case 5: if(!condition1) return 0; if(something) { pt->lc = 10; case 10: if(!condition2) return 0; } } return 1; }
Line numbers
Introduction to Contiki
ContikiDocumentation
• Contiki’s homepage:http://www.contiki-os.org/
• Contiki’s Wiki:http://github.com/contiki-os/contiki/wiki
• Doxygen documentation:http://contiki.sourceforge.net/docs/
• SensTools:http://senstools.gforge.inria.fr/doku.php?id=os:contiki
13
Introduction to Contiki
ContikiProgramming a node
Write C code hello-world.cmake TARGET=sky
hello-world.sky
hello-world.ihex
msp430-objcopy
make TARGET=sky hello-world.upload
msp430-bsl
hello-world.ce
msp430-gccmake TARGET=sky hello-world.ce
send 130.83.0.94 hello-world.ce
14
Introduction to Contiki
ContikiQuick start: building from the command line
• Go to the examples directory of Contiki cd ~/contiki/examples/hello-world
• To build a monolithic system image for the native system: make TARGET=native• To build a monolithic system image for the Tmote Sky Mote: make TARGET=sky
• To build and upload the image to the Tmote Sky Mote: make TARGET=sky myproject.upload
• To remember the target platform: make TARGET=sky savetarget
Target=platform à platform: any directory under platform/
15
Introduction to Contiki
ContikiQuick start example: generic template
#include “contiki.h”
PROCESS(my_example_process, “my example process”); AUTOSTART_PROCESSES(&my_example_process); PROCESS_THREAD(my_example_process, ev, data) { PROCESS_BEGIN(); // initialize statements come here // while(1) { // perform tasks here // PROCESS_WAIT_EVENT(); } PROCESS_END(); }
16
Introduction to Contiki
ContikiQuick start example: hello_world.c
#include “contiki.h” #include <stdio.h>
PROCESS(hello_world_process, “hello world”); AUTOSTART_PROCESSES(&hello_world_process); PROCESS_THREAD(hello_world_process, ev, data) { PROCESS_BEGIN(); // initialize statements come here printf(“Hello world!\n\r”); while(1) { // perform tasks here // PROCESS_WAIT_EVENT(); } PROCESS_END(); }
17
Introduction to Contiki
ContikiQuick start example: hello_world_etimer.c
#include “contiki.h” #include <stdio.h>
PROCESS(hello_world_etimer_process, “hello world etimer”); AUTOSTART_PROCESSES(&hello_world_etimer_process); PROCESS_THREAD(hello_world_etimer_process, ev, data) { PROCESS_BEGIN(); static struct etimer et; static int i; while(1) { etimer_set(&et, CLOCK_SECOND*5); printf(“Hello world! %d \n\r”, i); i+=5; PROCESS_WAIT_EVENT_UNTIL( etimer_expired(&et) ); } PROCESS_END(); }
18
Introduction to Contiki
ContikiQuick start example: blink.c
#include “contiki.h” #include “dev/leds.h”
PROCESS(blink_process, “blink”); AUTOSTART_PROCESSES(&blink_process); PROCESS_THREAD(blink_process, ev, data) { PROCESS_BEGIN(); static struct etimer et; static int i; while(1) { if (i) leds_on(LEDS_ALL); else leds_off(LEDS_ALL); i=(i?0:1); etimer_set(&et, CLOCK_SECOND); PROCESS_WAIT_EVENT_UNTIL( etimer_expired(&et) ); } PROCESS_END(); }
19
Introduction to Contiki
ContikiQuick start example: button_blink.c
#include “contiki.h” #include “dev/leds.h” #include “dev/button-sensor.h”
PROCESS(button_blink_process, “button blink”); AUTOSTART_PROCESSES(&button_blink_process); PROCESS_THREAD(button_blink_process, ev, data) { PROCESS_BEGIN(); // initialize statements come here SENSORS_ACTIVATE(button_sensor); while(1) { leds_toggle(LEDS_BLUE); PROCESS_WAIT_EVENT_UNTIL( ev == sensors_event && data== &button_sensor ); } PROCESS_END(); }
20
Introduction to Contiki
ContikiQuick start example: brdcast.c
#include “contiki-net.h” void recv(struct broadcast_conn *c) {/* do something here */ ;}; struct broadcast_callbacks callbck={recv};
PROCESS(brdcast_process, “brdcast”); AUTOSTART_PROCESSES(&brdcast_process); PROCESS_THREAD(brdcast_process, ev, data) { PROCESS_BEGIN(); static struct etimer et; static struct broadcast_conn bc; broadcast_open(&bc, 128, &callbck); while(1) { etimer_set(&et, CLOCK_SECOND*5); PROCESS_WAIT_EVENT_UNTIL( etimer_expired(&et) ); packetbuf_copyfrom(“hi!”, 3); broadcast_send(&bc); } PROCESS_END(); }
21
Introduction to Contiki
ContikiProcesses and Protothreads• declaration: PROCESS(name, strname) • definition:
ê PROCESS_THREAD(name, ev, data): event, additional application data ê PROCESS_BEGIN(), PROCESS_END(): switch macro to contain app code ê Most processes are endless loops, interrupted via events (see next slide)
PROCESS_WAIT_EVENT(), PROCESS_WAIT_EVENT_UNTIL(condition), PROCESS_WAIT_UNTIL(condition), PROCESS_WAIT_WHILE(condition), PROCESS_PAUSE(), PROCESS_EXIT()
• more info: Protothreads [http://www.sics.se/~adam/pt/]
Take care: ý Local variables inside are lost (unless defined as static)
ý Switch statements (switch(c){case…;}) used in processes
22
Introduction to Contiki
Demonstration of Contiki and Cooja
23