SlideShare a Scribd company logo
TinyOS 2.1 IPSN 2009 Stephen Dawson-Haggerty, Omprakash Gnawali, David Gay, Philip Levis, Răzvan Musăloiu-E., Kevin Klues, and John Regehr San Francisco, CA - April 16, 2009
Agenda 8:33: Overview (Om) 8:40: Basics (Phil and David) 9:30: TOSSIM (Razvan) 9:45: Safe TinyOS (John) 10:00: Threads (Kevin) 10:15:  break 10:20: Protocols (Om) 10:40: Upcoming (Stephen) 10:50: Hands-on (Razvan, Om, et al.) 11:30: End
What? An operating system for low power,  embedded, wireless devices Wireless sensor networks (WSNs) Sensor-actuator networks Embedded robotics Open source, open developer community http://www.tinyos.net
Who are we? Some principal developers and designers Stephen Dawson-Haggerty: network protocols David Gay: language design Omprakash Gnawali: network protocols Kevin Klues: core system Philip Levis: core system Răzvan Musăloiu-E.: network protocols John Regehr: compilation tools There are many contributors besides us, they all deserve credit
Why? TinyOS is very powerful  Modern operating system and language techniques in an embedded system A lot of libraries, support code, and community development TinyOS has a steep learning curve It can take time to use all of its capabilities Give a jump-start on high level concepts and how to write applications
Goals Give you a high-level understanding of TinyOS’s structure and ideas Explain how to build and install applications Survey important libraries  Focus on very recent additions Give you the experience of writing a networked sensing application
Schedule 8:33: Overview (Om) 8:40: Basics (Phil and David) 9:30: TOSSIM (Razvan) 9:45: Safe TinyOS (John) 10:00: Threads (Kevin) 10:15:  break 10:20: Protocols (Om) 10:40: Upcoming (Stephen) 10:50: Hands-on (Razvan, Om, et al.) 11:30: End
Basics Philip Levis (Stanford) David Gay (Intel Research)
Outline Components and interfaces Basic example Tasks More complex example Compiling and toolchain
TinyOS Components TinyOS and its applications are in nesC C dialect with extra features Basic unit of nesC code is a component Components connect via interfaces Connections called “wiring” B A i
Components A component is a file (names must match) Modules are components that have variables and executable code Configurations are components that wire other components together
Component Example BlinkC wires BlinkP.Timer to TimerC.Timer module BlinkP { … } implementation { int c; void increment() {c++;} } configuration BlinkC { … } implementation { components new TimerC(); components BlinkC; BlinkC.Timer -> TimerC; } TimerC BlinkP Timer
Singletons and Generics Singleton components are unique: they exist in a global namespace Generics are instantiated: each instantiation is a new, independent copy configuration BlinkC { … } implementation { components new TimerC(); components BlinkC; BlinkC.Timer -> TimerC; }
Interfaces Collections of related functions Define how components connect Interfaces are bi-directional: for A->B Commands are from A to B Events are from B to A Can have parameters (types) interface Timer<tag> { command void startOneShot(uint32_t period); command void startPeriodic(uint32_t period); event void fired(); }
Outline Components and interfaces Basic example Tasks More complex example Compiling and toolchain
Basic Example Goal: write an anti-theft device. Let’s start simple. Two parts: Detecting theft. Assume: thieves put the motes in their pockets. So, a “dark” mote is a stolen mote. Every N ms check if light sensor is below some threshold Reporting theft. Assume: bright flashing lights deter thieves. Theft reporting algorithm: light the  red LED  for a little while! What we’ll see Basic components, interfaces, wiring Essential system interfaces for startup, timing, sensor sampling
The Basics – Let’s Get Started module AntiTheftC { uses interface Boot; uses interface Timer<TMilli> as Check; uses interface Read<uint16_t>; } implementation { event void Boot.booted() { call Check.startPeriodic(1000); } event void Check.fired() { call Read.read(); } event void Read.readDone(error_t ok, uint16_t val) { if (ok == SUCCESS && val < 200) theftLed(); } } Components start with a  signature  specifying the interfaces  provided  by the component the interfaces  used  by the component A module is a component implemented in C with functions implementing commands and events and extensions to call commands, events interface Boot { /* Signaled when OS booted */ event void booted(); } interface Timer<tag> { command void startOneShot(uint32_t period); command void startPeriodic(uint32_t period); event void fired(); }
The Basics – Split-Phase Ops module AntiTheftC { uses interface Boot; uses interface Timer<TMilli> as Check; uses interface Read<uint16_t>; } implementation { event void Boot.booted() { call Check.startPeriodic(1000); } event void Check.fired() { call Read.read(); } event void Read.readDone(error_t ok, uint16_t val) { if (ok == SUCCESS && val < 200) theftLed(); } } In TinyOS, all long-running operations are  split-phase: A command starts the op: read An event signals op completion: readDone interface Read<val_t> { command error_t read(); event void readDone(error_t ok, val_t val); }
The Basics – Split-Phase Ops module AntiTheftC { uses interface Boot; uses interface Timer<TMilli> as Check; uses interface Read<uint16_t>; } implementation { event void Boot.booted() { call Check.startPeriodic(1000); } event void Check.fired() { call Read.read(); } event void Read.readDone(error_t ok, uint16_t val) { if ( ok == SUCCESS  && val < 200) theftLed(); } } In TinyOS, all long-running operations are  split-phase: A command starts the op: read An event signals op completion: readDone Errors are signalled using the error_t type, typically Commands only allow one outstanding request Events report any problems occurring in the op interface Read<val_t> { command error_t read(); event void readDone(error_t ok, val_t val); }
The Basics – Configurations configuration AntiTheftAppC { } implementation { components AntiTheftC, MainC, LedsC; AntiTheftC.Boot -> MainC.Boot; AntiTheftC.Leds -> LedsC; components new TimerMilliC() as MyTimer; AntiTheftC.Check -> MyTimer; components  new PhotoC(); AntiTheftC.Read -> PhotoC; } A configuration is a component built out of other components. It  wires  “used” to “provided” interfaces. It can instantiate  generic  components It can itself provide and use interfaces generic configuration TimerMilliC() { provides interface Timer<TMilli>; } implementation { ... } generic configuration PhotoC() { provides interface Read; } implementation { ... }
Components
Outline Components and interfaces Basic example Tasks and concurrency More complex example Compiling and toolchain
Tasks TinyOS has a single stack: long-running computation can reduce responsiveness Tasks: mechanism to defer computation Tells TinyOS “do this later” Tasks run to completion TinyOS scheduler runs them one by one in the order they post Keep them short! Interrupts run on stack, can post tasks
Outline Components and interfaces Basic example Tasks and concurrency More complex example Compiling and toolchain
More Complex Application Let’s improve our anti-theft device. A clever thief could still steal our motes by keeping a light shining on them! But the thief still needs to pick up a mote to steal it. Theft Detection Algorithm 2: Every N ms, sample acceleration at 100Hz and check if variance above some threshold What we’ll see (Relatively) high frequency sampling support Use of tasks to defer computation-intensive activities TinyOS execution model
Advanced Sensing, Tasks uses interface ReadStream ; uint16_t accelSamples[ACCEL_SAMPLES]; event void Timer.fired() { call  ReadStream.postBuffer (accelSamples, ACCEL_SAMPLES); call  ReadStream.read (10000); } event void  ReadStream.readDone (error_t ok, uint32_t actualPeriod) { if (ok == SUCCESS) post checkAcceleration(); } task void checkAcceleration() { ... check acceleration and report theft... } ReadStream is an interface for periodic sampling of a sensor into one or more buffers. postBuffer adds one or more buffers for sampling read starts the sampling operation readDone is signalled when the last buffer is full interface ReadStream<val_t> { command error_t postBuffer(val_t* buf, uint16_t count); command error_t read(uint32_t period); event void readDone(error_t ok, uint32_t actualPeriod); }
Advanced Sensing, Tasks uint16_t accelSamples[SAMPLES]; event void ReadStream.readDone(error_t ok, uint32_t actualPeriod) { if (ok == SUCCESS) post checkAcceleration(); } task void checkAcceleration()  { uint16_t i, avg, var; for (avg = 0, i = 0; i < SAMPLES; i++) avg += accelSamples[i]; avg /= SAMPLES; for (var = 0, i = 0; i < SAMPLES; i++) { int16_t diff = accelSamples[i] - avg; var += diff * diff; }  if (var > 4 * SAMPLES) theftLed(); } In readDone, we need to compute the variance of the sample. We defer this “computationally-intensive” operation to a separate  task , using post. We then compute the variance and report theft.
TinyOS Execution Model RealMainP AccelStreamC AntiTheftC RealMainP Stack Task Queue Timer Alarm SchedulerP Interrupt table serial receive H/W timer A/D conv. AntiTheftC Timer Alarm
TinyOS Execution Model Stack Task Queue serial receive H/W timer A/D conv. Interrupt table RealMainP AccelStreamC AntiTheftC Timer Alarm SchedulerP timer task SchedulerP Alarm Timer
TinyOS Execution Model SchedulerP Stack Task Queue Interrupt table RealMainP AccelStreamC AntiTheftC Timer Alarm SchedulerP serial receive H/W timer A/D conv. timer task AntiTheftC AccelStreamC Timer
Networking – “External” Types #include “antitheft.h” module AntiTheftC { ... uses interface  DisseminationValue<settings_t>  as SettingsValue; } implementation {  settings_t settings; event void SettingsValue.changed() { const settings_t *newSettings = call SettingsValue.get(); settings.detect = newSettings->detect; settings.alert = newSettings->alert; call Check.startPeriod(newSettings->checkInterval); } event void Timer.fired() { if (settings.detect & DETECT_DARK) call Read.read(); if (settings.detect & DETECT_ACCEL) { call ReadStream.postBuffer(accelSamples, ACCEL_SAMPLES); call ReadStream.read(10000); } } #ifndef ANTITHEFT_H #define ANTITHEFT_H typedef nx_struct { nx_uint8_t alert, detect; nx_uint16_t checkInterval; } settings_t; #endif External types (nx_...) provide C-like access, but: platform-independent layout and endianness gives interoperability no alignment restrictions means they can easily be used in network buffers compiled to individual byte read/writes
TinyOS/nesC Summary Components and Interfaces Programs built by writing and wiring components modules are components implemented in C configurations are components written by assembling other components Execution model Execution happens in a series of tasks (atomic with respect to each other) and interrupt handlers No threads System services: startup, timing, sensing (so far) (Mostly) represented by instantiatable generic components This instantiation happens at compile-time! (think C++ templates) All slow system requests are split-phase
Outline Components and interfaces Basic example Tasks More complex example Compiling and toolchain
The Toolchain TinyOS App PC Applications Native binary: 03 2F 77 9A F2 FF ...
The Toolchain TinyOS PC Applications Compile TinyOS applications Native binary: 03 2F 77 9A F2 FF ... App
The Toolchain Native binary: 03 2F 77 9A F2 FF ... TinyOS App PC Applications Install applications on motes
The Toolchain TinyOS App PC Applications Build PC applications Native binary: 03 2F 77 9A F2 FF ...
The Toolchain TinyOS App PC Applications Document TinyOS Native binary: 03 2F 77 9A F2 FF ...
The “Make” System Native binary: 03 2F 77 9A F2 FF ... make telosb install automates nesC, C compilation, mote installation TinyOS App PC Applications
“ Make”: Compile Applications ncc gcc int main() {   scheduler_init();   ... } Native binary: 03 2F 77 9A F2 FF ...
“ Make”: Install Applications pybsl, uisp, etc deluge Native binary: 03 2F 77 9A F2 FF ...
Build PC Applications TinyOS Java, C, Python apps Packet formats, constants, etc Talk with motes Native binary: 03 2F 77 9A F2 FF ...
PC Applications: Extracting Information from TinyOS mig ncc  –dump ncg Java, C or Python app packet formats constants <the kitchen sink> TinyOS
PC Applications: Talking to Motes Java, C or Python app sf packet libs packet libs
Document TinyOS nesdoc
TOSSIM Răzvan Musăloiu-E. (JHU)
What is TOSSIM? Discrete event simulator ns2
Cycle-accurate simulators Avrora, MSPSim Alternatives
Two directions Port make PC a supported platform Virtualize simulate one of the supported platforms TOSSIM in tinyos-2.x TOSSIM in tinyos-1.x
Features Simulates a MicaZ mote ATmega128L (128KB ROM, 4KB RAM) CC2420 Uses CPM to model the radio noise Supports two programming interfaces: Python C++
Anatomy TOSSIM tos/lib/tossim tos/chips/atm128/sim tos/chips/atm128/pins/sim tos/chips/atm128/timer/sim tos/chips/atm128/spi/sim tos/platforms/mica/sim tos/platforms/micaz/sim tos/platforms/micaz/chips/cc2420/sim Application Makefile *.nc *.h Simulation Driver *.py | *.cc
Quick Overview Glue Application Simulation NesC Python C++
The Building Process $ make micaz sim Generate an XML schema Compile the application Compile the Python support Build a share object Copying the Python support $ ./sim.py pytossim.o tossim.o c-support.o sim.o app.xml _TOSSIMmodule.o TOSSIM.py
TOSSIM.py Tossim Radio Mote Packet Mac
TOSSIM.Tossim .getNode() -> TOSSIM.Mote .radio() -> TOSSIM.Radio .newPacket() -> TOSSIM.Packet .mac() -> TOSSIM.Mac .runNextEvent() .ticksPerSecond() .time()
10 seconds from TOSSIM import * t = Tossim([]) ... while t.time() < 10*t.ticksPerSecond(): t.runNextEvent()
dbg Syntax dbg( tag, format, arg1, arg2, ... ); Example dbg(“Trickle”, “Starting time with time %u.\n”, timerVal); Python t = Tossim([]) t.addChannel(“Trickle”, sys.stdout)
Useful Functions typedef  long long int sim_time_t ; char* sim_time_string() sim_time_t sim_time() int sim_random() sim_time_t sim_ticks_per_sec()
Radio Model Closest-fit Pattern Matching (CPM) Improving Wireless Simulation Through Noise Modeling HyungJune Lee, Alberto Cerpa, and Philip Levis IPSN 2007
Radio Model Sender Receiver
Noise Level Meyer Heavy Casino Lab Signal SNR SNR
CC2420 SNR/PRR
TOSSIM.Radio .add( source, destination, gain ) .connected( source, destination ) -> True/False .gain( source, destination )
TOSSIM.Mote .bootAtTime( time ) .addNoiseTraceReading( noise ) .createNoiseModel() .isOn() -> True/False .turnOn()/.turnOff()
Example from TOSSIM import * t = Tossim([]) r = t.Radio() mote0 = t.getNode(0) mote1 = t.getNode(1) mote2 = t.getNode(2) r.add(0, 1, -10) r.add(1, 0, -10) r.add(1, 2, -50) r.add(2, 1, -50) 0 1 2 -50 dB -10 dB
Example (cont) noise = file(&quot;meyer-short.txt&quot;) lines = noise.readlines() for line in lines: str = line.strip() if (str != &quot;&quot;): val = int(str) for m in [mote0, mote1, mote2]: m.addNoiseTraceReading(val) for m in [mote0, mote1, mote2]: m.createNoiseModel() 0 1 2 -50 dB -10 dB
Other Features Injecting packets Inspecting internal variables C++ interface Debuging using gdb
Improvements TossimLive SerialActiveMessageC CC2420sim Multiple channels PacketLink CC2420Packet: .getRSSI(), .getLQI() ReadRssi() Flash support
Future Parametrized the PRR/SNR curve based on packet size  (in progress) Support for multiple binary images  (harder)
Safe TinyOS John Regehr (Utah)
What is Safe TinyOS? Memory safe execution for TinyOS 2.1 apps Compiler inserts safety checks These checks trap pointer / array errors before they can corrupt memory Behavior of memory-safe applications is unchanged Why use Safe TinyOS? Debugging pointer and array problems on motes can be extremely difficult
Using Safe TinyOS Must explicitly request safe compilation $ cd tinyos-2.x/apps/BaseStation $ make micaz safe … 18544 bytes in ROM 1724 bytes in RAM $ make micaz … 14888 bytes in ROM 1724 bytes in RAM
Designed to Fail In TinyOS 2.1: $ cd $TOSROOT/apps/tutorials/BlinkFail $ make micaz install  The application dies after a few seconds BlinkFailC.nc has an obvious memory bug Next try this: $ make micaz safe install After a few seconds the mote starts blinking its LEDs in funny patterns
FLIDs Default behavior on safety violation is to output a FLID (Fault Location IDentifier) using the LEDs A FLID is 8 digits in base-4 No LEDs lit = 0 1 LED lit = 1 2 LEDs lit = 2 3 LEDs lit = 3 A tool decodes FLIDs into error messages
Decoding a FLID $ tos-decode-flid ./build/micaz/flids.txt 00001020 Deputy error message for flid 0x0048:  BlinkFailC__a <= BlinkFailC__a + BlinkFailC__i++ + 1 (with no overflow): BlinkFailC.nc:70:  Assertion failed in CPtrArithAccess: BlinkFailC__a + BlinkFailC__i++ + 1 <= BlinkFailC__a + 10 (with no overflow)
Safe Components Safety is “opt in” at the level of nesC components This component is compiled as safe code: generic module SimpleArbiterP() @safe() { … } These components are “trusted” code: generic module SimpleArbiterP() @unsafe() { … } generic module SimpleArbiterP() { … } Trusted code is compiled w/o safety checks
Porting Code to Safe TinyOS Recommended strategy Annotate a component as  @safe() Compile application in safe mode Fix warnings / errors Repeat until no trusted components remain Arrays and pointers require annotations Annotations are for Deputy, the safe C compiler behind Safe TinyOS Purpose of annotations is to link memory regions with their bounds information
Annotation 1 To declare  msg , which always refers to a valid  message_t message_t* ONE msg = ...;  Or if  msg  may be null message_t* ONE_NOK msg;  Most annotations have a  _NOK  form But avoid using it when possible
Annotation 2 To declare  uartQueue  as an array of 10 pointers to  message_t Where each element of the array must at all times refer to a valid  message_t  message_t* ONE uartQueue[10];
Annotation 3 To declare  reqBuf  as a pointer that always points to a valid block of at least  reqBytes   uint8_t s:  uint8_t *COUNT(reqBytes) reqBuf;  Array dereferencing / pointer arithmetic can be done on  reqBuf : reqBuf[0]  is legal reqBuf[reqBytes-1]  is legal reqBuf[reqBytes]  results in a safety violation
Annotation 4 Multiple-indirect pointers require an annotation at each level: int *ONE *ONE pp = ...;  However, these are uncommon in TinyOS
Annotation 5 If you get stuck, the “trusted cast” offers an escape hatch: cc2420_header_t* ONE x = TCAST( cc2420_header_t* ONE,  (uint8_t *)msg +  offsetof(message_t, data) -  sizeof(cc2420_header_t) );
Interface Annotation 1 The  getPayload()  command from the Packet interface might be annotated like this: command void* COUNT_NOK(len)  getPayload (message_t* ONE msg,    uint8_t len);
Interface Annotation 2 However,  tinyos-2.x/tos/interfaces/Packet.nc  contains: * @param 'message_t* ONE msg' … * @param len … * @return 'void* COUNT_NOK(len)' … */  command void* getPayload (message_t* msg,    uint8_t len);  nesC allows you to put annotations in documentation comments
Safe TinyOS Summary Safe execution is useful Safety annotations are good documentation Most Mica2, MicaZ, TelosB apps and core services are safe Safe TinyOS Tutorial: http://docs.tinyos.net/index.php/Safe_TinyOS
Threads Kevin Klues (UCB)
The Great Divide Event-Based Execution More efficient Less RAM usage More complex Thread-Based Execution Less Efficient More RAM Usage Less Complex void  myFunc() { error_t  e = read(); //continue execution flow } void  readDone( uint8_t  val,  error_t  e) { //read() continuation code } void  myFunc() { error_t  e; uint8_t  val = read(&e); //read() continuation code } TOSThreads aims to resolve this fundamental tension
TOSThreads in a Nutshell Natural extension to the existing TinyOS concurrency model Implements Full-Fledged Threads Library Introduces Minimal Disruption to TinyOS Provides Flexible Event-based / Thread-based Code Boundary Enables Dynamic Linking and Loading of Application Binaries at Runtime Standard C and nesC based APIs
Architecture Overview Task   Scheduler  Thread Scheduler System Calls TinyOS   Thread Application   Threads
Blink Example (nesC) configuration  BlinkAppC { } implementation  { components  MainC, BlinkC,  LedsC; components  new ThreadC(STACK_SIZE); MainC.Boot <- BlinkC; BlinkC.Thread -> ThreadC; BlinkC.Leds -> LedsC; } module  BlinkC { uses  { interface  Boot; interface  Thread; interface  Leds; } } implementation  { event  void Boot.booted() { call  Thread.start(NULL); } event  void Thread.run( void * arg) { for (;;) { call  Leds.led0Toggle(); call  Thread.sleep(BLINK_PERIOD); } }
Blink Example (standard C) #include  &quot;tosthread.h&quot; #include  &quot;tosthread_leds.h&quot; //Initialize variables associated with a thread tosthread_t blink; void  blink_thread( void * arg); void  tosthread_main( void * arg) { tosthread_create(&blink, blink_thread, NULL, STACK_SIZE); } void  blink_thread( void * arg) { for(;;) { led0Toggle(); tosthread_sleep(BLINK_PERIOD); } }
Modifications to TinyOS Change in boot sequence Small change is TinyOS task scheduler Additional post-amble in the interrupt sequence
Boot Sequence event   void   TinyOS.booted() { atomic  { platform_bootstrap(); call   Scheduler.init();  call   PlatformInit.init();  while   (call Scheduler.runNextTask()); call   SoftwareInit.init();  while   (call Scheduler.runNextTask()); } signal   Boot.booted(); /* Spin in the Scheduler */  call   Scheduler.taskLoop(); } Standard TinyOS Boot Main int   main() { signal   TinyOS.booted(); //Should never get here return -1; }
Boot Sequence event   void   ThreadScheduler.booted() { setup_TinyOS_in_kernel_thread(); signal   TinyOSBoot.booted(); } Thread Scheduler Boot New Main int   main() { signal   ThreadScheduler.booted(); //Should never get here return -1; }
Task Scheduler command   void   Scheduler.taskLoop()  { for   (;;)  { uint8_t   nextTask; atomic   { while   ((nextTask = popTask()) == NO_TASK))   call  McuSleep.sleep(); } signal   TaskBasic.runTask[nextTask](); } } Original command   void   Scheduler.taskLoop()  { for   (;;)  { uint8_t   nextTask; atomic   { while   ((nextTask = popTask()) == NO_TASK)    call  ThreadScheduler.suspendThread(TOS_THREAD_ID); } signal   TaskBasic.runTask[nextTask](); } } New
Interrupt Handlers void   interruptCurrentThread() { if (  call   TaskScheduler.hasTasks() ) { call   ThreadScheduler.wakeupThread(TOS_THREAD_ID); call   ThreadScheduler.interruptCurrentThread(); } } TOSH_SIGNAL (ADC_VECTOR) { signal   SIGNAL_ADC_VECTOR.fired(); atomic  interruptCurrentThread(); } TOSH_SIGNAL (DACDMA_VECTOR) { signal   SIGNAL_DACDMA_VECTOR.fired(); atomic  interruptCurrentThread(); } … . … .
System Calls Task Queue Routing Arbiter System Call Task Receive Timer Send   Receive  Sense   Block  Storage  Application Thread  System Calls TinyOS Thread
Linking and Loading Full applications written in standard C Custom MicroExe format Multiple concurrently running applications Generic TinyLD component supporting multiple APIs
Resources TOSThreads Tutorial http://docs.tinyos.net/index.php/TOSThreads_Tutorial TOSThreads TEP http://www.tinyos.net/tinyos-2.x/doc/html/tep134.html Source Code System code:  tinyos-2.x/tos/lib/tosthreads Example Applications:  tinyos-2.x/apps/tosthreads
Protocols Omprakash Gnawali (USC)
Protocols in TinyOS 2.1 Network Protocols Collection: CTP, MultihopLQI Dissemination: Drip, DIP Time Synchronization (FTSP) Over-the-air programming (Deluge)
Collection Collect data from the network to one or a small number of roots One of many traffic classes Available: MultihopLQI and CTP
MultihopLQI Mostly tested and used on platforms with CC2420 MicaZ, TelosB, … Small code footprint tos/lib/net/lqi
CTP Platform independent More consistent performance than with MultihopLQI Code footprint can be a concern tos/lib/net/ctp
CTP Architecture Router Forwarder Lnk Estimator Link Layer Application
CTP Link Estimator Platform independent Beacons and data packets Bi-directional ETX estimate Does not originate beacons itself Accurate but also agile
CTP Router ETX path metric Beacon interval can be 64 ms-x mins Select new path if better by at least 1.5 ETX Alternate parents
CTP Forwarder Duplicate suppression Retransmissions Loops trigger route updates Forward through alternate parents
CTP Reliability
Dissemination Send data to all the nodes Commands, configuration parameters Efficient and fast Available protocols – Drip and DIP
Drip Fast and efficient for small number of items Trickle timers for advertisements Suppression tos/lib/net/drip
DIP Efficiently Disseminates large number of items (can not fit in one packet) Use hashes and version vectors to detect and identify updates to the values tos/lib/net/dip
Deluge Over-the-air programming Disseminates code Programs the nodes
Deluge Details Supports Tmote Sky/EPIC and MicaZ. Bulk dissemination on top of Drip Python tools Support for MIB600.  (new) tos/lib/net/Deluge, tos/lib/tosboot
Time Synchronization Global time on all the nodes Node with smallest id becomes the root Flooding Time Synchronization Protocol (FTSP) tos/lib/ftsp
Upcoming Technologies Stephen Dawson-Haggerty (UCB)
“ Work in Progress” Proceeding in working groups IEEE 802.15.4  Zigbee 6lowpan/IPv6 Overall theme: leverage emerging standards
IEEE 802.15.4 PHY/MAC specification MAC under development by working group CSMA-CA GTS Slotted CSMA-CA Application interface in flux More reading: tos/lib/mac/tkn154 http://www.tkn.tu-berlin.de/publications/papers/TKN154.pdf
ZigBee Network protocol and application stack built on IEEE 802.15.4 Goal: standards-complaint Zigbee-pro stack built on 802.15.4 stack Cluster-tree, mesh routing Security Application profiles:  i.e.  HVAC, Sensing
IPv6 IPv6 a good fit for sensor networks What about large header size? 6loWPAN Ideas about many important issues Management Configuration Security TEP138, draft-tavakoli-hydro-01
IPv6 BLIP: IPv6 for TinyOS Current progress: being integrated into core Useful basic feature set Mesh routing TCP/UDP Lots of tools, libraries for building apps Shell, network reprogramming, RPC, …
An IP Network “ sensor network” ≈ “IP subnet” “ TOS_NODE_ID” ≈ “IP address” “ base station” ≈ “edge router” “ application gateway” no longer exists internet backhaul links edge routers node routers
Addressing 128-bit address space Lots of IPv6 RFCs deal with this: RFC2461, RFC4862 Address type Example TinyOS usage Link-local unicast fe80::beef L2 Mapped Link-local multicast ff02::1 Radio local broadcast Global unicast 2001::64 Routable address Network ID/64 Interface ID/64
Useful Interfaces interface UDP { command error_t bind(uint16_t port); command error_t sendto(struct sockaddr_in6 *dest,    void *payload, uint16_t len); event void recvfrom(struct sockaddr_in6 *src, void *payload,  uint16_t len, struct ip_metadata *meta); } interface ICMPPing { command error_t ping(struct in6_addr *target,    uint16_t period, uint16_t n); event void pingReply(struct in6_addr *source,    struct icmp_stats *stats); event void pingDone(uint16_t ping_rcv, uint16_t ping_n); } UDPSocketC ICMPResponderC
Address Structures A lot like linux:  ip.h struct sockaddr_in6 { uint16_t sin6_port; struct in6_addr sin6_addr; };
Example App: Sense & Send event Timer.fired() { call Read.read(); } Read.readDone(error_t result, uint16_t val) { struct sockaddr_in6 dest; nx_struct report r; r.reading = val; inet_pton6(“2001::64”, &dest.sin6_addr); dest.sin6_port = htons(REPORT_PORT); call UDP.sendto(dest, &r, sizeof(r)); } Configuration MyAppC{ } implementation { components MyAppP, new UdpSocketC(); MyAppP.UDP -> UdpSocketC; ... }
Conclusions Exciting developments expected in 2009! Project links: 802.15.4:  http://tinyos.stanford.edu:8000/15.4_WG/  Zigbee:  http://www.open-zb.net/ BLIP:  http://smote.cs.berkeley.edu:8000/tracenv/wiki/blip
Hands-on Session Răzvan, Om, et al.
Goals Install TinyOS Layout of  tinyos-2.x Write two applications DisseminationDemoClient CollectionsDemoClient
Options LiveCD XubunTOS Customized Ubuntu 8.10 LiveCD Native Linux .rpm packages .deb packages Windows: Cygwin + .rpm packages MacOS X stow macports Recommended Today
Other Options VMware Jetos based on JeOS (Ubuntu Server 8.04) optimized for ssh access very small: 190MB compressed Lenny based on Debian 5.0 “Lenny” graphical interface using XFCE bigger: 300MB compressed XubunTOS
Components NesC:  nesc_*.deb Cross compiler binutils:  msp430-binutils-tinyos_*.deb gcc:  msp430-gcc-tinyos_*.deb libc:  msp430-libc-tinyos_*.deb gdb (optional) Deputy:  deputy-tinyos_*.deb
Environment export TOSROOT=$HOME/local/src/tinyos-2.xexport TOSDIR=$TOSROOT/tos export MAKERULES=$TOSROOT/support/make/Makerules export CLASSPATH=$TOSROOT/support/sdk/java/tinyos.jar:.export PYTHONPATH=$TOSROOT/support/sdk/python
Architectures AVR mica2, mica2dot micaz btnode IRIS ARM imote2 MSP430 telosb, sky shimmer eyesIFX tinynode epic 8051 CC2430 CC1110/CC1111
Layout + tinyos-2.x + apps + docs + support + tools + tos
Layout + apps + Blink + Null + RadioCountToLeds + MultihopOscilloscope + tests + ... + ... + docs + support + tools + tos
Layout + apps + docs + html + pdf + txt + ... + support + tools + tos
Layout + apps + docs + support + make - Makerules + avr/ + msp/ + ... + sdk + tools + tos
Layout + apps + docs + support + make + sdk + c + cpp + java + python + tools + tos
Layout + support + sdk + c + blip + sf + cpp + sf + java - tinyos.jar + python + tinyos - tos.py
Layout + apps + docs + support + tools + tos + chips + interfaces + lib + platforms + sensorboards + systems + types
Layout + tos + chips + atm128 + msp430 + pxa27x + cc2420 + cc1000 + at45db + stm25p + sht11 + ...
Layout + tos + chips + interfaces - Boot.nc - SplitControl.nc - StdControl.nc - ... + lib + platforms + sensorboards + systems + types
Layout + tos + lib + net + printf + timer + tosthreads + serial - SerialActiveMessageC.nc - SerialAMSenderC.nc - SerialAMReceiverC.nc - ... + ...
Layout + tos + lib + net + ctp + 4bitle + drip + Deluge + dip + blip + ...
Layout + tos + systems - AMReceiverC.nc - AMSenderC.nc - MainC.nc - LedsC.nc - TimerMilliC.nc - ...
Layout + tos + chips + interfaces + lib + platforms + sensorboards + systems + types - TinyError.h - messssage.h - ...
Applications DisseminationDemo CollectionDemo
DisseminationDemo
DisseminationDemo DisseminationDemoClient start the radio start Drip when a new value is received print its contents DisseminationDemoServer start the radio start Drip start a periodic timer on each firing or the timer increment a counter and disseminate it
DisseminationDemoClient MainC ActiveMessageC DisseminationC DisseminatorC DisseminationDemoClientC Boot SplitControl StdControl DisseminationValue <nx_uint32_t>
DisseminationDemoClient Interfaces Boot StdControl SplitControl DisseminationValue<t> Components MainC ActiveMessageC DisseminationC DisseminatorC
tos/interfaces/Boot.nc interface Boot { event void booted(); }
tos/interfaces/StdControl.nc interface StdControl { command error_t start(); command error_t stop(); }
tos/interfaces/SplitControl.nc interface SplitControl { command error_t start(); event void startDone(error_t error); command error_t stop(); event void stopDone(error_t error); }
tos/lib/net/DisseminationValue.nc interface DisseminationValue<t> { command const t* get(); command void set(const t*); event void changed(); }
tos/system/MainC.nc configuration MainC { provides interface Boot; uses interface Init as SoftwareInit; } implementation { ... }
tos/platforms/telosa/ActiveMessageC.nc configuration ActiveMessageC { provides { interface SplitControl; ... } } implementation { ... }
tos/lib/net/drip/DisseminationC.nc configuration DisseminationC { provides interface StdControl; } implementation { ... }
tos/lib/net/drip/DisseminatorC.nc generic configuration DisseminatorC(typedef t, uint16_t key) { provides interface DisseminationValue<t>; provides interface DisseminationUpdate<t>; } implementation { ... }
Makefile COMPONENT=DisseminationDemoClientAppC CFLAGS += -I%T/lib/net CFLAGS += -I%T/lib/net/drip CFLAGS += -I%T/lib/printf include $(MAKERULES)
Commands $ make telosb $ make telosb install,42 $ tos-dump.py serial@/dev/ttyUSB0:115200
Summary tos/interfaces/Boot.nc tos/interfaces/StdControl.nc tos/interfaces/SplitControl.nc tos/system/MainC.nc tos/platforms/telosa/ActiveMessageC.nc tos/lib/net/drip/DisseminationC.nc tos/lib/net/drip/DisseminatorC.nc
DisseminationDemoClientAppC.nc configuration DisseminationDemoClientAppC { } implementation { components MainC; components DisseminationC; components new DisseminatorC(nx_uint32_t, 2009); components DisseminationDemoClientC; components ActiveMessageC; DisseminationDemoClientC.Boot -> MainC; DisseminationDemoClientC.DisseminationStdControl -> DisseminationC; DisseminationDemoClientC.DisseminationValue -> DisseminatorC; DisseminationDemoClientC.RadioSplitControl -> ActiveMessageC; }
DisseminationDemoClientC.nc module DisseminationDemoClientC { uses { interface Boot; interface DisseminationValue<nx_uint32_t>; interface StdControl as DisseminationStdControl; interface SplitControl as RadioSplitControl; } } implementation { nx_uint32_t counter; event void Boot.booted() { call RadioSplitControl.start(); } ... }
DisseminationDemoClientC.nc module DisseminationDemoClientC { ... } implementation { ... event void RadioSplitControl.startDone(error_t error) { call DisseminationStdControl.start(); } event void DisseminationValue.changed() { printf(&quot;R: %lu\n&quot;, *(call DisseminationValue.get())); printfflush(); } event void RadioSplitControl.stopDone(error_t error) { } }
CollectionDemo
CollectionDemo CollectionDemoClient start the radio start CTP start a periodic timer on each firing or the timer increment a counter and sent it over CTP CollectionDemoServer start the radio start CTP when a new value is received print its contents
CollectionDemoClient MainC ActiveMessageC CollectionC CollectionSenderC CollectionDemoClientC Boot SplitControl StdControl Send TimerMilliC Timer <TMilli>
CollectionDemoClient Interfaces Boot StdControl SplitControl Send Timer<TMilli> Components MainC ActiveMessageC CollectionC CollectionSenderC TimerMilliC
CollectionDemoClient Interfaces Boot StdControl SplitControl Send Timer<TMilli> Components MainC ActiveMessageC CollectionC CollectionSenderC TimerMilliC
tos/interfaces/Send.nc interface Send { command error_t send(message_t* msg, uint8_t len); event void sendDone(message_t* msg, error_t error); command uint8_t maxPayloadLength(); command void* getPayload(message_t* msg, uint8_t len); command error_t cancel(message_t* msg); }
tos/lib/net/ctp/CollectionC.nc configuration CollectionC { provides { interface StdControl; ... } } implementation { ... }
tos/lib/net/ctp/CollectionSenderC.nc generic configuration CollectionSenderC(collection_id_t collectid) { provides { interface Send; interface Packet; } } implementation { ... }
tos/system/TimerMilliC.nc generic configuration TimerMilliC() { provides interface Timer<TMilli>; } implementation { ... }
Makefile COMPONENT=CollectionDemoClientAppC CFLAGS += -I%T/lib/net CFLAGS += -I%T/lib/net/ctp CFLAGS += -I%T/lib/net/4bitle CFLAGS += -I%T/lib/printf include $(MAKERULES)
Summary tos/interfaces/Boot.nc tos/interfaces/StdControl.nc tos/interfaces/SplitControl.nc tos/interfaces/Send.nc tos/lib/timer/Timer.nc tos/system/MainC.nc tos/system/TimerMilliC.nc tos/platforms/telosa/ActiveMessageC.nc tos/lib/net/ctp/CollectionC.nc tos/lib/net/ctp/CollectionSenderC.nc
CollectionDemoClientAppC.nc configuration CollectionDemoClientAppC { } implementation { components MainC; components ActiveMessageC; components CollectionC; components new CollectionSenderC(16); components new TimerMilliC() as Timer; components CollectionDemoClientC; CollectionDemoClientC.Boot -> MainC; CollectionDemoClientC.RadioSplitControl -> ActiveMessageC; CollectionDemoClientC.CollectionStdControl -> CollectionC; CollectionDemoClientC.Send -> CollectionSenderC; CollectionDemoClientC.Timer -> Timer; }
CollectionDemoClientC.nc module CollectionDemoClientC { uses { interface Boot; interface SplitControl as RadioSplitControl; interface StdControl as CollectionStdControl; interface Send; interface Timer<TMilli>; } } implementation { message_t smsg; typedef nx_struct { nx_uint8_t string[8]; nx_uint16_t counter; } name_t; name_t *name; ... }
CollectionDemoClientC.nc module CollectionDemoClientC { ... } implementation { ... event void Boot.booted() { name = call Send.getPayload(&smsg, sizeof(name_t)); strcpy((char*)name->string, &quot;name&quot;); name->counter = 0; call RadioSplitControl.start(); } ... }
CollectionDemoClientC.nc module CollectionDemoClientC { ... } implementation { ... event void RadioSplitControl.startDone(error_t error) { call CollectionStdControl.start(); call Timer.startPeriodic(1024); } ... }
CollectionDemoClientC.nc module CollectionDemoClientC { ... } implementation { ... event void Timer.fired() { error_t error; name->counter++; error = call Send.send(&smsg, sizeof(name_t)); printf(&quot;S: %d %d\n&quot;, name->counter, error); printfflush(); } event void Send.sendDone(message_t* msg, error_t error) { } event void RadioSplitControl.stopDone(error_t error) { } }
Code available at http://docs.tinyos.net/index.php/Ipsn2009-tutorial
The End.

More Related Content

PPTX
PPT
Tossim Accurate And Scalable Simulation Of Entire Tiny Os Applications Sensys03
PDF
Nesc tutorial
PDF
Intoduction to TinyOS, nesC and TOSSIM
PPT
Introduction to Tiny OS
PPTX
Micaz and TelosB
PDF
TinyOS Course 00: Introduction to WSN
Tossim Accurate And Scalable Simulation Of Entire Tiny Os Applications Sensys03
Nesc tutorial
Intoduction to TinyOS, nesC and TOSSIM
Introduction to Tiny OS
Micaz and TelosB
TinyOS Course 00: Introduction to WSN

What's hot (7)

PPT
Tiny os
PDF
TinyOS Course 01: Basic Programming
PPTX
Tossim
PDF
TinyOS Course 05: Advanced Protocols
PDF
TheThingsConference 2019 Slides of Alex Raimondi
PPTX
Engineering Cross-Layer Fault Tolerance in Many-Core Systems
PPTX
Rain technology seminar
Tiny os
TinyOS Course 01: Basic Programming
Tossim
TinyOS Course 05: Advanced Protocols
TheThingsConference 2019 Slides of Alex Raimondi
Engineering Cross-Layer Fault Tolerance in Many-Core Systems
Rain technology seminar
Ad

Similar to TinyOS 2.1 tutorial at IPSN 2009 (20)

PPT
0903 1
PDF
TinyOS programming 1st Edition Philip Levis
PDF
TinyOS programming 1st Edition Philip Levis
PDF
TinyOS programming 1st Edition Philip Levis
PDF
T2: What the Second Generation Holds
PDF
(Ebook) TinyOS programming by Philip Levis, David Gay ISBN 9780521896061, 052...
PDF
Tos tutorial
PPTX
Majorppt
PDF
nesC Part 1 (1).pdfbhhhhjjjjjjjjjjjjjjjjjkk
PDF
Discovering st32
PDF
EEEM048_Lecture5_Software platforms and services .pdf
PDF
Architecture 4 Wireless Sensor Networks
PDF
6. TinyOS_2.pdf
PPTX
Intel galileo gen 2
PPTX
IOT beginnners
PPTX
IOT beginnners
PDF
Tinyos programming
PDF
Intro to embedded systems programming
PPT
Lecture 5: Software platforms and services
PPTX
An Introduction to Microcontrollers part 2
0903 1
TinyOS programming 1st Edition Philip Levis
TinyOS programming 1st Edition Philip Levis
TinyOS programming 1st Edition Philip Levis
T2: What the Second Generation Holds
(Ebook) TinyOS programming by Philip Levis, David Gay ISBN 9780521896061, 052...
Tos tutorial
Majorppt
nesC Part 1 (1).pdfbhhhhjjjjjjjjjjjjjjjjjkk
Discovering st32
EEEM048_Lecture5_Software platforms and services .pdf
Architecture 4 Wireless Sensor Networks
6. TinyOS_2.pdf
Intel galileo gen 2
IOT beginnners
IOT beginnners
Tinyos programming
Intro to embedded systems programming
Lecture 5: Software platforms and services
An Introduction to Microcontrollers part 2
Ad

Recently uploaded (20)

PDF
KodekX | Application Modernization Development
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PPTX
MYSQL Presentation for SQL database connectivity
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Machine learning based COVID-19 study performance prediction
PPTX
Spectroscopy.pptx food analysis technology
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Review of recent advances in non-invasive hemoglobin estimation
PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PPTX
sap open course for s4hana steps from ECC to s4
PDF
Empathic Computing: Creating Shared Understanding
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
Approach and Philosophy of On baking technology
DOCX
The AUB Centre for AI in Media Proposal.docx
KodekX | Application Modernization Development
20250228 LYD VKU AI Blended-Learning.pptx
MYSQL Presentation for SQL database connectivity
Per capita expenditure prediction using model stacking based on satellite ima...
Machine learning based COVID-19 study performance prediction
Spectroscopy.pptx food analysis technology
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Chapter 3 Spatial Domain Image Processing.pdf
Review of recent advances in non-invasive hemoglobin estimation
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
Mobile App Security Testing_ A Comprehensive Guide.pdf
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
The Rise and Fall of 3GPP – Time for a Sabbatical?
sap open course for s4hana steps from ECC to s4
Empathic Computing: Creating Shared Understanding
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Diabetes mellitus diagnosis method based random forest with bat algorithm
Advanced methodologies resolving dimensionality complications for autism neur...
Approach and Philosophy of On baking technology
The AUB Centre for AI in Media Proposal.docx

TinyOS 2.1 tutorial at IPSN 2009

  • 1. TinyOS 2.1 IPSN 2009 Stephen Dawson-Haggerty, Omprakash Gnawali, David Gay, Philip Levis, Răzvan Musăloiu-E., Kevin Klues, and John Regehr San Francisco, CA - April 16, 2009
  • 2. Agenda 8:33: Overview (Om) 8:40: Basics (Phil and David) 9:30: TOSSIM (Razvan) 9:45: Safe TinyOS (John) 10:00: Threads (Kevin) 10:15: break 10:20: Protocols (Om) 10:40: Upcoming (Stephen) 10:50: Hands-on (Razvan, Om, et al.) 11:30: End
  • 3. What? An operating system for low power, embedded, wireless devices Wireless sensor networks (WSNs) Sensor-actuator networks Embedded robotics Open source, open developer community http://www.tinyos.net
  • 4. Who are we? Some principal developers and designers Stephen Dawson-Haggerty: network protocols David Gay: language design Omprakash Gnawali: network protocols Kevin Klues: core system Philip Levis: core system Răzvan Musăloiu-E.: network protocols John Regehr: compilation tools There are many contributors besides us, they all deserve credit
  • 5. Why? TinyOS is very powerful Modern operating system and language techniques in an embedded system A lot of libraries, support code, and community development TinyOS has a steep learning curve It can take time to use all of its capabilities Give a jump-start on high level concepts and how to write applications
  • 6. Goals Give you a high-level understanding of TinyOS’s structure and ideas Explain how to build and install applications Survey important libraries Focus on very recent additions Give you the experience of writing a networked sensing application
  • 7. Schedule 8:33: Overview (Om) 8:40: Basics (Phil and David) 9:30: TOSSIM (Razvan) 9:45: Safe TinyOS (John) 10:00: Threads (Kevin) 10:15: break 10:20: Protocols (Om) 10:40: Upcoming (Stephen) 10:50: Hands-on (Razvan, Om, et al.) 11:30: End
  • 8. Basics Philip Levis (Stanford) David Gay (Intel Research)
  • 9. Outline Components and interfaces Basic example Tasks More complex example Compiling and toolchain
  • 10. TinyOS Components TinyOS and its applications are in nesC C dialect with extra features Basic unit of nesC code is a component Components connect via interfaces Connections called “wiring” B A i
  • 11. Components A component is a file (names must match) Modules are components that have variables and executable code Configurations are components that wire other components together
  • 12. Component Example BlinkC wires BlinkP.Timer to TimerC.Timer module BlinkP { … } implementation { int c; void increment() {c++;} } configuration BlinkC { … } implementation { components new TimerC(); components BlinkC; BlinkC.Timer -> TimerC; } TimerC BlinkP Timer
  • 13. Singletons and Generics Singleton components are unique: they exist in a global namespace Generics are instantiated: each instantiation is a new, independent copy configuration BlinkC { … } implementation { components new TimerC(); components BlinkC; BlinkC.Timer -> TimerC; }
  • 14. Interfaces Collections of related functions Define how components connect Interfaces are bi-directional: for A->B Commands are from A to B Events are from B to A Can have parameters (types) interface Timer<tag> { command void startOneShot(uint32_t period); command void startPeriodic(uint32_t period); event void fired(); }
  • 15. Outline Components and interfaces Basic example Tasks More complex example Compiling and toolchain
  • 16. Basic Example Goal: write an anti-theft device. Let’s start simple. Two parts: Detecting theft. Assume: thieves put the motes in their pockets. So, a “dark” mote is a stolen mote. Every N ms check if light sensor is below some threshold Reporting theft. Assume: bright flashing lights deter thieves. Theft reporting algorithm: light the red LED for a little while! What we’ll see Basic components, interfaces, wiring Essential system interfaces for startup, timing, sensor sampling
  • 17. The Basics – Let’s Get Started module AntiTheftC { uses interface Boot; uses interface Timer<TMilli> as Check; uses interface Read<uint16_t>; } implementation { event void Boot.booted() { call Check.startPeriodic(1000); } event void Check.fired() { call Read.read(); } event void Read.readDone(error_t ok, uint16_t val) { if (ok == SUCCESS && val < 200) theftLed(); } } Components start with a signature specifying the interfaces provided by the component the interfaces used by the component A module is a component implemented in C with functions implementing commands and events and extensions to call commands, events interface Boot { /* Signaled when OS booted */ event void booted(); } interface Timer<tag> { command void startOneShot(uint32_t period); command void startPeriodic(uint32_t period); event void fired(); }
  • 18. The Basics – Split-Phase Ops module AntiTheftC { uses interface Boot; uses interface Timer<TMilli> as Check; uses interface Read<uint16_t>; } implementation { event void Boot.booted() { call Check.startPeriodic(1000); } event void Check.fired() { call Read.read(); } event void Read.readDone(error_t ok, uint16_t val) { if (ok == SUCCESS && val < 200) theftLed(); } } In TinyOS, all long-running operations are split-phase: A command starts the op: read An event signals op completion: readDone interface Read<val_t> { command error_t read(); event void readDone(error_t ok, val_t val); }
  • 19. The Basics – Split-Phase Ops module AntiTheftC { uses interface Boot; uses interface Timer<TMilli> as Check; uses interface Read<uint16_t>; } implementation { event void Boot.booted() { call Check.startPeriodic(1000); } event void Check.fired() { call Read.read(); } event void Read.readDone(error_t ok, uint16_t val) { if ( ok == SUCCESS && val < 200) theftLed(); } } In TinyOS, all long-running operations are split-phase: A command starts the op: read An event signals op completion: readDone Errors are signalled using the error_t type, typically Commands only allow one outstanding request Events report any problems occurring in the op interface Read<val_t> { command error_t read(); event void readDone(error_t ok, val_t val); }
  • 20. The Basics – Configurations configuration AntiTheftAppC { } implementation { components AntiTheftC, MainC, LedsC; AntiTheftC.Boot -> MainC.Boot; AntiTheftC.Leds -> LedsC; components new TimerMilliC() as MyTimer; AntiTheftC.Check -> MyTimer; components new PhotoC(); AntiTheftC.Read -> PhotoC; } A configuration is a component built out of other components. It wires “used” to “provided” interfaces. It can instantiate generic components It can itself provide and use interfaces generic configuration TimerMilliC() { provides interface Timer<TMilli>; } implementation { ... } generic configuration PhotoC() { provides interface Read; } implementation { ... }
  • 22. Outline Components and interfaces Basic example Tasks and concurrency More complex example Compiling and toolchain
  • 23. Tasks TinyOS has a single stack: long-running computation can reduce responsiveness Tasks: mechanism to defer computation Tells TinyOS “do this later” Tasks run to completion TinyOS scheduler runs them one by one in the order they post Keep them short! Interrupts run on stack, can post tasks
  • 24. Outline Components and interfaces Basic example Tasks and concurrency More complex example Compiling and toolchain
  • 25. More Complex Application Let’s improve our anti-theft device. A clever thief could still steal our motes by keeping a light shining on them! But the thief still needs to pick up a mote to steal it. Theft Detection Algorithm 2: Every N ms, sample acceleration at 100Hz and check if variance above some threshold What we’ll see (Relatively) high frequency sampling support Use of tasks to defer computation-intensive activities TinyOS execution model
  • 26. Advanced Sensing, Tasks uses interface ReadStream ; uint16_t accelSamples[ACCEL_SAMPLES]; event void Timer.fired() { call ReadStream.postBuffer (accelSamples, ACCEL_SAMPLES); call ReadStream.read (10000); } event void ReadStream.readDone (error_t ok, uint32_t actualPeriod) { if (ok == SUCCESS) post checkAcceleration(); } task void checkAcceleration() { ... check acceleration and report theft... } ReadStream is an interface for periodic sampling of a sensor into one or more buffers. postBuffer adds one or more buffers for sampling read starts the sampling operation readDone is signalled when the last buffer is full interface ReadStream<val_t> { command error_t postBuffer(val_t* buf, uint16_t count); command error_t read(uint32_t period); event void readDone(error_t ok, uint32_t actualPeriod); }
  • 27. Advanced Sensing, Tasks uint16_t accelSamples[SAMPLES]; event void ReadStream.readDone(error_t ok, uint32_t actualPeriod) { if (ok == SUCCESS) post checkAcceleration(); } task void checkAcceleration() { uint16_t i, avg, var; for (avg = 0, i = 0; i < SAMPLES; i++) avg += accelSamples[i]; avg /= SAMPLES; for (var = 0, i = 0; i < SAMPLES; i++) { int16_t diff = accelSamples[i] - avg; var += diff * diff; } if (var > 4 * SAMPLES) theftLed(); } In readDone, we need to compute the variance of the sample. We defer this “computationally-intensive” operation to a separate task , using post. We then compute the variance and report theft.
  • 28. TinyOS Execution Model RealMainP AccelStreamC AntiTheftC RealMainP Stack Task Queue Timer Alarm SchedulerP Interrupt table serial receive H/W timer A/D conv. AntiTheftC Timer Alarm
  • 29. TinyOS Execution Model Stack Task Queue serial receive H/W timer A/D conv. Interrupt table RealMainP AccelStreamC AntiTheftC Timer Alarm SchedulerP timer task SchedulerP Alarm Timer
  • 30. TinyOS Execution Model SchedulerP Stack Task Queue Interrupt table RealMainP AccelStreamC AntiTheftC Timer Alarm SchedulerP serial receive H/W timer A/D conv. timer task AntiTheftC AccelStreamC Timer
  • 31. Networking – “External” Types #include “antitheft.h” module AntiTheftC { ... uses interface DisseminationValue<settings_t> as SettingsValue; } implementation { settings_t settings; event void SettingsValue.changed() { const settings_t *newSettings = call SettingsValue.get(); settings.detect = newSettings->detect; settings.alert = newSettings->alert; call Check.startPeriod(newSettings->checkInterval); } event void Timer.fired() { if (settings.detect & DETECT_DARK) call Read.read(); if (settings.detect & DETECT_ACCEL) { call ReadStream.postBuffer(accelSamples, ACCEL_SAMPLES); call ReadStream.read(10000); } } #ifndef ANTITHEFT_H #define ANTITHEFT_H typedef nx_struct { nx_uint8_t alert, detect; nx_uint16_t checkInterval; } settings_t; #endif External types (nx_...) provide C-like access, but: platform-independent layout and endianness gives interoperability no alignment restrictions means they can easily be used in network buffers compiled to individual byte read/writes
  • 32. TinyOS/nesC Summary Components and Interfaces Programs built by writing and wiring components modules are components implemented in C configurations are components written by assembling other components Execution model Execution happens in a series of tasks (atomic with respect to each other) and interrupt handlers No threads System services: startup, timing, sensing (so far) (Mostly) represented by instantiatable generic components This instantiation happens at compile-time! (think C++ templates) All slow system requests are split-phase
  • 33. Outline Components and interfaces Basic example Tasks More complex example Compiling and toolchain
  • 34. The Toolchain TinyOS App PC Applications Native binary: 03 2F 77 9A F2 FF ...
  • 35. The Toolchain TinyOS PC Applications Compile TinyOS applications Native binary: 03 2F 77 9A F2 FF ... App
  • 36. The Toolchain Native binary: 03 2F 77 9A F2 FF ... TinyOS App PC Applications Install applications on motes
  • 37. The Toolchain TinyOS App PC Applications Build PC applications Native binary: 03 2F 77 9A F2 FF ...
  • 38. The Toolchain TinyOS App PC Applications Document TinyOS Native binary: 03 2F 77 9A F2 FF ...
  • 39. The “Make” System Native binary: 03 2F 77 9A F2 FF ... make telosb install automates nesC, C compilation, mote installation TinyOS App PC Applications
  • 40. “ Make”: Compile Applications ncc gcc int main() { scheduler_init(); ... } Native binary: 03 2F 77 9A F2 FF ...
  • 41. “ Make”: Install Applications pybsl, uisp, etc deluge Native binary: 03 2F 77 9A F2 FF ...
  • 42. Build PC Applications TinyOS Java, C, Python apps Packet formats, constants, etc Talk with motes Native binary: 03 2F 77 9A F2 FF ...
  • 43. PC Applications: Extracting Information from TinyOS mig ncc –dump ncg Java, C or Python app packet formats constants <the kitchen sink> TinyOS
  • 44. PC Applications: Talking to Motes Java, C or Python app sf packet libs packet libs
  • 47. What is TOSSIM? Discrete event simulator ns2
  • 48. Cycle-accurate simulators Avrora, MSPSim Alternatives
  • 49. Two directions Port make PC a supported platform Virtualize simulate one of the supported platforms TOSSIM in tinyos-2.x TOSSIM in tinyos-1.x
  • 50. Features Simulates a MicaZ mote ATmega128L (128KB ROM, 4KB RAM) CC2420 Uses CPM to model the radio noise Supports two programming interfaces: Python C++
  • 51. Anatomy TOSSIM tos/lib/tossim tos/chips/atm128/sim tos/chips/atm128/pins/sim tos/chips/atm128/timer/sim tos/chips/atm128/spi/sim tos/platforms/mica/sim tos/platforms/micaz/sim tos/platforms/micaz/chips/cc2420/sim Application Makefile *.nc *.h Simulation Driver *.py | *.cc
  • 52. Quick Overview Glue Application Simulation NesC Python C++
  • 53. The Building Process $ make micaz sim Generate an XML schema Compile the application Compile the Python support Build a share object Copying the Python support $ ./sim.py pytossim.o tossim.o c-support.o sim.o app.xml _TOSSIMmodule.o TOSSIM.py
  • 54. TOSSIM.py Tossim Radio Mote Packet Mac
  • 55. TOSSIM.Tossim .getNode() -> TOSSIM.Mote .radio() -> TOSSIM.Radio .newPacket() -> TOSSIM.Packet .mac() -> TOSSIM.Mac .runNextEvent() .ticksPerSecond() .time()
  • 56. 10 seconds from TOSSIM import * t = Tossim([]) ... while t.time() < 10*t.ticksPerSecond(): t.runNextEvent()
  • 57. dbg Syntax dbg( tag, format, arg1, arg2, ... ); Example dbg(“Trickle”, “Starting time with time %u.\n”, timerVal); Python t = Tossim([]) t.addChannel(“Trickle”, sys.stdout)
  • 58. Useful Functions typedef long long int sim_time_t ; char* sim_time_string() sim_time_t sim_time() int sim_random() sim_time_t sim_ticks_per_sec()
  • 59. Radio Model Closest-fit Pattern Matching (CPM) Improving Wireless Simulation Through Noise Modeling HyungJune Lee, Alberto Cerpa, and Philip Levis IPSN 2007
  • 60. Radio Model Sender Receiver
  • 61. Noise Level Meyer Heavy Casino Lab Signal SNR SNR
  • 63. TOSSIM.Radio .add( source, destination, gain ) .connected( source, destination ) -> True/False .gain( source, destination )
  • 64. TOSSIM.Mote .bootAtTime( time ) .addNoiseTraceReading( noise ) .createNoiseModel() .isOn() -> True/False .turnOn()/.turnOff()
  • 65. Example from TOSSIM import * t = Tossim([]) r = t.Radio() mote0 = t.getNode(0) mote1 = t.getNode(1) mote2 = t.getNode(2) r.add(0, 1, -10) r.add(1, 0, -10) r.add(1, 2, -50) r.add(2, 1, -50) 0 1 2 -50 dB -10 dB
  • 66. Example (cont) noise = file(&quot;meyer-short.txt&quot;) lines = noise.readlines() for line in lines: str = line.strip() if (str != &quot;&quot;): val = int(str) for m in [mote0, mote1, mote2]: m.addNoiseTraceReading(val) for m in [mote0, mote1, mote2]: m.createNoiseModel() 0 1 2 -50 dB -10 dB
  • 67. Other Features Injecting packets Inspecting internal variables C++ interface Debuging using gdb
  • 68. Improvements TossimLive SerialActiveMessageC CC2420sim Multiple channels PacketLink CC2420Packet: .getRSSI(), .getLQI() ReadRssi() Flash support
  • 69. Future Parametrized the PRR/SNR curve based on packet size (in progress) Support for multiple binary images (harder)
  • 70. Safe TinyOS John Regehr (Utah)
  • 71. What is Safe TinyOS? Memory safe execution for TinyOS 2.1 apps Compiler inserts safety checks These checks trap pointer / array errors before they can corrupt memory Behavior of memory-safe applications is unchanged Why use Safe TinyOS? Debugging pointer and array problems on motes can be extremely difficult
  • 72. Using Safe TinyOS Must explicitly request safe compilation $ cd tinyos-2.x/apps/BaseStation $ make micaz safe … 18544 bytes in ROM 1724 bytes in RAM $ make micaz … 14888 bytes in ROM 1724 bytes in RAM
  • 73. Designed to Fail In TinyOS 2.1: $ cd $TOSROOT/apps/tutorials/BlinkFail $ make micaz install The application dies after a few seconds BlinkFailC.nc has an obvious memory bug Next try this: $ make micaz safe install After a few seconds the mote starts blinking its LEDs in funny patterns
  • 74. FLIDs Default behavior on safety violation is to output a FLID (Fault Location IDentifier) using the LEDs A FLID is 8 digits in base-4 No LEDs lit = 0 1 LED lit = 1 2 LEDs lit = 2 3 LEDs lit = 3 A tool decodes FLIDs into error messages
  • 75. Decoding a FLID $ tos-decode-flid ./build/micaz/flids.txt 00001020 Deputy error message for flid 0x0048: BlinkFailC__a <= BlinkFailC__a + BlinkFailC__i++ + 1 (with no overflow): BlinkFailC.nc:70: Assertion failed in CPtrArithAccess: BlinkFailC__a + BlinkFailC__i++ + 1 <= BlinkFailC__a + 10 (with no overflow)
  • 76. Safe Components Safety is “opt in” at the level of nesC components This component is compiled as safe code: generic module SimpleArbiterP() @safe() { … } These components are “trusted” code: generic module SimpleArbiterP() @unsafe() { … } generic module SimpleArbiterP() { … } Trusted code is compiled w/o safety checks
  • 77. Porting Code to Safe TinyOS Recommended strategy Annotate a component as @safe() Compile application in safe mode Fix warnings / errors Repeat until no trusted components remain Arrays and pointers require annotations Annotations are for Deputy, the safe C compiler behind Safe TinyOS Purpose of annotations is to link memory regions with their bounds information
  • 78. Annotation 1 To declare msg , which always refers to a valid message_t message_t* ONE msg = ...; Or if msg may be null message_t* ONE_NOK msg; Most annotations have a _NOK form But avoid using it when possible
  • 79. Annotation 2 To declare uartQueue as an array of 10 pointers to message_t Where each element of the array must at all times refer to a valid message_t message_t* ONE uartQueue[10];
  • 80. Annotation 3 To declare reqBuf as a pointer that always points to a valid block of at least reqBytes uint8_t s: uint8_t *COUNT(reqBytes) reqBuf; Array dereferencing / pointer arithmetic can be done on reqBuf : reqBuf[0] is legal reqBuf[reqBytes-1] is legal reqBuf[reqBytes] results in a safety violation
  • 81. Annotation 4 Multiple-indirect pointers require an annotation at each level: int *ONE *ONE pp = ...; However, these are uncommon in TinyOS
  • 82. Annotation 5 If you get stuck, the “trusted cast” offers an escape hatch: cc2420_header_t* ONE x = TCAST( cc2420_header_t* ONE, (uint8_t *)msg + offsetof(message_t, data) - sizeof(cc2420_header_t) );
  • 83. Interface Annotation 1 The getPayload() command from the Packet interface might be annotated like this: command void* COUNT_NOK(len) getPayload (message_t* ONE msg, uint8_t len);
  • 84. Interface Annotation 2 However, tinyos-2.x/tos/interfaces/Packet.nc contains: * @param 'message_t* ONE msg' … * @param len … * @return 'void* COUNT_NOK(len)' … */ command void* getPayload (message_t* msg, uint8_t len); nesC allows you to put annotations in documentation comments
  • 85. Safe TinyOS Summary Safe execution is useful Safety annotations are good documentation Most Mica2, MicaZ, TelosB apps and core services are safe Safe TinyOS Tutorial: http://docs.tinyos.net/index.php/Safe_TinyOS
  • 87. The Great Divide Event-Based Execution More efficient Less RAM usage More complex Thread-Based Execution Less Efficient More RAM Usage Less Complex void myFunc() { error_t e = read(); //continue execution flow } void readDone( uint8_t val, error_t e) { //read() continuation code } void myFunc() { error_t e; uint8_t val = read(&e); //read() continuation code } TOSThreads aims to resolve this fundamental tension
  • 88. TOSThreads in a Nutshell Natural extension to the existing TinyOS concurrency model Implements Full-Fledged Threads Library Introduces Minimal Disruption to TinyOS Provides Flexible Event-based / Thread-based Code Boundary Enables Dynamic Linking and Loading of Application Binaries at Runtime Standard C and nesC based APIs
  • 89. Architecture Overview Task Scheduler Thread Scheduler System Calls TinyOS Thread Application Threads
  • 90. Blink Example (nesC) configuration BlinkAppC { } implementation { components MainC, BlinkC, LedsC; components new ThreadC(STACK_SIZE); MainC.Boot <- BlinkC; BlinkC.Thread -> ThreadC; BlinkC.Leds -> LedsC; } module BlinkC { uses { interface Boot; interface Thread; interface Leds; } } implementation { event void Boot.booted() { call Thread.start(NULL); } event void Thread.run( void * arg) { for (;;) { call Leds.led0Toggle(); call Thread.sleep(BLINK_PERIOD); } }
  • 91. Blink Example (standard C) #include &quot;tosthread.h&quot; #include &quot;tosthread_leds.h&quot; //Initialize variables associated with a thread tosthread_t blink; void blink_thread( void * arg); void tosthread_main( void * arg) { tosthread_create(&blink, blink_thread, NULL, STACK_SIZE); } void blink_thread( void * arg) { for(;;) { led0Toggle(); tosthread_sleep(BLINK_PERIOD); } }
  • 92. Modifications to TinyOS Change in boot sequence Small change is TinyOS task scheduler Additional post-amble in the interrupt sequence
  • 93. Boot Sequence event void TinyOS.booted() { atomic { platform_bootstrap(); call Scheduler.init(); call PlatformInit.init(); while (call Scheduler.runNextTask()); call SoftwareInit.init(); while (call Scheduler.runNextTask()); } signal Boot.booted(); /* Spin in the Scheduler */ call Scheduler.taskLoop(); } Standard TinyOS Boot Main int main() { signal TinyOS.booted(); //Should never get here return -1; }
  • 94. Boot Sequence event void ThreadScheduler.booted() { setup_TinyOS_in_kernel_thread(); signal TinyOSBoot.booted(); } Thread Scheduler Boot New Main int main() { signal ThreadScheduler.booted(); //Should never get here return -1; }
  • 95. Task Scheduler command void Scheduler.taskLoop() { for (;;) { uint8_t nextTask; atomic { while ((nextTask = popTask()) == NO_TASK)) call McuSleep.sleep(); } signal TaskBasic.runTask[nextTask](); } } Original command void Scheduler.taskLoop() { for (;;) { uint8_t nextTask; atomic { while ((nextTask = popTask()) == NO_TASK) call ThreadScheduler.suspendThread(TOS_THREAD_ID); } signal TaskBasic.runTask[nextTask](); } } New
  • 96. Interrupt Handlers void interruptCurrentThread() { if ( call TaskScheduler.hasTasks() ) { call ThreadScheduler.wakeupThread(TOS_THREAD_ID); call ThreadScheduler.interruptCurrentThread(); } } TOSH_SIGNAL (ADC_VECTOR) { signal SIGNAL_ADC_VECTOR.fired(); atomic interruptCurrentThread(); } TOSH_SIGNAL (DACDMA_VECTOR) { signal SIGNAL_DACDMA_VECTOR.fired(); atomic interruptCurrentThread(); } … . … .
  • 97. System Calls Task Queue Routing Arbiter System Call Task Receive Timer Send Receive Sense Block Storage Application Thread System Calls TinyOS Thread
  • 98. Linking and Loading Full applications written in standard C Custom MicroExe format Multiple concurrently running applications Generic TinyLD component supporting multiple APIs
  • 99. Resources TOSThreads Tutorial http://docs.tinyos.net/index.php/TOSThreads_Tutorial TOSThreads TEP http://www.tinyos.net/tinyos-2.x/doc/html/tep134.html Source Code System code: tinyos-2.x/tos/lib/tosthreads Example Applications: tinyos-2.x/apps/tosthreads
  • 101. Protocols in TinyOS 2.1 Network Protocols Collection: CTP, MultihopLQI Dissemination: Drip, DIP Time Synchronization (FTSP) Over-the-air programming (Deluge)
  • 102. Collection Collect data from the network to one or a small number of roots One of many traffic classes Available: MultihopLQI and CTP
  • 103. MultihopLQI Mostly tested and used on platforms with CC2420 MicaZ, TelosB, … Small code footprint tos/lib/net/lqi
  • 104. CTP Platform independent More consistent performance than with MultihopLQI Code footprint can be a concern tos/lib/net/ctp
  • 105. CTP Architecture Router Forwarder Lnk Estimator Link Layer Application
  • 106. CTP Link Estimator Platform independent Beacons and data packets Bi-directional ETX estimate Does not originate beacons itself Accurate but also agile
  • 107. CTP Router ETX path metric Beacon interval can be 64 ms-x mins Select new path if better by at least 1.5 ETX Alternate parents
  • 108. CTP Forwarder Duplicate suppression Retransmissions Loops trigger route updates Forward through alternate parents
  • 110. Dissemination Send data to all the nodes Commands, configuration parameters Efficient and fast Available protocols – Drip and DIP
  • 111. Drip Fast and efficient for small number of items Trickle timers for advertisements Suppression tos/lib/net/drip
  • 112. DIP Efficiently Disseminates large number of items (can not fit in one packet) Use hashes and version vectors to detect and identify updates to the values tos/lib/net/dip
  • 113. Deluge Over-the-air programming Disseminates code Programs the nodes
  • 114. Deluge Details Supports Tmote Sky/EPIC and MicaZ. Bulk dissemination on top of Drip Python tools Support for MIB600. (new) tos/lib/net/Deluge, tos/lib/tosboot
  • 115. Time Synchronization Global time on all the nodes Node with smallest id becomes the root Flooding Time Synchronization Protocol (FTSP) tos/lib/ftsp
  • 116. Upcoming Technologies Stephen Dawson-Haggerty (UCB)
  • 117. “ Work in Progress” Proceeding in working groups IEEE 802.15.4 Zigbee 6lowpan/IPv6 Overall theme: leverage emerging standards
  • 118. IEEE 802.15.4 PHY/MAC specification MAC under development by working group CSMA-CA GTS Slotted CSMA-CA Application interface in flux More reading: tos/lib/mac/tkn154 http://www.tkn.tu-berlin.de/publications/papers/TKN154.pdf
  • 119. ZigBee Network protocol and application stack built on IEEE 802.15.4 Goal: standards-complaint Zigbee-pro stack built on 802.15.4 stack Cluster-tree, mesh routing Security Application profiles: i.e. HVAC, Sensing
  • 120. IPv6 IPv6 a good fit for sensor networks What about large header size? 6loWPAN Ideas about many important issues Management Configuration Security TEP138, draft-tavakoli-hydro-01
  • 121. IPv6 BLIP: IPv6 for TinyOS Current progress: being integrated into core Useful basic feature set Mesh routing TCP/UDP Lots of tools, libraries for building apps Shell, network reprogramming, RPC, …
  • 122. An IP Network “ sensor network” ≈ “IP subnet” “ TOS_NODE_ID” ≈ “IP address” “ base station” ≈ “edge router” “ application gateway” no longer exists internet backhaul links edge routers node routers
  • 123. Addressing 128-bit address space Lots of IPv6 RFCs deal with this: RFC2461, RFC4862 Address type Example TinyOS usage Link-local unicast fe80::beef L2 Mapped Link-local multicast ff02::1 Radio local broadcast Global unicast 2001::64 Routable address Network ID/64 Interface ID/64
  • 124. Useful Interfaces interface UDP { command error_t bind(uint16_t port); command error_t sendto(struct sockaddr_in6 *dest, void *payload, uint16_t len); event void recvfrom(struct sockaddr_in6 *src, void *payload, uint16_t len, struct ip_metadata *meta); } interface ICMPPing { command error_t ping(struct in6_addr *target, uint16_t period, uint16_t n); event void pingReply(struct in6_addr *source, struct icmp_stats *stats); event void pingDone(uint16_t ping_rcv, uint16_t ping_n); } UDPSocketC ICMPResponderC
  • 125. Address Structures A lot like linux: ip.h struct sockaddr_in6 { uint16_t sin6_port; struct in6_addr sin6_addr; };
  • 126. Example App: Sense & Send event Timer.fired() { call Read.read(); } Read.readDone(error_t result, uint16_t val) { struct sockaddr_in6 dest; nx_struct report r; r.reading = val; inet_pton6(“2001::64”, &dest.sin6_addr); dest.sin6_port = htons(REPORT_PORT); call UDP.sendto(dest, &r, sizeof(r)); } Configuration MyAppC{ } implementation { components MyAppP, new UdpSocketC(); MyAppP.UDP -> UdpSocketC; ... }
  • 127. Conclusions Exciting developments expected in 2009! Project links: 802.15.4: http://tinyos.stanford.edu:8000/15.4_WG/ Zigbee: http://www.open-zb.net/ BLIP: http://smote.cs.berkeley.edu:8000/tracenv/wiki/blip
  • 129. Goals Install TinyOS Layout of tinyos-2.x Write two applications DisseminationDemoClient CollectionsDemoClient
  • 130. Options LiveCD XubunTOS Customized Ubuntu 8.10 LiveCD Native Linux .rpm packages .deb packages Windows: Cygwin + .rpm packages MacOS X stow macports Recommended Today
  • 131. Other Options VMware Jetos based on JeOS (Ubuntu Server 8.04) optimized for ssh access very small: 190MB compressed Lenny based on Debian 5.0 “Lenny” graphical interface using XFCE bigger: 300MB compressed XubunTOS
  • 132. Components NesC: nesc_*.deb Cross compiler binutils: msp430-binutils-tinyos_*.deb gcc: msp430-gcc-tinyos_*.deb libc: msp430-libc-tinyos_*.deb gdb (optional) Deputy: deputy-tinyos_*.deb
  • 133. Environment export TOSROOT=$HOME/local/src/tinyos-2.xexport TOSDIR=$TOSROOT/tos export MAKERULES=$TOSROOT/support/make/Makerules export CLASSPATH=$TOSROOT/support/sdk/java/tinyos.jar:.export PYTHONPATH=$TOSROOT/support/sdk/python
  • 134. Architectures AVR mica2, mica2dot micaz btnode IRIS ARM imote2 MSP430 telosb, sky shimmer eyesIFX tinynode epic 8051 CC2430 CC1110/CC1111
  • 135. Layout + tinyos-2.x + apps + docs + support + tools + tos
  • 136. Layout + apps + Blink + Null + RadioCountToLeds + MultihopOscilloscope + tests + ... + ... + docs + support + tools + tos
  • 137. Layout + apps + docs + html + pdf + txt + ... + support + tools + tos
  • 138. Layout + apps + docs + support + make - Makerules + avr/ + msp/ + ... + sdk + tools + tos
  • 139. Layout + apps + docs + support + make + sdk + c + cpp + java + python + tools + tos
  • 140. Layout + support + sdk + c + blip + sf + cpp + sf + java - tinyos.jar + python + tinyos - tos.py
  • 141. Layout + apps + docs + support + tools + tos + chips + interfaces + lib + platforms + sensorboards + systems + types
  • 142. Layout + tos + chips + atm128 + msp430 + pxa27x + cc2420 + cc1000 + at45db + stm25p + sht11 + ...
  • 143. Layout + tos + chips + interfaces - Boot.nc - SplitControl.nc - StdControl.nc - ... + lib + platforms + sensorboards + systems + types
  • 144. Layout + tos + lib + net + printf + timer + tosthreads + serial - SerialActiveMessageC.nc - SerialAMSenderC.nc - SerialAMReceiverC.nc - ... + ...
  • 145. Layout + tos + lib + net + ctp + 4bitle + drip + Deluge + dip + blip + ...
  • 146. Layout + tos + systems - AMReceiverC.nc - AMSenderC.nc - MainC.nc - LedsC.nc - TimerMilliC.nc - ...
  • 147. Layout + tos + chips + interfaces + lib + platforms + sensorboards + systems + types - TinyError.h - messssage.h - ...
  • 150. DisseminationDemo DisseminationDemoClient start the radio start Drip when a new value is received print its contents DisseminationDemoServer start the radio start Drip start a periodic timer on each firing or the timer increment a counter and disseminate it
  • 151. DisseminationDemoClient MainC ActiveMessageC DisseminationC DisseminatorC DisseminationDemoClientC Boot SplitControl StdControl DisseminationValue <nx_uint32_t>
  • 152. DisseminationDemoClient Interfaces Boot StdControl SplitControl DisseminationValue<t> Components MainC ActiveMessageC DisseminationC DisseminatorC
  • 153. tos/interfaces/Boot.nc interface Boot { event void booted(); }
  • 154. tos/interfaces/StdControl.nc interface StdControl { command error_t start(); command error_t stop(); }
  • 155. tos/interfaces/SplitControl.nc interface SplitControl { command error_t start(); event void startDone(error_t error); command error_t stop(); event void stopDone(error_t error); }
  • 156. tos/lib/net/DisseminationValue.nc interface DisseminationValue<t> { command const t* get(); command void set(const t*); event void changed(); }
  • 157. tos/system/MainC.nc configuration MainC { provides interface Boot; uses interface Init as SoftwareInit; } implementation { ... }
  • 158. tos/platforms/telosa/ActiveMessageC.nc configuration ActiveMessageC { provides { interface SplitControl; ... } } implementation { ... }
  • 159. tos/lib/net/drip/DisseminationC.nc configuration DisseminationC { provides interface StdControl; } implementation { ... }
  • 160. tos/lib/net/drip/DisseminatorC.nc generic configuration DisseminatorC(typedef t, uint16_t key) { provides interface DisseminationValue<t>; provides interface DisseminationUpdate<t>; } implementation { ... }
  • 161. Makefile COMPONENT=DisseminationDemoClientAppC CFLAGS += -I%T/lib/net CFLAGS += -I%T/lib/net/drip CFLAGS += -I%T/lib/printf include $(MAKERULES)
  • 162. Commands $ make telosb $ make telosb install,42 $ tos-dump.py serial@/dev/ttyUSB0:115200
  • 163. Summary tos/interfaces/Boot.nc tos/interfaces/StdControl.nc tos/interfaces/SplitControl.nc tos/system/MainC.nc tos/platforms/telosa/ActiveMessageC.nc tos/lib/net/drip/DisseminationC.nc tos/lib/net/drip/DisseminatorC.nc
  • 164. DisseminationDemoClientAppC.nc configuration DisseminationDemoClientAppC { } implementation { components MainC; components DisseminationC; components new DisseminatorC(nx_uint32_t, 2009); components DisseminationDemoClientC; components ActiveMessageC; DisseminationDemoClientC.Boot -> MainC; DisseminationDemoClientC.DisseminationStdControl -> DisseminationC; DisseminationDemoClientC.DisseminationValue -> DisseminatorC; DisseminationDemoClientC.RadioSplitControl -> ActiveMessageC; }
  • 165. DisseminationDemoClientC.nc module DisseminationDemoClientC { uses { interface Boot; interface DisseminationValue<nx_uint32_t>; interface StdControl as DisseminationStdControl; interface SplitControl as RadioSplitControl; } } implementation { nx_uint32_t counter; event void Boot.booted() { call RadioSplitControl.start(); } ... }
  • 166. DisseminationDemoClientC.nc module DisseminationDemoClientC { ... } implementation { ... event void RadioSplitControl.startDone(error_t error) { call DisseminationStdControl.start(); } event void DisseminationValue.changed() { printf(&quot;R: %lu\n&quot;, *(call DisseminationValue.get())); printfflush(); } event void RadioSplitControl.stopDone(error_t error) { } }
  • 168. CollectionDemo CollectionDemoClient start the radio start CTP start a periodic timer on each firing or the timer increment a counter and sent it over CTP CollectionDemoServer start the radio start CTP when a new value is received print its contents
  • 169. CollectionDemoClient MainC ActiveMessageC CollectionC CollectionSenderC CollectionDemoClientC Boot SplitControl StdControl Send TimerMilliC Timer <TMilli>
  • 170. CollectionDemoClient Interfaces Boot StdControl SplitControl Send Timer<TMilli> Components MainC ActiveMessageC CollectionC CollectionSenderC TimerMilliC
  • 171. CollectionDemoClient Interfaces Boot StdControl SplitControl Send Timer<TMilli> Components MainC ActiveMessageC CollectionC CollectionSenderC TimerMilliC
  • 172. tos/interfaces/Send.nc interface Send { command error_t send(message_t* msg, uint8_t len); event void sendDone(message_t* msg, error_t error); command uint8_t maxPayloadLength(); command void* getPayload(message_t* msg, uint8_t len); command error_t cancel(message_t* msg); }
  • 173. tos/lib/net/ctp/CollectionC.nc configuration CollectionC { provides { interface StdControl; ... } } implementation { ... }
  • 174. tos/lib/net/ctp/CollectionSenderC.nc generic configuration CollectionSenderC(collection_id_t collectid) { provides { interface Send; interface Packet; } } implementation { ... }
  • 175. tos/system/TimerMilliC.nc generic configuration TimerMilliC() { provides interface Timer<TMilli>; } implementation { ... }
  • 176. Makefile COMPONENT=CollectionDemoClientAppC CFLAGS += -I%T/lib/net CFLAGS += -I%T/lib/net/ctp CFLAGS += -I%T/lib/net/4bitle CFLAGS += -I%T/lib/printf include $(MAKERULES)
  • 177. Summary tos/interfaces/Boot.nc tos/interfaces/StdControl.nc tos/interfaces/SplitControl.nc tos/interfaces/Send.nc tos/lib/timer/Timer.nc tos/system/MainC.nc tos/system/TimerMilliC.nc tos/platforms/telosa/ActiveMessageC.nc tos/lib/net/ctp/CollectionC.nc tos/lib/net/ctp/CollectionSenderC.nc
  • 178. CollectionDemoClientAppC.nc configuration CollectionDemoClientAppC { } implementation { components MainC; components ActiveMessageC; components CollectionC; components new CollectionSenderC(16); components new TimerMilliC() as Timer; components CollectionDemoClientC; CollectionDemoClientC.Boot -> MainC; CollectionDemoClientC.RadioSplitControl -> ActiveMessageC; CollectionDemoClientC.CollectionStdControl -> CollectionC; CollectionDemoClientC.Send -> CollectionSenderC; CollectionDemoClientC.Timer -> Timer; }
  • 179. CollectionDemoClientC.nc module CollectionDemoClientC { uses { interface Boot; interface SplitControl as RadioSplitControl; interface StdControl as CollectionStdControl; interface Send; interface Timer<TMilli>; } } implementation { message_t smsg; typedef nx_struct { nx_uint8_t string[8]; nx_uint16_t counter; } name_t; name_t *name; ... }
  • 180. CollectionDemoClientC.nc module CollectionDemoClientC { ... } implementation { ... event void Boot.booted() { name = call Send.getPayload(&smsg, sizeof(name_t)); strcpy((char*)name->string, &quot;name&quot;); name->counter = 0; call RadioSplitControl.start(); } ... }
  • 181. CollectionDemoClientC.nc module CollectionDemoClientC { ... } implementation { ... event void RadioSplitControl.startDone(error_t error) { call CollectionStdControl.start(); call Timer.startPeriodic(1024); } ... }
  • 182. CollectionDemoClientC.nc module CollectionDemoClientC { ... } implementation { ... event void Timer.fired() { error_t error; name->counter++; error = call Send.send(&smsg, sizeof(name_t)); printf(&quot;S: %d %d\n&quot;, name->counter, error); printfflush(); } event void Send.sendDone(message_t* msg, error_t error) { } event void RadioSplitControl.stopDone(error_t error) { } }
  • 183. Code available at http://docs.tinyos.net/index.php/Ipsn2009-tutorial