270 likes | 480 Views
nesC. Prepared for the Multimedia Networks Group University of Virginia. Quick Review: TinyOS. “Operating system” for wireless embedded sensor networks Actually a set of software components that can be “wired” together into a single binary which is run on the motes Minimal OS functions
E N D
nesC Prepared for the Multimedia Networks Group University of Virginia
Quick Review: TinyOS • “Operating system” for wireless embedded sensor networks • Actually a set of software components that can be “wired” together into a single binary which is run on the motes • Minimal OS functions • 2 threads of execution: tasks and hardware event handlers • No memory management…
Quick Review: nesC • Pronounced “”NES-see” • Extension of C • Supports C syntax • Compiled into C • “designed to embody the structuring concepts and execution model of TinyOS”
nesC and TinyOS • TinyOS was originally written in C, applications were combinations of .c, .comp, and .desc files • TinyOS (components) have been reimplemented in nesC • A new language for mote programming is currently being developed • nesC is a temporary solution
Vocabulary • Application – one or more components wired together to form an executable • Component – basic building blocks for nesC apps. Two types: modules and configurations • Module – component that implements one or more interfaces • Configuration – component that wires other components together • Interface – provides an abstract definition of the interaction between two components
C1 C2 C3 Visualizing modules • modules: module C1 { requires interface triangle; } implementation { ... } module C2 { provides interface triangle in; requires { interface triangle out; interface rectangle side; } } implementation { ... } module C3 { provides interface triangle; provides interface rectangle; } implementation { ... }
C1 C2 C2 C3 C3 Visualizing configurations • Connect configurations: configuration app { } implementation { uses c1, c2, c3; c1 -> c2; // implicit interface sel. c2.out -> c3.triangle; c3 <- c2.side; } • Partial configurations: component c2c3 { provides interface triangle t1; } implementation { uses c2, c3; t1 -> c2.in; c2.out -> c3.triangle; c3 <- c2.side; }
More on wiring configuration C { provides interface X; } implementation { components C1, C2; X = C1.X; C1.Y -> C2.Y; C1.Z <- C2.Z; } • “=“ used when any endpoint is external (a specification element – provides or uses) • “->” or “<-” used when both endpoints are internal • A -> B is equivalent to B <- A
Fan-in, fan-out configuration C { provides interface X; } implementation { components C1, C2; X = C1.X; X = C2.X; } • Endpoints can be connected multiple times • In this case, multiple functions will be executed when C.X’s commands are called and multiple signalers will issue callbacks for subscribers to C.X’s events
Implicit connections configuration C { } implementation { components C1, C2; C1 <- C2.X; C2.Y <- C2; C1.Z -> C2; } • When only there is only one specification element of a given type in the component being mapped to or from, it doesn’t need to be explicitly specified in connections • C1.X <- C2.X is equivalent to C1 <- C2.X as long as there is only one specification element of type X in C1
Interfaces, commands, events • Interfaces are bidirectional: “they specify a set of functions to be implemented by the interface’s provider (commands) and a set to be implemented by the interface’s user (events) • Commands typically call downwards (from application components to components closer to hardware) while events call upwards
Example interface // can include c files interface SendMsg { command result_t send(uint16_t address, uint8_t length, TOS_MsgPtr msg); event result_t sendDone(TOS_MsgPtr msg, result_t success); }
More on commands and events • Calling a command int x = ...; call Send.send[x + 1](1, sizeof(Message), &msg1); • Signaling an event int x = ...; signal Send.sendDone[x + 1](&msg1, SUCCESS);
Tasks • “A task is an independent locus of control defined by a function of storage class task returning void and with no arguments: task void myTask() { ... }” • “Tasks are posted by prefixing a call to the task with post, e.g., post myTask();”
Tasks events commands Interrupts Hardware TinyOS Execution Contexts • Events generated by interrupts preempt tasks • Tasks do not preempt tasks • Both essential process state transitions
Atomic statements bool busy; // global void f() { bool available; atomic { available = !busy; busy = TRUE; } if (available) do_something; atomic busy = FALSE; } • “guarantee that the statement is executed “as-if” no other computation occurred simultaneously” • Should be short! • nesC forbids: call, signal, goto, return, break, continue, case, default, label
Misc: Attributes • Uses gcc’s __attribute__ syntax to declare properties of functions, variables, and typedefs • “C” – element should appear in global C scope rather than module scope • “spontaneous” – functions only – there may be calls to the function that don’t appear in the source code (e.g. interrupt handlers or C main function) module RealMain { ... } implementation { int main(int argc, char **argv) __attribute__((C, spontaneous)) { ... } }
Misc: Attributes continued • “combine” – specify the combining function for a type in a typedef declaration • Combining function specifies how to combine multiple results from a command or event which has fan-out typedef uint8_t result_t __attribute__((combine(rcombine))); result_t rcombine(result_t r1, result_t r2) { return r1 == FAIL ? FAIL : r2; }
Misc: Compile time constant functions • Evaluate to a constant at compile time • unsigned int unique(char *identifier) • If the program contains n calls to unique with the same identifier string, returns a unique integer in the range 0..n-1 • unsigned int uniqueCount(char *identifier) • If the program contains n calls to unique with the same identifier string, returns n
Blink Example • Program toggles the red LED every second
Blink.nc configuration Blink { } implementation { components Main, BlinkM, SingleTimer, LedsC; Main.StdControl -> SingleTimer.StdControl; Main.StdControl -> BlinkM.StdControl; BlinkM.Timer -> SingleTimer.Timer; BlinkM.Leds -> LedsC; }
BlinkM.nc (specification) module BlinkM { provides { interface StdControl; } uses { interface Timer; interface Leds; } }
BlinkM.nc (implementation) implementation { command result_t StdControl.init() { call Leds.init(); return SUCCESS; } command result_t StdControl.start() { // Start a repeating timer that fires every 1000ms return call Timer.start(TIMER_REPEAT, 1000); } command result_t StdControl.stop() { return call Timer.stop(); } event result_t Timer.fired() { call Leds.redToggle(); return SUCCESS; } }
SingleTimer.nc configuration SingleTimer { provides interface Timer; provides interface StdControl; } implementation { components TimerC; Timer = TimerC.Timer[unique("Timer")]; StdControl = TimerC; }