Kristof Van Laerhoven, Embedded Systems, Uni Freiburg ...Introduction to Contiki Introduction to...
Transcript of Kristof Van Laerhoven, Embedded Systems, Uni Freiburg ...Introduction to Contiki Introduction to...
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