Programming in nesC (and TOSSIM)

Professor Jack Stankovic Department of Computer Science University of Virginia

Questions

• How do you program these wireless sensor devices? nesC • How do you debug your code on a PC? TOSSIM – Lab 3 • How do you download your code? Lab 0 • How do you debug the system? Message Center – Lab 2

1 Questions

• What else do you need to know? – TinyOS

• Why nesC? – Most widely used – Example of systems language for embedded systems

Helpful Materials

• Labs and Lab materials – see class web site • Handouts – read • Read: – The nesC Language: A Holistic Approach to Networked Embedded Systems, . Gay, et. al., PLDI, 2003 (sections 1-4 inclusive) • Google to find TinyOS tutorial

2 Outline

• Overview • Main Elements and Examples • Task Model and Concurrency • More Coding Details • Examples • Message Center (Lab 2; intro in class) • TOSSIM • Summary

TinyOS and nesC Paradigm

• Component-based • TinyOS, libraries, applications written in nesC • Intended for embedded systems and WSN • -like syntax (new keywords) – Call, signal, task, post, async, … • TinyOS concurrency model (tasks and events)

3 TinyOS and nesC Paradigm

• No dynamic memory • nesC bi-directional interface is an excellent fit for event driven systems • Race conditions checked at compile time

Big Picture • Write components; use components written by others – Will need new keywords/framework for defining components • Glue components together – Called wiring – Configuration file • Bi-directional interfaces • Concurrency/Execution Model – Tasks – Event handlers • Data races checked at compile time

4 Big Picture

• Use development environment on PC and download to target system (motes) • Simulator available before downloading – Debug on PC • Message Center tool – inject/read msgs – Debug on actual platform

Big Picture

• nesC application – 1 or more components – Wire them together – Must have a MAIN component

• Modules (implement your code) • Configurations (the wiring) • Interfaces

5 Big Picture

Provides Interfaces Interface:

Commands (how to use the interface) Component Events (user of interface must implement)

Uses Interfaces

Application Example

application sensing application

routing Routing Layer

messaging Messaging Layer

packet Radio Packet UART Packet

Radio byte UART byte byte photo Temp SW

bit RFM clocks ADC i2c HW

6 Example (cont.)

• You might only write the application component • Perhaps all other components are from a library

• Applies to TinyOS – 108 code modules in TinyOS – Examples of Applications • Surge 31 modules – 27 of them OS • TinyDB 65 modules – 38 of them OS

Example (cont.)

• Note: HW components – Veneer of SW exists for each HW component • Hides interrupt vector set up • Abstracts details of HW init and use (more details later)

7 Interfaces

Interface:

Declare commands (implementor of this interface must implement these commands)

Declare events (User of this interface, i.e., a components that invokes commands, must implement these events – call back functions)

Interfaces have global scope!

Interface Example

Timer.nc * filename for a bidirectional interface

interface Timer {

command result_t start (char type uint32_t interval); command result_t stop(); event result_t fired(); }

• Interface is a type • Many instances of the interface may exist • A command or event in an interface is named i.f (Ex: Timer.start, Timer.fired)

8 Split Phase

• Because of the execution model, code should exist in small execution pieces • Similar to asynchronous method calls

• Separate initiation of method call from the return of the call – Call to split-phase operation returns immediately – When work actually finishes the caller is notified via another method call

Specify Split-Phase

• Declare Interface with both – Command – Event

(e.g., Timer.nc of previous (2) slides back)

• Use to avoid long delay operations – (since a non-preemptive model is used)

9 Components and Interfaces

Provides interfaces (multiple interfaces) (bi-directional)

Component

Uses Interfaces (multiple interfaces) (bidirectional)

Component Example -Modules

• Implements a component’s specification with C code:

module MyCompM { module MyCompM { provides interface X; provides { provides interface Y; interface X; uses interface Z; interface Y; } } implementation { uses interface Z; specification …// C code } } implementation { …// C code MyCompM.nc } MyCompM.nc

The implementation part implements the provides interfaces and if the uses interface has an event then this module must also implement an event handler.

10 Interfaces

• Used for grouping functionality, like: – split-phase operation (send, sendDone) – standard control interface (init, start, stop)

• Describe bidirectional interaction: TimerM

interface Clock { command result_t setRate (char interval, char scale); event result_t fired (); } Clock.nc

ClockC • Interface provider must implement commands • Interface user must implement events

Note: This is how you declare a split-phase operation, i.e., Command and Event declared.

Interfaces

• Examples of interfaces:

interface StdControl { interface Timer { command result_t init (); command result_t start (char type, command result_t start (); uint32_t interval); command result_t stop (); command result_t stop (); } event result_t fired (); StdControl.nc } Timer.nc interface SendMsg { interface ReceiveMsg { command result_t send (uint16_t addr, event TOS_MsgPtr receive (TOS_MsgPtr m); uint8_t len, } TOS_MsgPtr p); event result_t sendDone (); } SendMsg.nc ReceiveMsg.nc

11 Interfaces

• Not all Interfaces are split-phase

• E.g., StdControl and ReceiveMsg are not interface StdControl { interface ReceiveMsg { command result_t init (); event TOS_MsgPtr receive (TOS_MsgPtr command result_t start (); m); command result_t stop (); } }

Parameterized Interfaces

• Note [ …] : This is not a parameter list (can have that too).

module GenericCommM { provides interface SendMsg [uint8_t id]; provides interface ReceiveMsg [uint8_t id]; … } implementation {… } GenericCommM.nc

12 Parameterized Interfaces ID = 1 ID = 2 ID = 3

Uses SendMsg Uses SendMsg Uses SendMsg Interface Interface Interface

Send Msg 1 Send Msg 2 Send Msg 3

SendMsg Interface Provided by some Component Must know who to respond to

All boxes are components

Parameterized Interfaces ID = 1 ID = 2 ID = 3

Uses Timer Uses Timer Uses Timer Interface Interface Interface

Set timer for 200 ms Set timer for 150 ms Set timer for 75 ms

Timer Interface Provided by some Component Must know who to respond to

All boxes are components

13 Components/Interfaces Commands Events

Interface1 command a command b Wire all Provides components event c that issue Interface2 commands command d a, b or d to this component

Component

Configurations

• Wire components together

• Connected elements must be compatible (interface-interface , command-command, event-event)

• 3 wiring statements in nesC:

– endpoint 1 = endpoint 2 – endpoint 1 -> endpoint 2 – endpoint 1 <- endpoint 2 (equivalent: endpoint 2 -> endpoint 1)

14 Configuration - Example

• Blink application

• Wiring Example BlinkC Main configuration BlinkC { }

implementation { components Main, BlinkM, ClockC, LedsC;

Main.StdControl->BlinkM.StdControl; BlinkM BlinkM.Clock->ClockC; BlinkM.Leds->LedsC; } BlinkC.nc ClockC LedsC ClockC is really ClockC.Clock LedsC is really LedsC.Leds

Configuration

Main.StdControl -> BlinkM.StdControl

Component Interface Component Interface Implementation USES PROVIDES

15 Equals Sign

But A does not A: provides I implement I but uses what is provided by B

Hence A = B

Often used for hierarchical B: provides I Configuration files – see Example later

Implementation

• fn.nc – For all source files (interfaces, modules and configurations)

16 Concurrency Model

• Underlying execution model (TinyOS) – Tasks and Events – Split phase operation

Tasks

• Tasks – Deferred computation – Non-preemptable by other tasks – Scheduled FCFS from task queue – When no tasks – CPU goes to sleep – Returns void

– Declare tasks with task keyword – Schedule tasks with post keyword

17 Task

task void processData() {

int16_t i, sum=0; atomic { for (i=0; i< size; i++) sum += (rdata[i] >> 7); } display(sum >> log2size); }

Tasks FCFS Queue alert

task void abc() { . . Next task post alert(); Current task . . TinyOS }

Non-preemptive

18 Events

• Events – Execution of an interrupt handler – Runs to completion – Can preempt tasks and can be preempted by other events

– Declare events with event keyword (as part of interfaces) – Notify events with signal keyword

Events FCFS Queue alert

P R Upcalls Event: packet here E E Event: byte M Here Can post Signal packet P Tasks/keep T Event: Bits Handlers short Signal Byte

HW interrupt/ Asynchronous radio

19 Commands and Events

• For those commands and events that can be executed by interrupt handlers – explicitly mark as async

async event result_t ADC.ready (uint16_t data) { putdata(data); post processData(); return SUCCESS; }

Events

• Signify completion of a split-phase operation – Example: packet send via send command ; then communication component will signal sendDone event when transmission is complete • Events from environment – Message reception – Clock firing

20 Race Conditions

• Solutions – Access shared data exclusively within tasks – Have all accesses within atomic statements

X Non-preemptive Task queue x Shared data

Event Handlers

Directions of Calls

Event Call – use keyword signal

Component

Command Call – use keyword call

21 Big Picture Components (modules) Main async command … post task Task call commands … signal events post tasks … call commands command signal events … … Task … Components (modules) async command … HW Interrupts command Invoke commands … and events async event …

Components - nesC X = Y Config • The nesC model: notation – Interfaces: Application Component • uses D

• provides Component – Components: A • modules Component • configurations C

• Application:= Component graph of B

components Component F

Component configuration E configuration

22 Modules

• Call commands and Signal events

module TimerM { provides interface StdControl; provides interface Timer[uint8_t id]; uses interface Clock;… }

implementation { command result_t StdControl.stop() { call Clock.setRate(TOS_I1PS, TOS_S1PS); … signal xyz.fired(); } TimerM.nc … }

Modules • Task: a task is an independent locus of control defined by a function of storage class task returning void and with no arguments • Posting tasks: keyword post

module BlinkM {… } implementation {… task void processing () { if(state) call Leds.redOn(); else call Leds.redOff(); }

event result_t Timer.fired () { state = !state; post processing(); return SUCCESS; BlinkM.nc }… }

23 Atomic Statements

bool busy; // gobal .… bool available; nesC forbids calling …. commands or signaling events in an atomic { atomic section

available = !busy; busy = TRUE; } ….

atomic busy = false;

Interrupt Handling

• Keep interrupt handlers short • May post tasks • Examples – Increment counter in atomic statement and then done – Call LED to set light red; done – Post task; done – Call -> Call -> Call -> Call then return, …; bad idea

24 Matching SW and HW

• Thin veneer of code for HW devices – See next slide • Assign symbolic names for signals/pins – Photo_PWR (to turn on power to photo sensor) • Abstract away interrupt vectors

HW Interrupt defined Handler Interrupt Vectors

Matching SW and HW

• Example LED – Red LED on/off – Green LED on/off – Yellow LED on/off – Toggle – Turn on/off power

– LED has no interrupts

– User has it easy; just know interface

25 Components of Interest

• LED, Clock, UART, ADC, RFM, I2C (hardware abstraction components)

• Other components: Chirp, counter, blink, AM_Beacon, AM_Echo, …

• Find interfaces in – tos/interfaces/

Application Example (revisited)

application sensing application

routing Routing Layer

messaging Messaging Layer

packet Radio Packet UART Packet

Radio byte UART byte byte photo Temp SW

bit RFM clocks ADC i2c HW

26 ADC

• init() • get-data()

• Fires separate event for each data port

Programming Environment

• cygwin/Win2000 or gcc/Linux • Wireless download of code also available

mote

Code programming mote-PC download board comms

27 Summary/Principles/Concepts

• Single application • Tasks and Events • Wrap HW devices in – Concurrency thin veneer of SW • Split-phase – Hide details – Asynchronous • Components + Glue • Embedded systems • Use only components language required • No dynamic memory – Even for OS • Race conditions • Interfaces – Atomic sections • Bi-directional • Pre-compiler for C interfaces

Message Center

• Tool for sending and receiving packets into actual system

• Use tool via 2 windows

• Learn via Lab 2

28 TOSSIM

• TinyOS Simulator (not typical) – Versus ns2 or glomosim or …

• Write your actual code

• Compile it into TOSSIM framework

• Once debugged – code moved to real platform

TOSSIM Features

A discrete event simulator; runs on a PC

High fidelity simulations – capture TinyOS behavior at a low level

Uses TinyOS’ component based architecture

29 TOSSIM capabilities ‹Simulates large scale sensor networks (e.g., thousands) ‹Simulates network at bit level (bit error per link) ‹Simulates repeatable loss rate ‹Simulates asymmetric links ‹Simulates each individual ADC capture ‹Simulates every interrupt in the system ‹Time is kept at 4MHz granularity => 4 million ticks per second

TOSSIM non-capabilities

‹ Does not simulate single strength ‹ Does not model execution time ° No spin locks or task spin locks ° A piece of code runs instantaneously ‹ Does not model power draw ‹ Interrupts are non-preemptive ‹ Simulates the 40Kbit RFM mica networking stack ‹ Does not simulate the Mica2 ChipCon CC1000 stack

30 TOSSIM Radio Models

‹ Simple : every mote in one cell, bits perfectly transmitted

‹ Lossy : connectivity determined at startup ° Radio propagation is not modeled, rather an abstraction of it is (bit error rate) ° Specified in a file *.nss (use –rf= option) ° Specified connectivity ° Specified bit error rate ° For example ° ::bit error rate ° 0:1:0.009

Radio Model my_radio_model.nss 0:1:0.001 1:0:0.002 .001 1 0:2:0.001 0 .002 2:0:0.9 .9 x .001 2

Model an asymmetric link

31 Using TOSSIM

‹Compiling TOSSIM cd apps/Blink make pc make –rf=fname pc

‹ Use: ./build/pc/main.exe [options]

[options] are (see manual for more):

-k , -Set radio speed to Kbits/s. Valid values: 10, 25, 50. -r, specifies a radio model (simple is default) -t, - tells TOSSIM to run for a specified number of virtual seconds. number of nodes to simulate

Debugging

Your code

…… dbg(DBG_CRC, “crc check failed”); …… dbg(DBG_BOOT, “Sensor initialized”); ……

32 TOSSIM Debugging

‹ Known dbg flags ( system/include/dbg_modes.h) : ° all, boot, clock, task, sched, sensor, led, route, am, crc, packet, encode, radio, logger, adc, i2c, uart, prog, sim, queue, simradio, hardware, simmem (found in TinyOS code)

° For use in applications: usr1, usr2, usr3, temp

‹ Insert debug statements in source code ° dbg(DBG_ROUTE|DBG_ERROR, "Received control message: lose our network name!.\n");

TOSSIM Debugging

‹ Set dbg flags to get the proper debug information ° When simulator starts it read DBG environment variable to enable modes ° For example: export DBG=usr1,route ° Only these debug statements will be active!

33 Important

• Once you recompile with mote as target instead of pc (i.e., TOSSIM)

– All debug statements are removed from the executable for you!

Using Debugging

• Print to screen or file • Use Serial Forwarder – Can inject messages to mote 0 • -comm tossim-serial – Can snoop all messages in network • -comm tossim-radio

• Run gdb – gdb build/pc/main.exe

34 TOSSIM

• See TOSSIM document (read when you are preparing for Lab 3)

• See TOSSIM paper (sections 1-3 inclusive; read now)

• Learn via Lab 3

Summary

• nesC – most widely used today for WSN - systems

• Use naming conventions – see handout

• Lab 0 – mechanics of downloading, etc. • Lab (Programming) Assignments 1-4 • Possible Extra Credit Project

35