snack sensor network application construction kit (otherwise known as tinymeal**) ben greenstein...
Post on 21-Dec-2015
213 views
TRANSCRIPT
SNACK Sensor Network Application
Construction Kit(otherwise known as TinyMeal**)
Ben GreensteinEddie Kohler
Deborah Estrin
CENS Technical SeminarJanuary 9, 2004
*TinyOS work with David Culler at Intel Research, Berkeley**Name courtesy of Tom Schoellhammer
Goals of SNACK Make it easy for scientists (i.e., non-programmers)
to rapidly develop efficient sensor network applications
Write a library of components and a configuration language that are: Easy to use for both non-programmers and experienced
systems developers Expressive but not cluttered
Construct a compiler that: Optimizes a configuration to produce an efficient
implementation
Do nesC and TinyOS meet this goal? Most common complaint about
TinyOS/nesC: “You have to be a genius to program in it” Almost correct; you only have to be an
experienced systems developer to program in it. The goal of TinyOS has largely been one
of efficiency. Very little effort has been focused on making application development easy Note: TinyDB and Tiny Diffusion can handle a
variety of queries, but the application itself, namely TinyDB or Tiny Diffusion, is always the same.
Consequences of Flexible Hardware/ Software Interface in TinyOS
No function pointers No callbacks
No component instances (changing) Funky state maintenance
No dynamic memory Static allocation of messages Pointer swaps Guards
RFM
Radio byte
i2c
Tempphoto
clocksbit
byte
packet Radio Packet
HW
SW
ADC
UART Packet
UART byte
Component Autonomy
Principle Components should function irrespective of what
is using them
Consequence Timers in more components than need to be
Examples Larger footprint Handlers everywhere Actions that should be temporally coupled are not
Unformatted packets
Design Choice Monolithic TOS_Msg with 29 byte
payloadConsequence
Doesn’t work well for layered systems, because 29 bytes isn’t enough room to encapsulate
Flat data block not well suited to dynamically sized and typed content
Examples Every data type gets its own packet Complex structures of unions of
structures
TOSMSG
Not to mention…
Scheduling restrictions Split-phase operations Poor data passing semantics Restrictions on using the usual things we use
to develop applications Preprocessing directives Header files
Solutions within TinyOS
A timer eliminator: MinRate Collapses the timers into one timer event Generates packets at a minimum rate Drives soft state mechanisms of various
services Advantages
Fewer timers Fewer header bytes sent Reduced duplication of attributes
Issues of soft state Soft state can drown a network, particularly in
TOSSIM Eventual consistency isn’t always timely
SourceStamp
AM
SpanningStamp
MinRate
LocationStamp
DelaunayStamp
Tag/length/value packet format* Add as many attributes as needed or as can fit in
data portion of TOS_Msg structure Limited to 8 different types of attributes in system
Constant time inserts, tests for inclusion, linear reads putAttr() and getAttr() provided as inline for write and read Byte 0 of data portion contains bit field for test
1+c bytes of overhead for c attributes
TinyOS implementation:TOS_Msg msg->data
Tag Fieldbyte
Tag(3 bits)
Length(5 bits)
Value(length as specified)
Tag(3 bits)
Length(5 bits)
*See also: Robert Braden, Ted Faber, and Mark Handley, “From Protocol Stack to Protocol Heap - Role-Based Architecture,” Proceedings of the First Workshop on Hot Topics in Networking (Hotnets-I), ACM SIGCOMM, Princeton, NJ (October 2002).
TOS_Msg memory manager
Sits directly above the AM layer Buffer Pool
Buffer allocation and guards handled in memory layer instead of in every component
alloc(), free(), copyAlloc()
Implicit Deallocation When SendMsg.send () fails and immediately after upcalls
to SendMsg.sendDone() and ReceiveMsg.receive()
Queued Send absorbs bursts (thanks, Phil B.)
An application constructed with these enhancements
A fire is localized to one square meter in a meadow. It is probably a campfire, so do nothing
A fire has grown larger; locate any sprinklers nearby and turn them on. If there are no sprinklers, alert a human
The app architecture
SourceCache SourceStamp
AM
Memory Layer
QueuedSendBufferPool BufferQueueComm
SpanningCache SpanningStamp
CombineCache CombineStamp
MinRate
Sink Sampler
DelaunayCache
LocationStamp
DelaunayStamp
LocationCache
*
*
*
*
*
*uses BufferPoolInverseNeighbhood
So how should it be done?
Easy Programming, debugging
Extensible Component additions, Inheritance
Familiar Learning curve not too steep
Reusable Efficient
Users plug services together
Component software can be snapped together by non-programmers to achieve a desired functionality Without removing flexibility for experts Therefore, lots of default behavior
Building an application, then, requires only to learn a configuration language
Efficiency not sacrificed
Weave services together into an efficient implementation If two services within an application each use a
component that could be shared, instantiate only once and connect to both services
Provide compiler support for optimizing the merging of services
Write the core services in a powerful and standard language
Example: a sum aggregatorclass SumAggregator32 : public Component, public Uint32Receiver{public: SumAggregator32();
virtual bool recv(int intstance, uint32_t m);
void set_acc_target(NodeStore32Access *r, int i){ _accTarget = r, _accTargetInstance = i; }
protected: uint32_t getSum(); uint32_t _lastSum;
// Variables for calling the push and access targets Uint32Receiver *_pushTarget; int _pushTargetInstance; NodeStore32Access *_accTarget; int _accTargetInstance;};
Configuration language
Flexible wiring environment Declarations
Named instances of components E.g. m::MinRate(period = 100ms);
Associative array of named parameter types E.g., MinRate(period = 100ms);
Wirings Connection of components via their interfaces Flexibility in specification Access rules (how components can be shared)
Flexible wiring
The arrow operator (->) connects two components TreeRoot[signal]->[start]MinRate
The transitive arrow operator (..>) establishes a precedence relation Network[MsgReceiver]..>Extractor16(type = TREEHOPS);
Tokens in brackets [, ] denote interfaces Tokens outside of brackets denote components Specified interfaces and components can be types
or instances
Design methodology
Configuration methodology Macrocompiler tasks
Separate functionality
Components should be small, but not artificially so. Each should serve a specific purpose, but should be general enough to be reused
Examples: NodeStore8, MinRate, Stamp8, SendQueue
routingTable[hopsAccess]->[Access8] NodeStore8;
TreeRoot[signal]->[start] MinRate (period = 300000ms)[MsgReceiver]..> Stamp8 (type = TREEHOPS)..> SendQueue ..>Network;
Provide component flexibility
If you don't care which instance of a component is used, you don't need to specify an instance
Examples: Network, SendQueue
TreeRoot[signal]->[start] MinRate (period = 300000ms)[MsgReceiver]..> Stamp8 (type = TREEHOPS)..> SendQueue ..> Network;
TreeRoot[signal]->[start] MinRate (period <= 300000ms)[MsgReceiver]..> Stamp8 (type = TREEHOPS)..> SendQueue ..> Network;
Constrain component flexibility
If you don't care what instance is used, but do care about the initialization of whatever is used, you can specify a type with an initialization
Use associative array to expose initialization to macrocompiler Allow parameter bounds instead of constants
Example:
Provide interface flexibility If you don't care about the outgoing port or incoming
port for an interface, you don't need to specify instances
Should not require interface specification if same as preceding interfaces specification
Example: MsgReceiver
MsgReceiver
TreeRoot[signal]->[start] MinRate (period = 300000ms)[MsgReceiver]..> Stamp8 (type = TREEHOPS)..> SendQueue ..> Network;
Example: link quality estimation
lqeStore::NodeStore32();lqeStamp::PullStampBlob(type = LQE);
Network[MsgReceiver]..>ExtractorBlob(type = LQE)[pushGeneric]->[hoodLinkEstimate]LQE;
Network[MsgReceiver]..>Extractor16(type = SRCID)[push16]->[id]LQE;Network[MsgReceiver]..>Extractor16(type = SEQNO)[push16]->[seq]LQE;
LQE[toAccess]->[highAccess16]lqeStore;LQE[fromAccess]->[lowAccess16]lqeStore;
lqeStamp[pullGeneric]->[statsBlob]LQE;
MinRate(period = 100000ms)[MsgReceiver]..>lqeStamp..>SendQueue..>Network;
Design methodology
Configuration methodology
Macrocompiler tasks
Syntax and semantics check
Component names are valid Interface names are valid Component instances are declared Wiring uses [, ], ->, and ..> lexemes correctly
Precedence graph generation
The compiler looks at precedence relationships and builds a single graph
It replaces ..> with ->
Compiler instantiation Takes a component wiring and determines how instances of
each component need to be created How many instances? What initialization parameters? Example: MinRate(period = 300000ms);
minrate_1_::MinRate(period = 300000ms);
_treeroot_1_ [signal]->[start] _minrate_1_ [msgReceiver]->[msgReceiver] _stamp8_1_ [msgReceiver]->[msgReceiver] _sendqueue_1_ [msgReceiver]->[msgReceiver] _network_1_;
Component Sharing
Looks for components that can be shared
Example:
Serives A and B are part of an applicationService A needs a NodeStore32(type = LQE)Service B needs a NodeStore32(type = LQE)Application get a single NodeStore32(type = LQE)
Semi-constrained initializations
Components with compatible semi-constrained initializations are shared
Example:
Semi-constrained declarations:MinRate1(period <= 1000ms) MinRate2(period <= 500ms)
Become… minRate(period = 500ms)
Efficient Supersets
The compiler looks for single components that can replace sets of components to make things more efficient.
Example:
Extractor1616 replaces two Extractor16's.
Code generation
The compiler generates a C++ main file and a Makefile given the resulting wiring
Example: MinRate _minrate_2_;
_minrate_2_[msgReceiver]->lqeStamp
becomes…
MinRate _minrate_2_;_minrate_2_.init(100000);_minrate_2_.set_msg_target(lqeStamp);_minrate_2.start();
Concluding Remarks
Work in progress Around 20 components written A compiler that takes a wiring and produces a
C++ instantiation Most of the optimization work is ongoing
The End