You are on page 1of 45

TinyOS Tutorial

CS580S Sensor Networks and


Systems
February 7, 2007

Jisu Oh
Dept. of Computer Science
SUNY-Binghamton
Outline
• TinyOS Program Architecture
• NesC application: interfaces and components
• Concurrency Model: Two-level scheduling

• Component Development
• TinyOS installation
• Configuration file vs. Module file

• Running TinyOS code


• TOSSIM
• PowerTossim
TinyOS Program Architecture
• http://www.tinyos.net/tinyos-1.x/doc/index.html

• NesC application
= components with well-defined, bidirectional
interfaces

• Concurrency Model
• Two-level scheduling
Interfaces
• /opt/tinyos-1.x/tos/interfaces
• The only point of access to the component
• Bi-directional

• Declare a set of functions


• command
• Provided by a component, these provide functionality into
that component
• Invoked by a component wired to it
• the interface provider must implement
• event
• A “happening” that is produced by a component and that
can be responded to by any components wired to this
component
• the interface user must implement
Interface Timer

• /opt/tinyos-1.x/tos/interfaces/Timer.nc

• interface Timer{

command result_t start (char type, uint32_t interval);

command result_t stop ();

event result_t fired ();


}
Components
• Configurations  wiring
• Assemble other components together
• Connecting interfaces used by components to interfaces
provided by others

• Example: TimerC.nc
configuration TimerC{
provides interface Timer[uint8_t id];
provides interface StdControl;
}
implementation{
components TimerM, ClockC;

TimerM.Clock → ClockC;
Timer = TimerM;
}
Components
• Modules
• Provide application code
• Implement one or more interface

• Example CC1000RadioIntM.nc
module CC1000RadioIntM{
provides interface StdControl;
uses interface StdControl as TimerControl;
uses interface Timer as WakeupTimer;
}
implementation{
task void PacketSent(){}
command result_t StdControl.init(){}
event result_t WakeupTimer.fired(){}
}
Mica2 CC1000 Radio Stack Architecture
Provider, User and Interface

interface Timer{
command result_t start(char type, uint32_t interval);
command result_t stop();
event result_t fired();
}
StdControl User
Provider TimerControl
TimerC Interface
CC1000RadioIntM
Timer WakeupTimer

configuration TimerC{ module CC1000RadioIntM{


provides interface Timer[uint8_t id]; uses interface StdControl as TimerControl;
provides interface StdControl; uses interface Timer as WakeupTimer;
} }
Naming Conventions
• http://www.tinyos.net/tinyos-1.x/doc/tutorial/naming.html

• Interfaces
• Verbs or nouns
• In mixed case with the first letter of each internal word capitalized
• ex) ADC, Range, SendMsg

• Components
• Nouns
• In mixed case with the first letter of each internal word capitalized
• ex) Counter, TimerC, TimerM

• Files
• “.nc” as a suffix
• ex) ADC.nc, TimerC.nc
Concurrency Model

• Two-level scheduling
• Hardware event handlers
• Call commands, post tasks, and signal other events
• Preempt tasks
• Preempted by asynchronous hardware event handlers
(events and commands)
• Tasks
• computations Tasks
Preempt Tasks
POST FIFO
events

Hardware commands
Event
commands
handler
Interrupts
Time
Hardware
Concurrency Model (cont.)

• Scheduling priority summary


High
Hardware event, async events and async command
Events and commands
Tasks
Low

Preempt Tasks
POST FIFO
events

commands

commands

Interrupts
Time
Hardware
Two-level scheduling
FIFO

Preempt command 2 event 4


Task 1

Post Task 2

Post Task 1
command 1

event 1 event 2 event 3 event 5

Hardware Hardware Time


interrupt 1 interrupt 2
Next
• TinyOS Program Architecture
• NesC application: interfaces and components
• Concurrency Model: Two-level scheduling

• Component Development
• TinyOS installation
• Configuration file: wiring
• Module file: application code

• Running TinyOS code


• TOSSIM
• PowerTossim
TinyOS installation for windows

• Install TinyOS 1.1.0


• Not TinyOS 1.1.15 or TinyOS 2.0
• Upgrade your Cygwin
• Cygwin distributed with TinyOS 1.1.0 is not compatible with
TinyOS 1.1.11 or above version
• Upgrade nesc version >= 1.1.1
• Reboot your computer
• Upgrade to TinyOS 1.1.15 CVS Snapshots to use
PowerTossim
• Check your installation
• Link to installation instruction
http://bingweb.binghamton.edu/~joh3/CS580S/tinyos_installation.html
An example application: Blink
• /opt/tinyos-1.x/apps/Blink

• Configuration file – Blink.nc Wireing!


• a top-level configuration file
• specify how and to which other components this
particular component is wired to
• allow the component to “provide” various interfaces to
other components (that can wire to it) or “use”
interfaces

Application code!
• Module file – BlinkM.nc
• the actual implementation of the component itself
• deal with event handling, command implementation,
task posting, etc.
A component graph of Blink application
Blink.nc – A frame of Configuration files

Indicate that this is


a configuration file

configuration Blink
Interfaces which this
{ configuration
provide interfaces
provides or uses

use interfaces
}

implementation A list of components


which this configuration
{ references
components

// wiring Connecting
components
}
Blink.nc – in detail

configuration Blink No interfaces are


{ provided or used by
//provides interfaces Blink.nc
//uses interfaces
}

implementation
{ components Main, BlinkM, SingleTimer, LedsC;
Component.interface
// wiring
Main.StdControl → BlinkM.StdControl;
Main.StdControl → SingleTimer.StdControl;
BlinkM.Timer → SingleTimer.Timer;
BlinkM.Leds → LedsC;
} interfaces BIND implementation
Blink.nc – Main and StdControl

• A component “Main”
• Executed first in a TinyOS application
• A TinyOS application must have Main component in its
configuration

• An interface “StdControl”
• Used to initialize and start TinyOS components
• /opt/tinyos-1.x/tos/interfaces/StdControl.nc
interface StdControl
{
command result_t init();
command result_t start();
command result_t stop();
}
BlinkM.nc – A frame of Module files

Indicate that this


is a module file

module BlinkM
Interfaces which this
{ module provides or
provides interfaces
uses

uses interfaces
}
Application code
implementation
{
// implementation of
commands, //events or any tasks
if needed
}
Implementation
BlinkM.nc – inside of Module part needed

interface StdControl
module BlinkM { command result_t init();
{ provides interface StdControl ; command result_t start();
command result_t stop();
uses interface Timer ; }

interface Timer
{ command result_t start(char type, uint32_t, interval);
command result_t stop();
event result_t fired();
}

uses interface Leds ; interface Leds


{ async command result_t init();
async command result_t redOn();
// and more commands
} }
BlinkM.nc – inside of Module (cont.)

implementation
{ command result_t StdControl.init() {
call Leds.init();
return SUCCESS;
}
command result_t StdControl.start() {
return call Timer.start(TIMER_REPEAT, 1000);
}
command result_t StdControl.stop() {
return call Timer.stop();
}
event result_t Timer.fired() {
call Leds.yellowToggle();
return SUCCESS;
}
}
Message Communication Example
• A component “MsgComm”
• A example application which shows a message
communication in TinyOS
• http://bingweb.binghamton.edu/~joh3/CS580S/MsgComm.tgz
MsgComm
• MsgComm.h
//Message id for this application
enum{ AM_MYMSG = 10 };

//Data structure for TOS_Msg.data


Typedef struct MsgCommMsg{
uint16_t src; //source address
uint16_t reading; //sensor reading
}__attribute__((packed)) MsgCommMsg;

• MsgComm.nc
Includes MsgComm;
configuration MsgComm {
}
Implementation{
components Main, MsgCommM, TimerC, Photo, GenericComm as Comm;

Main.StdControl → MsgCommM.StdControl;
Main.StdControl → TimerC;
Main.StdControl → Photo;
Main.StdControl → Comm;

MsgCommM.ADC → Photo;
MsgCommM.Timer → TimerC.Timer[unique (“Timer”)];
MsgCommM.SendMsg → Comm.SendMsg[AM_MYMSG];
MsgCommM.ReceiveMsg → Comm.ReceiveMsg[AM_MYMSG];
}
MsgComm (cont.)
• MsgCommM.nc (1)
Includes MsgComm; command result_t StdControl.init()
{
module MsgCommM { atomic ch_busy = FALSE;
provides interface StdControl; return SUCCESS;
} // end of StdContro.init()
uses interface SendMsg;
uses interface ReceiveMsg;
uses interface ADC; command result_t StdControl.start()
uses interface Timer; {
} return call Timer.start(TIMER_REPEAT, 1000);
} // end of StdControl.start()
implementation
{ command result_t StdControl.stop()
bool ch_busy; {
TOS_Msg tos_msg_buf; return call Timer.stop();
MsgCommMsg* send_buf; }//end of StdControl.stop()
MsgCommMsg msg_buf;
event result_t Timer.fired()
{
call ADC.getData();
return SUCCESS;
} // end of Timer.fired()
MsgComm (cont.)
• MsgCommM.nc (2)
task void sendData()
{
atomic
{
if(!ch_busy)
{
send_buf = (MsgCommMsg*)tos_msg_buf.data;
send_buf->src = msg_buf.src;
send_buf->reading = msg_buf.reading;

if((call SendMsg.send(TOS_BCAST_ADDR, sizeof(MsgCommMsg), &tos_msg_buf)) != SUCCESS)


ch_busy = FALSE;
else
{
dbg(DBG_USR1, “Sending at node [%d]: src[%d], data[%d]\n”,
TOS_LOCAL_ADDRESS, send_buf->src, send_buf->reading);
}
} //end of if to check channel busy
} //end of atomic
} //end of task sendData()

async event result_t ADC.dataReady(uint16_t data)


{
atomic msg_buf.src = TOS_LOCAL_ADDRESS;
atomic msg_buf.reading = data;
post sendData();
return SUCCESS;
}// end of ADC.dataReady()
MsgComm (cont.)
• MsgCommM.nc (3)

event result_t SendMsg.sendDone(TOS_MsgPtr msg, result_t success)


{
atomic ch_busy = FALSE;
return SUCCESS;
} //end of SendMsg.sendDone()

event TOS_MsgPtr ReceiveMsg.receive(TOS_MsgPtr m)


{
MsgCommMsg* data_buf = (MsgCommMsg*)m->data;

dbg(DBG_USR1, “Receiving from [%d] with data [%d]\n”,


data_buf->src, data_buf->reading);
atomic msg_buf.src = data_buf->src;
atomic msg_buf.reading = data_buf->reading;

post sendData();
return m;
}// end of ReceiveMsg.receive()

} // end of implementation
Multihop Routing in TinyOS
• Uses a shortest-path-first algorithm with a single
destination node (the root) and active two-way link
estimation
• MultiHopEngineM: the overall packet movement logic for
multi-hop functionality (determines the next-hop path)
• MultiHopLEPSM
• the Link Estimation and Parent Selection(LEPS) mechanisms
• You can import your own link estimation and parent selection
mechanism instead of using this module
• Works on real motes, not on TOSSIM
• MultiHopRouter: connects above two components

• Reference:
http://www.tinyos.net/tinyos-1.x/doc/multihop/multihop_routing
• Multihop component : /opt/tinyos-1.x/lib/Route
• example application: Surge
• /opt/tinyos-1.x/apps/Surge
Next
• TinyOS Program Architecture
• NesC application: interfaces and components
• Concurrency Model: Two-level scheduling

• Component Development
• TinyOS installation
• Configuration file: wiring
• Module file: application code

• Running TinyOS code


• TOSSIM
• PowerTossim
Running on a PC: TOSSIM

• Why simulation?

• Sensor networks are


• new, event-driven, large, deployed in remote locations

• Simulation provides:
• controlled, reproducible testing environment
• means to explore and improve design space

• TOSSIM
• P. Levis, N. Lee, M. Welsh, and D. Culler,
TOSSIM: Accurate and Scalable Simulation of Entire TinyOS App
ACM Conference on Embedded Networked Sensor
Systems (SenSys), November 2003.
Running on a PC: TOSSIM (cont.)

• TOSSIM
• TinyOS mote simulator

• Scales to thousands of nodes

• Compiles directly from TinyOS source

• Simulates network at bit level

• Replaces hardware with software components

• Hardware interrupts are modeled as simulator events

• Manual: /opt/tinyos-1.x/doc/nido.pdf
TOSSIM Architecture
How to use TOSSIM?
• Generate Makefile # Makefile for Blink
• component name COMPONENT=Blink
• include ../Makerules # PFLAGS = -I%T/lib/Counters
• optional flags Include ../Makerules

• Compile and Run


• Change directory where your application is stored
cd /opt/tinyos-1.x/apps/Blink
• Compile the application for use in TOSSIM simulation
on the host pc
make pc
• Enable debugging mode
export DBG=usr1
• Run an executable file
./bulid/pc/main.exe [option] N
Where N is the number of nodes in the simulation
Debugging: dbg
• dbg
• Configuration of debugging output at run-time

• Example debugging statement


• dbg(DBG_BOOT, “AM Module initialized\n”);

• Available DBG_[mode]
• all, boot, clock, task, sched, sensor, led, crypto,
route, am, crc, packet, encode, radio, logger, etc.

• usr1, usr2, usr3


• user output mode 1,2,3
• reserved for application components
PowerTossim
• Sensor network
• power limited, hard to reach locations (ex, battlefield),
difficult and expensive to replace batteries
 Need to simulate energy usage before deployment

• PowerTossim
• a power modeling extension to TOSSIM developed by
Harvard University
• Models power consumed by TinyOS applications
• Integrated into TOSSIM in the TinyOS 1.1.10 or above

• PowerTossim references
• http://www.eecs.harvard.edu/~shnayder/ptossim/
PowerTossim (cont.)
• Enable power mode for dbg
export DBG=power

• Run your application with the –p flag and save the output to
a file
./build/pc/main.exe –t=60 –p 2 > out.trace

• Run postprocess.py on the resulting trace


$TOSROOT/tools/scripts/PowerTOSSIM/postprocess.py
–sb=0 –em
$TOSROOT/tools/scripts/PowerTOSSIM/mica2_energy_mod
el.txt out.trace

• Then
PowerTossim (cont.)
• You will see
Let’s run MsgComm!
• http://bingweb.binghamton.edu/~joh3/CS580S
• Download MsgComm.tgz, upzip and compile it
Let’s run MsgComm! (cont.)
• Run!

← Compile on the PC

↙Turn on DBG mode USR1 and POWER


↙ Run with 10 motes for 60 seconds
and save it into a file

↖Get a power consumption summary by using PowerTOSSIM


Let’s run MsgComm! (cont.)
• 10output.trace

From DBG_POWER

From DBG_USR1
Let’s run MsgComm! (cont.)
• 10output.power

Consumed energy summary


for mote 0
Useful URL
• TinyOS official Website: http://www.tinyos.net
• TinyOS Documentation
• http://www.tinyos.net/tinyos-1.x/doc/index.thml
• Tutorial
• http://www.tinyos.net/tinyos-1.x/tutorial/index.html
• NesC
• http://www.tinyos.net/tinyos-1.x/doc/nesc/ref.pdf
• Tossim
• http://www.tinyos.net/tinyos-1.x/doc/nido.pdf
• PowerTossim
• http://www.eecs.harvard.edu/~shnayder/ptossim/install.htm
• Sample applications
• In tinyos directory, /opt/tinyos-1.x/apps
• TinyOS CVS repository
• http://sourceforge.net/cvs/?group_id=28656
Questions?
THANK YOU!