Upload
wilton
View
42
Download
0
Embed Size (px)
DESCRIPTION
Programming Sensor Networks. David Gay Intel Research Berkeley. Object tracking Sensors take magnetometer readings, locate object using centroid of readings Communicate using geographic routing to base station Robust against node and link failures. Environmental monitoring - PowerPoint PPT Presentation
Citation preview
Programming Programming Sensor NetworksSensor Networks
David GayIntel Research Berkeley
Object trackingObject tracking Sensors take magnetometer readings, locate Sensors take magnetometer readings, locate
object using centroid of readingsobject using centroid of readings Communicate using geographic routing to base Communicate using geographic routing to base
stationstation Robust against node and link failuresRobust against node and link failures
Environmental monitoringEnvironmental monitoring Gather temperature, humidity, light from a Gather temperature, humidity, light from a
redwood treeredwood tree Communicate using tree routing to base stationCommunicate using tree routing to base station 33 nodes, 44 days33 nodes, 44 days
Challenges and Challenges and RequirementsRequirements
ExpressivityExpressivity Many applications, many OS services, many hardware Many applications, many OS services, many hardware
devicesdevices
Real-time requirementsReal-time requirements Some time-critical tasks (sensor acquisition and radio Some time-critical tasks (sensor acquisition and radio
timing)timing)
Constant hardware evolutionConstant hardware evolutionReliabilityReliability
Apps run for months/years without human Apps run for months/years without human interventionintervention
Extremely limited resourcesExtremely limited resources Very low cost, size, and power consumptionVery low cost, size, and power consumption
ReprogrammabilityReprogrammability““Easy” programmingEasy” programming
used by non-CS-experts, e.g., scientistsused by non-CS-experts, e.g., scientists
Recurring ExampleRecurring Example
Multi-hop data collectionMulti-hop data collection Motes form a spanning tree rooted at a base Motes form a spanning tree rooted at a base
station nodestation node Motes periodically sample one or more sensorsMotes periodically sample one or more sensors Motes perform some local processing, then send Motes perform some local processing, then send
sensor data to parent in treesensor data to parent in tree Parents either process receivedParents either process received
data (aggregation) or forwarddata (aggregation) or forwardit as isit as is
Programming the Hard Programming the Hard WayWay
AssemblerC compiler
““The Real Programmer’s” The Real Programmer’s” ScorecardScorecard
ExpressivityExpressivity
Real-time requirementsReal-time requirements
Constant hardware evolutionConstant hardware evolution
ReliabilityReliability
Extremely limited resourcesExtremely limited resources
ReprogrammabilityReprogrammability
““Easy” programmingEasy” programming
Programming the Hard Programming the Hard WayWay
AssemblerC compiler
3 Practical Programming 3 Practical Programming SystemsSystems
nesCnesC A C dialect designed to address sensor network A C dialect designed to address sensor network
challengeschallenges Used to implement TinyOS, Maté, TinySQL (TinyDB)Used to implement TinyOS, Maté, TinySQL (TinyDB)
MatéMaté An infrastructure for building virtual machinesAn infrastructure for building virtual machines Provide safe, efficient high-level programming Provide safe, efficient high-level programming
environmentsenvironments Several programming models: simple scripts, Several programming models: simple scripts,
Scheme, TinySQLScheme, TinySQL
TinySQLTinySQL A sensor network query languageA sensor network query language Simple, well-adapted to data-collection applicationsSimple, well-adapted to data-collection applications
nesC overviewnesC overviewComponent-based C dialectComponent-based C dialect
All cross-component interaction via All cross-component interaction via interfacesinterfaces
Connections specified at compile-timeConnections specified at compile-time
Simple, non-blocking execution modelSimple, non-blocking execution model TasksTasks
Run-to-completionRun-to-completion Atomic with respect to each otherAtomic with respect to each other
Interrupt handlersInterrupt handlers Run-to-completionRun-to-completion
““Whole program”Whole program”Reduced expressivityReduced expressivity
No dynamic allocationNo dynamic allocation No function pointersNo function pointers
nesC component modelnesC component model
module AppM {module AppM { provides interface provides interface InitInit;; uses interface uses interface ADCADC;; uses interface uses interface TimerTimer;; uses interface uses interface SendSend;;}}implementation {implementation { … …}}
interface interface InitInit { { command bool init();command bool init();}}
A call to a command, such as: bool ok = call Init.init();is a function-call to behaviour provided by some component (e.g., AppM).
nesC component modelnesC component model
module AppM {module AppM { provides interface provides interface InitInit;; uses interface uses interface ADCADC;; uses interface uses interface TimerTimer;; uses interface uses interface SendSend;;}}implementation {implementation { … …}}
interface interface InitInit { { command bool init();command bool init();}}
interface interface ADCADC { { command void getData();command void getData(); event void dataReady(int data);event void dataReady(int data);}}
Interfaces are bi-directional. AppM can call ADC.getData and must implement event void ADC.dataReady(int data) { … }The component to which ADC is connected will signal dataReady, resulting in a function-call to ADC.dataReady in AppM.
nesC component modelnesC component model
module AppM {module AppM { provides interface provides interface InitInit;; uses interface uses interface ADCADC;; uses interface uses interface TimerTimer;; uses interface uses interface SendSend;;}}implementation {implementation { TOS_Msg myMsg;TOS_Msg myMsg; int busy;int busy;
event void ADC.dataReady()event void ADC.dataReady() {{ call Send.send(&myMsg);call Send.send(&myMsg); busy = TRUE;busy = TRUE; }} ......}}
interface interface InitInit { { command bool init();command bool init();}}
interface interface ADCADC { { command void getData();command void getData(); event void dataReady(int data);event void dataReady(int data);}}
interface interface TimerTimer { { command void setRate(int rate);command void setRate(int rate); event void fired();event void fired();}}
interface interface SendSend { { command void send(TOS_Msg *m);command void send(TOS_Msg *m); event void sendDone();event void sendDone();}}
components Main, AppM, components Main, AppM, TimerC, Photo, MessageQueue;TimerC, Photo, MessageQueue; Main.Init -> AppM.Init;Main.Init -> AppM.Init;
configuration App { }configuration App { }implementation {implementation {
}}
AppM.Timer -> TimerC.Timer;AppM.Timer -> TimerC.Timer; Main.Init -> TimerC.Init;Main.Init -> TimerC.Init;
… …
TimerC
AppM
Main
MessageQueuePhoto
nesC component modelnesC component modelmodule AppM {module AppM { provides interface Init;provides interface Init; uses interface ADC;uses interface ADC; uses interface Timer;uses interface Timer; uses interface Send;uses interface Send;} …} …
InitInit
Init
Timer
Timer
ADC Send
ADC Send
Some Other FeaturesSome Other FeaturesParameterised interfaces, generic interfacesParameterised interfaces, generic interfaces
interface ADC[int id]: runtime dispatch between interface ADC[int id]: runtime dispatch between interfacesinterfaces
interface Attribute<t>: type parameter to interfaceinterface Attribute<t>: type parameter to interface
Generic components (allocated at compile-time)Generic components (allocated at compile-time) Reusable components with arguments:Reusable components with arguments:
generic module Queue(typedef t, int size) …generic module Queue(typedef t, int size) … Generic configurations can instantiate many Generic configurations can instantiate many
components at oncecomponents at once
Distributed identifier “allocation”Distributed identifier “allocation” unique(“some string”): returns a different number at unique(“some string”): returns a different number at
each use with the same string, from a contiguous each use with the same string, from a contiguous sequence starting at 0sequence starting at 0
uniqueCount(“some string”): returns the number of uses uniqueCount(“some string”): returns the number of uses of unique(“some string”)of unique(“some string”)
Concurrency supportConcurrency support Atomic sections, compile-time data-race detectionAtomic sections, compile-time data-race detection
nesC ScorecardnesC Scorecard
ExpressivityExpressivity Subsystems: radio stack, routing, timers, Subsystems: radio stack, routing, timers,
sensors, etcsensors, etc Applications: data collection, TinyDB, Nest final Applications: data collection, TinyDB, Nest final
experiment, etcexperiment, etc
Constant hardware evolutionConstant hardware evolution René René Mica Mica Mica2 Mica2 MicaZ; Telos (x3) MicaZ; Telos (x3) Many other platforms at other institutionsMany other platforms at other institutions
How was this achieved?How was this achieved? The component model helps a lot, especially The component model helps a lot, especially
when used following particular when used following particular patternspatterns
nesC ScorecardnesC ScorecardExpressivityExpressivity
Subsystems: radio stack, routing, timers, sensors, etcSubsystems: radio stack, routing, timers, sensors, etc Applications: data collection, TinyDB, Nest final Applications: data collection, TinyDB, Nest final
experiment, etcexperiment, etc
Constant hardware evolutionConstant hardware evolution René René Mica Mica Mica2 Mica2 MicaZ; Telos (x3) MicaZ; Telos (x3) Many other platforms at other institutionsMany other platforms at other institutions
How was this achieved?How was this achieved? The component model helps a lot, especially when The component model helps a lot, especially when
used following particular used following particular patternspatterns Placeholder: allow easy, application-wide selection of a Placeholder: allow easy, application-wide selection of a
particular service implementationparticular service implementation Adapter: adapt an old component to a new interfaceAdapter: adapt an old component to a new interface
Placeholder:Placeholder: allow easy, application-wide selection of a particular allow easy, application-wide selection of a particular
service implementationservice implementation
MotivationMotivation services have multiple compatible implementationsservices have multiple compatible implementations
routing ex: MintRoute, ReliableRoute; hardware independence routing ex: MintRoute, ReliableRoute; hardware independence layerslayers
used in several parts of system, applicationused in several parts of system, application ex: routing used in network management and data collectionex: routing used in network management and data collection
most code should specify abstract service, not specific most code should specify abstract service, not specific versionversion
application selects implementation in one placeapplication selects implementation in one place
Router
Init
Route
Main
Data Collection
Management
MRouteReliableRoute
Placeholder:Placeholder: allow easy, application-wide selection of a particular allow easy, application-wide selection of a particular
service implementationservice implementation
configuration Router {configuration Router { provides Init;provides Init; provides Route;provides Route; uses Init as XInit;uses Init as XInit; uses Route as XRoute;uses Route as XRoute;} implementation {} implementation { Init = XInit;Init = XInit; Route = XRoute;Route = XRoute;}}
Router
Init
Route
Main
Data Collection
Management
MRoute
configuration App { } configuration App { } implementation {implementation { components Router, MRoute;components Router, MRoute;
Router.XInit -> MRoute.Init;Router.XInit -> MRoute.Init; Router.XRoute -> MRoute.Route;Router.XRoute -> MRoute.Route; … …}}
Adapter:Adapter: adapt an old component to a new interfaceadapt an old component to a new interface
MotivationMotivation functionality offered by a component with one
interface needed needs to be accessed by another component via a different interface.
AttrPhotoTinyDB LightAttribute ADC
Adapter:Adapter: adapt an old component to a new interfaceadapt an old component to a new interface
AttrPhotoTinyDB LightAttribute ADC
generic module AdaptAdcCgeneric module AdaptAdcC (char *name, typedef t) {(char *name, typedef t) { provides Attribute<t>;provides Attribute<t>; provides Init;provides Init; uses ADC;uses ADC;} implementation {} implementation { command void Init.init() {command void Init.init() { call Attribute.register(name);call Attribute.register(name); }} command void Attribute.get() {command void Attribute.get() { call ADC.get();call ADC.get(); }} … …}}
configuration AttrPhoto {configuration AttrPhoto { provides Attribute<long>;provides Attribute<long>;}}implementation {implementation { components Light,components Light, new AdaptAdcC(“Photo”, long);new AdaptAdcC(“Photo”, long); Attribute = AdaptAdcC;Attribute = AdaptAdcC; AdaptAdcC.ADC -> Light;AdaptAdcC.ADC -> Light;}}
nesC scorecardnesC scorecard
ExpressivityExpressivity
Constant hardware evolutionConstant hardware evolution
Real-time requirements (Real-time requirements (soft onlysoft only)) Radio stack, especially earlier bit/byte radiosRadio stack, especially earlier bit/byte radios Time synchronisationTime synchronisation High-frequency samplingHigh-frequency sampling
Achieved throughAchieved through Running a single applicationRunning a single application Having full control over the OS (cf Placeholder)Having full control over the OS (cf Placeholder)
nesC scorecardnesC scorecard
ExpressivityExpressivity
Constant hardware evolutionConstant hardware evolution
Real-time requirements (Real-time requirements (soft onlysoft only))
ReliabilityReliability C is an unsafe languageC is an unsafe language Concurrency is trickyConcurrency is tricky
Addressed throughAddressed through A static programming style, e.g., the Service A static programming style, e.g., the Service
Instance patternInstance pattern Compile-time checks such as data-race detectionCompile-time checks such as data-race detection
Timer
Clock
Service Instance:Service Instance: support multiple instances with efficient support multiple instances with efficient
collaborationcollaboration
MotivationMotivation multiple users need independent instance of servicemultiple users need independent instance of service
ex: timers, file descriptorsex: timers, file descriptors services instances need to coordinate, e.g., for services instances need to coordinate, e.g., for
efficiencyefficiency ex: ex: nn timers sharing single underlying hardware timer timers sharing single underlying hardware timer
Data Collection
Radio
timer0timer1
MRoute
timer2
Service Instance:Service Instance: support multiple instances with efficient support multiple instances with efficient
collaborationcollaboration
module TimerP {module TimerP { provides Timer[int id];provides Timer[int id]; uses Clock;uses Clock;}}implementation {implementation { timer_t timers[uniqueCount(“Timer”)];timer_t timers[uniqueCount(“Timer”)]; command Timer.start[int id](…) { … }command Timer.start[int id](…) { … }}}
Timer
Clock
Data Collection
Radiotimer0timer1
generic configuration TimerC() {generic configuration TimerC() { provides interface Timer;provides interface Timer;}}implementation {implementation { components TimerP;components TimerP; Timer = TimerP.Timer[unique(“Timer”)];Timer = TimerP.Timer[unique(“Timer”)];}}
components Radio, TimerC;components Radio, TimerC; Radio.Timer –> new TimerC();Radio.Timer –> new TimerC();
Race condition exampleRace condition examplemodule AppM { … }module AppM { … }
implementation {implementation {
bool busy;bool busy;
asyncasync event void Timer.fired() { event void Timer.fired() {
// Avoid concurrent data collection attempts!// Avoid concurrent data collection attempts!
if (!busy) { if (!busy) { //// Concurrent state access Concurrent state access
busy = TRUE; busy = TRUE; // // Concurrent state access Concurrent state access
call ADC.getData();call ADC.getData();
}}
}}
… …
}}
Data race detectionData race detection
Every concurrent state access is a potential Every concurrent state access is a potential race conditionrace condition
Concurrent state access:Concurrent state access: If object O is accessed in a function reachable from If object O is accessed in a function reachable from
an interrupt entry point, then all accesses to O are an interrupt entry point, then all accesses to O are potential race conditionspotential race conditions
All concurrent state accesses must occur in All concurrent state accesses must occur in atomicatomic statementsstatements
Concurrent state access detection is Concurrent state access detection is straightforward:straightforward:
Call graph fully specified by configurationsCall graph fully specified by configurations Interrupt entry points are knownInterrupt entry points are known Data model is simple (variables only)Data model is simple (variables only)
Data race fixedData race fixedmodule AppM { … }module AppM { … }implementation {implementation { bool busy;bool busy; async event void Timer.fired() { // From interruptasync event void Timer.fired() { // From interrupt // Avoid concurrent data collection attempts!// Avoid concurrent data collection attempts! bool localBusy;bool localBusy; atomicatomic { { localBusy = busy;localBusy = busy; busy = TRUE;busy = TRUE; }} if (!localBusy)if (!localBusy) call ADC.getData();call ADC.getData(); }}
nesC scorecardnesC scorecard
ExpressivityExpressivity
Constant hardware evolutionConstant hardware evolution
Real-time requirements (Real-time requirements (soft onlysoft only))
ReliabilityReliability
Extremely limited resourcesExtremely limited resources Complex applications exist: NEST FE, TinyScheme, Complex applications exist: NEST FE, TinyScheme,
TinyDBTinyDB Lifetimes of several months achievedLifetimes of several months achieved
How?How? Language features: resolve “wiring” at compile-timeLanguage features: resolve “wiring” at compile-time Compiler features: inlining, dead-code eliminationCompiler features: inlining, dead-code elimination And, of course, clever researchers and hackersAnd, of course, clever researchers and hackers
Resource UsageResource Usage
An interpreter specialised for data-collectionAn interpreter specialised for data-collection Makes heavy use of components, patternsMakes heavy use of components, patterns
Optimisation reduces power by 46%, code size by Optimisation reduces power by 46%, code size by 44%44%
A less component-intensive system (the radio) A less component-intensive system (the radio) “only” gains 7% from optimisation“only” gains 7% from optimisation
inlining +inlining +dead-codedead-code
dead-codedead-codeonlyonly
no no optimisatiooptimisationn
power power drawdraw
5.1mW5.1mW 9.5mW9.5mW 9.5mW9.5mW
code sizecode size 47.1kB47.1kB 52.5kB52.5kB 83.8kB83.8kB
nesC scorecardnesC scorecard
ExpressivityExpressivity
Constant hardware evolutionConstant hardware evolution
Real-time requirements (Real-time requirements (soft onlysoft only))
ReliabilityReliability
Extremely limited resourcesExtremely limited resources
ReprogrammabilityReprogrammability Whole program onlyWhole program only Provided by a TinyOS serviceProvided by a TinyOS service
nesC scorecardnesC scorecard
ExpressivityExpressivity
Constant hardware evolutionConstant hardware evolution
Real-time requirements (Real-time requirements (soft onlysoft only))
ReliabilityReliability
Extremely limited resourcesExtremely limited resources
ReprogrammabilityReprogrammability
““Easy” programmingEasy” programming Patterns help, but…Patterns help, but… Split-phase programming is painfulSplit-phase programming is painful Distributed algorithms are hardDistributed algorithms are hard Little-to-no debugging supportLittle-to-no debugging support
3 Practical Programming 3 Practical Programming SystemsSystems
nesCnesC A C dialect designed to address sensor network A C dialect designed to address sensor network
challengeschallenges Used to implement TinyOS, Maté, TinySQL (TinyDB)Used to implement TinyOS, Maté, TinySQL (TinyDB)
MatéMaté An infrastructure for building virtual machinesAn infrastructure for building virtual machines Provide safe, efficient high-level programming Provide safe, efficient high-level programming
environmentsenvironments Several programming models: simple scripts, Several programming models: simple scripts,
Scheme, TinySQLScheme, TinySQL
TinySQLTinySQL A sensor network query languageA sensor network query language Simple, well-adapted to data-collection applicationsSimple, well-adapted to data-collection applications
The Maté ApproachThe Maté Approach
Goals:Goals: Support reprogrammability, nicer programming Support reprogrammability, nicer programming
modelsmodels While preserving efficiency and increasing reliabilityWhile preserving efficiency and increasing reliability
Sensor networks are application specific.Sensor networks are application specific. We don’t need general programming: nodes in We don’t need general programming: nodes in
redwood trees don’t need to locate snipers in redwood trees don’t need to locate snipers in Sonoma.Sonoma.
Solution: an application specific virtual machine Solution: an application specific virtual machine (ASVM).(ASVM).
Design an ASVM for an application domain, Design an ASVM for an application domain, exposing its primitives, and providing the needed exposing its primitives, and providing the needed flexibility with limited resources..flexibility with limited resources..
The Maté ApproachThe Maté Approach
ReprogrammabilityReprogrammability Transmit small bytecoded programs.Transmit small bytecoded programs.
ReliabilityReliability The bytecodes perform runtime checks.The bytecodes perform runtime checks.
EfficiencyEfficiency The ASVM exposes high-level operations suitable The ASVM exposes high-level operations suitable
to the application domain.to the application domain.
Support a wide range of programming Support a wide range of programming models, applicationsmodels, applications
Decompose an ASVM into a Decompose an ASVM into a core, shared template core, shared template programming model and application domain extensionsprogramming model and application domain extensions
Operations
ASVM ArchitectureASVM Architecture
Scheduler
Concurrency Manager
ProgramStore
Template
Handlers
ASVM TemplateASVM TemplateThreaded, stack-based architectureThreaded, stack-based architecture
One basic type, 16-bit signed integersOne basic type, 16-bit signed integers Additional data storage supplied by language-specific Additional data storage supplied by language-specific
operationsoperations
SchedulerScheduler Executes runnable threads in a round-robin fashionExecutes runnable threads in a round-robin fashion Invokes operations on behalf of handlersInvokes operations on behalf of handlers
Concurrency ManagerConcurrency Manager Analyses handler code for shared resources Analyses handler code for shared resources
(conservative, flow insensitive, context insensitive (conservative, flow insensitive, context insensitive analysis).analysis).
Ensures race free and deadlock free execution Ensures race free and deadlock free execution
Program StoreProgram Store Stores and disseminates handler codeStores and disseminates handler code
ASVM ExtensionsASVM ExtensionsHandlers: events that trigger executionHandlers: events that trigger execution
One-to-one handler/thread mapping (but not required)One-to-one handler/thread mapping (but not required) Examples: timer, route forwarding request, ASVM Examples: timer, route forwarding request, ASVM
bootboot
Operations: units of executionOperations: units of execution Define the ASVM instruction set, and can extend an Define the ASVM instruction set, and can extend an
ASVM’s set of supported types as well as storage.ASVM’s set of supported types as well as storage. Two kinds: primitives and functionsTwo kinds: primitives and functions
Primitives: language dependent (e.g., jump, read Primitives: language dependent (e.g., jump, read variable)variable)
Can have embedded operands (e.g., push constant)Can have embedded operands (e.g., push constant)
Functions: language independent (e.g., send())Functions: language independent (e.g., send()) Must be usable in any ASVM Must be usable in any ASVM
MatMatéé scorecard scorecard
ExpressivityExpressivity By being tailored to an application domainBy being tailored to an application domain
MatMatéé scorecard scorecard
ExpressivityExpressivity
Real-time requirementsReal-time requirements Just say no!Just say no!
MatMatéé scorecard scorecard
ExpressivityExpressivity
Real-time requirementsReal-time requirements Just say nesC!Just say nesC!
MatMatéé scorecard scorecard
ExpressivityExpressivity
Real-time requirementsReal-time requirements
Constant hardware evolutionConstant hardware evolution Presents a hardware-independent modelPresents a hardware-independent model Relies on nesC to implement itRelies on nesC to implement it
QueryVM: an ASVMQueryVM: an ASVM
Programming ModelProgramming Model Scheme program on all nodesScheme program on all nodes
Application domainApplication domain multi-hop data collectionmulti-hop data collection
LibrariesLibraries sensors, routing, in-network aggregationsensors, routing, in-network aggregation
QueryVM size:QueryVM size: 65 kB code65 kB code 3.3 kB RAM3.3 kB RAM
QueryVM EvaluationQueryVM EvaluationSimple: collect light from all nodes every 50sSimple: collect light from all nodes every 50s
19 lines, 105 bytes19 lines, 105 bytes
Simple querySimple query// SELECT id, parent, light INTERVAL 50// SELECT id, parent, light INTERVAL 50mhop_set_update(100); settimer0(500); mhop_set_update(100); settimer0(500); mhop_set_forwarding(1);mhop_set_forwarding(1);any snoop() heard(snoop_msg());any snoop() heard(snoop_msg());any intercept() heard(intercept_msg());any intercept() heard(intercept_msg());any heard(msg) snoop_epoch(decode(msg, vector(2))[0]);any heard(msg) snoop_epoch(decode(msg, vector(2))[0]);
any Timer0() {any Timer0() { led(l_blink | l_green);led(l_blink | l_green); if (id()) {if (id()) { next_epoch();next_epoch(); mhopsend(encode(vector(epoch(), id(), parent(), mhopsend(encode(vector(epoch(), id(), parent(), light())));light()))); }}}}
QueryVM EvaluationQueryVM EvaluationSimple: collect light from all nodes every 50sSimple: collect light from all nodes every 50s
12 lines, 105 bytes12 lines, 105 bytes
Conditional: collect exponentially weighted Conditional: collect exponentially weighted moving average of temperature from some moving average of temperature from some nodesnodes
32 lines, 167 bytes32 lines, 167 bytes
SpatialAvg: compute average temperature, in-SpatialAvg: compute average temperature, in-networknetwork
31 lines, 127 bytes31 lines, 127 bytes or, 117 lines if averaging code in Schemeor, 117 lines if averaging code in Scheme
MatMatéé scorecard scorecard
ExpressivityExpressivity
Real-time requirementsReal-time requirements
Constant hardware evolutionConstant hardware evolution
ReliabilityReliability Runtime checksRuntime checks Reprogramming always possibleReprogramming always possible
MatMatéé scorecard scorecard
ExpressivityExpressivity
Real-time requirementsReal-time requirements
Constant hardware evolutionConstant hardware evolution
ReliabilityReliability
Extremely limited resourcesExtremely limited resources VM expresses application logic in high-level VM expresses application logic in high-level
operationsoperations But, don’t try and write an FFT!But, don’t try and write an FFT!
QueryVM EnergyQueryVM Energy
Ran queries on 42 node Ran queries on 42 node networknetwork
Compared QueryVM to nesC Compared QueryVM to nesC implementation of same queriesimplementation of same queries
Fixed collection tree and packet Fixed collection tree and packet size to control networking cost.size to control networking cost.
0
1
2
3
4
5
Simple Conditional SpatialAvg
Pow
er D
raw
(m
W)
nesC
QueryVM
QueryVM sometimes uses less energy than the nesC code.QueryVM sometimes uses less energy than the nesC code. Due to vagaries of radio congestion (nesC nodes all transmitting Due to vagaries of radio congestion (nesC nodes all transmitting
in synch)in synch)
Decompose QueryVM cost using a 2-node network.Decompose QueryVM cost using a 2-node network. Run with no query: base cost (listening for messages).Run with no query: base cost (listening for messages). Ran programs for eight hours, sampling power draw at 10KHzRan programs for eight hours, sampling power draw at 10KHz
No measurable energy overhead!No measurable energy overhead! There’s not much work in the application code…There’s not much work in the application code…
MatMatéé scorecard scorecard
ExpressivityExpressivity
Real-time requirementsReal-time requirements
Constant hardware evolutionConstant hardware evolution
ReliabilityReliability
Extremely limited resourcesExtremely limited resources
ReprogrammingReprogramming Enough said already…Enough said already…
MatMatéé scorecard scorecard
ExpressivityExpressivity
Real-time requirementsReal-time requirements
Constant hardware evolutionConstant hardware evolution
ReliabilityReliability
Extremely limited resourcesExtremely limited resources
ReprogrammingReprogramming
““Easy” programmingEasy” programming The good: simple threaded event-processing The good: simple threaded event-processing
modelmodel The bad: scripting languages don’t make writing The bad: scripting languages don’t make writing
distributed algorithms any easierdistributed algorithms any easier
3 Practical Programming 3 Practical Programming SystemsSystems
nesCnesC A C dialect designed to address sensor network A C dialect designed to address sensor network
challengeschallenges Used to implement TinyOS, Maté, TinySQL (TinyDB)Used to implement TinyOS, Maté, TinySQL (TinyDB)
MatéMaté An infrastructure for building virtual machinesAn infrastructure for building virtual machines Provide safe, efficient high-level programming Provide safe, efficient high-level programming
environmentsenvironments Several programming models: simple scripts, Several programming models: simple scripts,
Scheme, TinySQLScheme, TinySQL
TinySQLTinySQL A sensor network query languageA sensor network query language Simple, well-adapted to data-collection applicationsSimple, well-adapted to data-collection applications
TinySQLTinySQL
nesC, Scheme are both “local” languagesnesC, Scheme are both “local” languages A lot of programming effort to deal with A lot of programming effort to deal with
distribution, reliabilitydistribution, reliability Example: distributed average computationExample: distributed average computation
In-network averagingIn-network averaging any maxdepth = 5; // max routing tree any maxdepth = 5; // max routing tree depth supporteddepth supported any window = 2 * maxdepth;any window = 2 * maxdepth;
// The state of an average aggregate is an // The state of an average aggregate is an array containing:array containing: // counts for 'window' epochs// counts for 'window' epochs // sums for 'window' epochs// sums for 'window' epochs // the number of the oldest epoch in the // the number of the oldest epoch in the windowwindow any avg_make() {any avg_make() { any Y = make_vector(1 + 2 * window);any Y = make_vector(1 + 2 * window); vector_fill!(Y, 0);vector_fill!(Y, 0); return Y;return Y; }}
// The epoch changed. Ensure epoch + 1 is // The epoch changed. Ensure epoch + 1 is inside the inside the // window.// window. any avg_newepoch(Y) {any avg_newepoch(Y) { any start = Y[2 * window];any start = Y[2 * window];
if (epoch() + 1 >= start + window)if (epoch() + 1 >= start + window) {{
// figure out new start and how much to // figure out new start and how much to shift valuesshift values
// from old epoch for the new start// from old epoch for the new start any shift = epoch() + 2 - window - any shift = epoch() + 2 - window - start, i;start, i;
start = epoch() + 2 - window, i;start = epoch() + 2 - window, i;Y[2 * window] = start;Y[2 * window] = start;
if (shift > window)if (shift > window) shift = window;shift = window;elseelse
{{ for (i = shift; i < window; i++)for (i = shift; i < window; i++) {{ Y[i - shift] = Y[i];Y[i - shift] = Y[i];
Y[i - shift + window] = Y[i + window];Y[i - shift + window] = Y[i + window]; }} }}
// clear new values// clear new valuesfor (i = window - shift; i < window; i++)for (i = window - shift; i < window; i++) {{ Y[i] = 0;Y[i] = 0; Y[i + window] = 0;Y[i + window] = 0; }}
}} }}
// Update the state for epoch 'when' with a // Update the state for epoch 'when' with a count of 'n' count of 'n'
// and a sum of 'sum'// and a sum of 'sum' any add_avg(Y, when, n, sum) {any add_avg(Y, when, n, sum) { any start = Y[2 * window];any start = Y[2 * window]; if (when >= start && when < start + if (when >= start && when < start + window)window) {{
Y[when - start] += n; // update Y[when - start] += n; // update countcount
Y[when - start + window] += n; // update Y[when - start + window] += n; // update sumsum }} }}
// Add local result for current epoch// Add local result for current epoch any avg_update(Y, val) add_avg(Y, epoch(), 1, any avg_update(Y, val) add_avg(Y, epoch(), 1, val);val);
// avg_get returns a six-byte string containg // avg_get returns a six-byte string containg encodedencoded // epoch, count, sum (2 bytes each)// epoch, count, sum (2 bytes each) // where epoch is chosen so that our // where epoch is chosen so that our descendant'sdescendant's // results have reached us before we try and // results have reached us before we try and sendsend // them on// them on any avg_get(Y) {any avg_get(Y) { any start = Y[2 * window];any start = Y[2 * window]; any when = epoch() - 2 * (maxdepth - 1 - any when = epoch() - 2 * (maxdepth - 1 - depth());depth()); any tosend = vector(when, 0, 0);any tosend = vector(when, 0, 0);
// encode the result for epoch 'when', but // encode the result for epoch 'when', but avoid avoid // problems if we don't know it or if we're // problems if we don't know it or if we're too too // deep in the tree// deep in the tree if (depth() >= maxdepth)if (depth() >= maxdepth) tosend[0] = epoch() - 256;tosend[0] = epoch() - 256; else if (when >= start)else if (when >= start) {{ tosend[1] = Y[when - start]; // counttosend[1] = Y[when - start]; // count
tosend[2] = Y[when - start + window]; // tosend[2] = Y[when - start + window]; // sumsum }} return encode(tosend);return encode(tosend); }}
any avg_buffer() make_string(6);any avg_buffer() make_string(6);
// Add some results from our descendants to // Add some results from our descendants to our stateour state any avg_intercept(Y, intercepted) {any avg_intercept(Y, intercepted) { any decoded = decode(vector(2, 2, 2));any decoded = decode(vector(2, 2, 2)); add_avg(Y, vector[0], vector[1], vector[2]);add_avg(Y, vector[0], vector[1], vector[2]); }}
TinySQLTinySQL
nesC, Scheme are both “local” languagesnesC, Scheme are both “local” languages A lot of programming effort to deal with A lot of programming effort to deal with
distribution, reliabilitydistribution, reliability Example: distributed average computationExample: distributed average computation
TinySQL is a higher-level programming modelTinySQL is a higher-level programming model ““The sensor network is a database, sensors are The sensor network is a database, sensors are
attributes”attributes” Query it with SQL!Query it with SQL!
ExamplesExamplesSELECT id, parent, temp INTERVAL 50sSELECT id, parent, temp INTERVAL 50s
SELECT id, expdecay(humidity, 3) WHERE parent > SELECT id, expdecay(humidity, 3) WHERE parent > 0 INTERVAL 50s0 INTERVAL 50s
SELECT avg(temp) INTERVAL 50sSELECT avg(temp) INTERVAL 50s
TinySQL: Two TinySQL: Two ImplementationsImplementations
TinyDB: the originalTinyDB: the original A nesC program which interprets TinySQL queriesA nesC program which interprets TinySQL queries
TinySQLVM (aka QueryVM…)TinySQLVM (aka QueryVM…) MatMaté VM running Schemeé VM running Scheme TinySQL queries compiled to Scheme applicationTinySQL queries compiled to Scheme application
Comparable performance, flexibilityComparable performance, flexibility TinySQLVM uses 5-20% less energy than TinyDB on TinySQLVM uses 5-20% less energy than TinyDB on
the three example queriesthe three example queries ~4 months operation on 2 AA’s (15-node, plant-~4 months operation on 2 AA’s (15-node, plant-
watering app)watering app) TinyDB can run multiple queriesTinyDB can run multiple queries TinySQLVM allows user-written extensions to TinySQLVM allows user-written extensions to
TinySQLTinySQL
TinySQL scorecardTinySQL scorecard
ExpressivityExpressivity Limited to a single kind of applicationLimited to a single kind of application
TinySQL scorecardTinySQL scorecard
ExpressivityExpressivity
Real-time requirementsReal-time requirements We won’t go there…We won’t go there…
TinySQL scorecardTinySQL scorecard
ExpressivityExpressivity
Real-time requirementsReal-time requirements
Constant hardware evolutionConstant hardware evolution Presents a hardware-independent programming Presents a hardware-independent programming
modelmodel
TinySQL scorecardTinySQL scorecard
ExpressivityExpressivity
Real-time requirementsReal-time requirements
Constant hardware evolutionConstant hardware evolution
ReliabilityReliability You can’t express any nasty bugs You can’t express any nasty bugs
TinySQL scorecardTinySQL scorecard
ExpressivityExpressivity
Real-time requirementsReal-time requirements
Constant hardware evolutionConstant hardware evolution
ReliabilityReliability
Extremely limited resourcesExtremely limited resources Little computation requiredLittle computation required Can perform high-level optimisations (see the Can perform high-level optimisations (see the
many TinyDB papers)many TinyDB papers)
TinySQL scorecardTinySQL scorecard
ExpressivityExpressivity
Real-time requirementsReal-time requirements
Constant hardware evolutionConstant hardware evolution
ReliabilityReliability
Extremely limited resourcesExtremely limited resources
ReprogrammingReprogramming Is not a problemIs not a problem
TinySQL scorecardTinySQL scorecard
ExpressivityExpressivity
Real-time requirementsReal-time requirements
Constant hardware evolutionConstant hardware evolution
ReliabilityReliability
Extremely limited resourcesExtremely limited resources
ReprogrammingReprogramming
““Easy” programmingEasy” programming Simple, declarative, whole system programming Simple, declarative, whole system programming
modelmodel
Related Work: nesCRelated Work: nesCOther component and module systemsOther component and module systems
Closest are Knit and MesaClosest are Knit and Mesa None have our desired features: None have our desired features:
component-based, compile-time wiring, bi-directional component-based, compile-time wiring, bi-directional interfacesinterfaces
Lots of embedded, real-time programming Lots of embedded, real-time programming languageslanguages
Giotto, Esterel, Lustre, Signal, E-FRPGiotto, Esterel, Lustre, Signal, E-FRP Stronger guarantees, but not general-purpose Stronger guarantees, but not general-purpose
systems languagessystems languages
Component architectures in operating systemsComponent architectures in operating systems Click, Scout, x-kernel, Flux OSKit, THINKClick, Scout, x-kernel, Flux OSKit, THINK Mostly based on dynamic dispatch, no whole-Mostly based on dynamic dispatch, no whole-
program optimizationprogram optimization
Related Work: ASVMsRelated Work: ASVMs
JVM, KVM, CLRJVM, KVM, CLR Designed for devices with much greater resources: Designed for devices with much greater resources:
100+ KB RAM100+ KB RAM
Java CardJava Card An application specific JVM for smart cardsAn application specific JVM for smart cards Many of the same principles apply (constraints, Many of the same principles apply (constraints,
CAP format)CAP format)
SPIN, Exokernel, Tensilica, etc.SPIN, Exokernel, Tensilica, etc. Customizable boundaries for application specificityCustomizable boundaries for application specificity
Impala/SOSImpala/SOS Support incremental binary updates: easy to crash Support incremental binary updates: easy to crash
a systema system
ScorecardsScorecardsCC nesCnesC MatMatéé TinySQLTinySQL
ExpressivityExpressivity
Real-timeReal-time Hardware Hardware
evol.evol.
ReliabilityReliability Limited Limited
resourcesresources
ReprogrammiReprogrammingng
??Easy to useEasy to use ??
And the Winner is…And the Winner is…
nesCnesC High performance, suitable for any part of an High performance, suitable for any part of an
applicationapplication But, harder to program, bugs may bring down But, harder to program, bugs may bring down
systemsystem
MatMatéé Safe, simple programming environmentsSafe, simple programming environments But, limited performance – best for “scripting”, But, limited performance – best for “scripting”,
not radio stacksnot radio stacks
TinySQLTinySQL Easiest to useEasiest to use But, limited application domainBut, limited application domain
WhyWhy not use all three? not use all three? Extend TinySQL with MatExtend TinySQL with Maté (Scheme) é (Scheme)
codecode Extend Extend MatMaté with new functions, é with new functions,
events written in nesCevents written in nesC
ConclusionConclusion
Sensor networks raise a number of Sensor networks raise a number of programming challengesprogramming challenges
Very limited resourcesVery limited resources High reliability requirementsHigh reliability requirements Event-driven, concurrent programming modelEvent-driven, concurrent programming model
nesC and nesC and MatMaté represent two different tradeoffs é represent two different tradeoffs in this spacein this space
nesC: maximum performance and flexibility, some nesC: maximum performance and flexibility, some reliability through compile-time checks, harder reliability through compile-time checks, harder programmingprogramming
MatMaté: efficiency for a specific application domain, é: efficiency for a specific application domain, full reliability through runtime checks, simpler full reliability through runtime checks, simpler (scripting) to simple (TinySQL) programming(scripting) to simple (TinySQL) programming
Service Instance:Service Instance: support multiple instances with efficient support multiple instances with efficient
collaborationcollaboration
Timer
Clock
Data Collection
Radiotimer0timer1
ConsequencesConsequences clients remain independent, clients remain independent,
configurabilityconfigurabilityimplementation can coordinateimplementation can coordinate
clients guaranteed that service is availableclients guaranteed that service is available
robustnessrobustness service automatically “sized” to application needsservice automatically “sized” to application needs
efficiencyefficiency static allocation may be wasteful ifstatic allocation may be wasteful if
# worst case simultaneous users < # different users# worst case simultaneous users < # different users
Placeholder:Placeholder: allow easy, application-wide selection of a particular allow easy, application-wide selection of a particular
service implementationservice implementation
Router
Init
Route
Main
Data Collection
Management
MRoute
ConsequencesConsequences defines global names for common servicesdefines global names for common services
replaceabilityreplaceability easy application-wide implementation selectioneasy application-wide implementation selection no runtime costno runtime cost
efficiencyefficiency
Conditional queryConditional query// SELECT id, expdecay(light, 3) WHERE (parent > 0) INTERVAL 50// SELECT id, expdecay(light, 3) WHERE (parent > 0) INTERVAL 50any expdecay_make(bits) vector(bits, 0);any expdecay_make(bits) vector(bits, 0);any expdecay_get(s, val) s[1] = s[1] - (s[1] >> s[0]) + (val >> s[0]);any expdecay_get(s, val) s[1] = s[1] - (s[1] >> s[0]) + (val >> s[0]);any s_op1 = expdecay_make(3);any s_op1 = expdecay_make(3);
mhop_set_update(100); settimer0(500); mhop_set_forwarding(1);mhop_set_update(100); settimer0(500); mhop_set_forwarding(1);any snoop() heard(snoop_msg());any snoop() heard(snoop_msg());any intercept() heard(intercept_msg());any intercept() heard(intercept_msg());any heard(msg) snoop_epoch(decode(msg, vector(2))[0]);any heard(msg) snoop_epoch(decode(msg, vector(2))[0]);any Timer0() {any Timer0() { led(l_blink | l_green);led(l_blink | l_green); if (id()) {if (id()) { next_epoch();next_epoch(); if (parent() > 0)if (parent() > 0) mhopsend(encode(vector(epoch(), id(), expdecay_get(s_op1, mhopsend(encode(vector(epoch(), id(), expdecay_get(s_op1, light()))));light())))); }}}}
Spatial querySpatial query// SELECT avg[light] INTERVAL 50// SELECT avg[light] INTERVAL 50mhop_set_update(100); settimer0(500); mhop_set_forwarding(0);mhop_set_update(100); settimer0(500); mhop_set_forwarding(0);any s_op1 = avg_make();any s_op1 = avg_make();
any snoop() snoop_epoch(decode(snoop_msg(), vector(2))[0]);any snoop() snoop_epoch(decode(snoop_msg(), vector(2))[0]);any intercept() {any intercept() { vector fields = decode(intercept_msg(), vector(2, avg_buffer()));vector fields = decode(intercept_msg(), vector(2, avg_buffer())); snoop_epoch(fields[0]);snoop_epoch(fields[0]); avg_intercept(s_op1, fields[1]);avg_intercept(s_op1, fields[1]); }}any epochchange() avg_newepoch(s_op1);any epochchange() avg_newepoch(s_op1);any Timer0() {any Timer0() { led(l_blink | l_green);led(l_blink | l_green); if (id()) {if (id()) { next_epoch();next_epoch(); avg_update(s_op1, light());avg_update(s_op1, light()); }} mhopsend(encode(vector(epoch(), avg_get(s_op1))));mhopsend(encode(vector(epoch(), avg_get(s_op1))));}}