21.08.2013 Views

A State-Based Programming Model for Wireless Sensor Networks

A State-Based Programming Model for Wireless Sensor Networks

A State-Based Programming Model for Wireless Sensor Networks

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

58 Chapter 3. <strong>Programming</strong> and Runtime Environments<br />

or to <strong>for</strong>m an application. Each component interface defines the tasks, events,<br />

and commands it exports <strong>for</strong> use by other components. Each component has a<br />

component frame, which constitutes the component’s context, in which all tasks,<br />

events, and commands execute and which stores its state. Components may<br />

be considered objects of a static object-oriented language. Components always<br />

exist <strong>for</strong> the entire duration of a process and cannot be instantiated or deleted<br />

at runtime. The variables within a component frame are static (i.e., they have<br />

global lifetime) and have component scope (i.e., are visible only from with in<br />

the component). However, multiple static instances of a component may exist as<br />

parameterized interfaces. Parameterized interfaces are statically declared as array<br />

of components and are accessed by index or name. The elements of a component<br />

array provide identical interfaces but have individual states. They are used to<br />

model identical resources, such as individual channels of a multi-channel ADC<br />

or individual network buffers in an array of buffers.<br />

TinyOS is inherently event-driven and thus it shares the benefits of eventdriven<br />

systems. As an event-driven system it has only a single context in which<br />

all program code executes. There<strong>for</strong>e the implementation of TinyOS avoids<br />

context-switching overhead. All components share a single runtime stack while<br />

component frames are statically allocated, like global variables. As a deviation<br />

from the basic event-driven model, TinyOS has a two-level scheduling hierarchy<br />

which allows programmers to program interrupt service routines similar to<br />

event handlers using the TinyOS event abstraction. In most other event-driven<br />

systems, interrupts are typically hidden from the programmer and are handled<br />

within the drivers. IO data is typically buffered in the drivers and asynchronous<br />

events are used to communicate their availability to user code. In TinyOS, on<br />

the contrary, interrupts are not hidden from the programmer. This has been a<br />

conscious design decision. It allows to implement time critical operations within<br />

user code and provides greater flexibility <strong>for</strong> IO-data handling.<br />

However, this approach has a severe drawback. TinyOS events may interrupt<br />

tasks and other events at any time. Thus TinyOS requires programmers to explicitly<br />

synchronize access to variables that are shared within tasks and events<br />

(or within multiple events) in order to avoid data races. TinyOS has many of<br />

the synchronization issues of preemptive multi-tasking, which we consider one<br />

of the main drawback of TinyOS. In oder to support the programmer with synchronization,<br />

more recent versions of nesC have an atomic statement to en<strong>for</strong>ce<br />

atomic operation by disabling interrupt handling. Also, the nesC compiler has<br />

some logic to warn about potential data races. However, it cannot detect all<br />

race conditions and produces a high number of false positives. A code analysis<br />

of TinyOS (see [45]) and its applications has revealed that the code had many<br />

data races be<strong>for</strong>e race detection was implemented. In one example with race<br />

detection in place, 156 variables were found to have (possibly multiple) race<br />

conditions, 53 of which were false positives (i.e., about 30%).<br />

The high number of actual race conditions in the TinyOS show that interruptible<br />

code is very hard to understand and manage and thus highly error prone.<br />

Even though the compiler in the recent version now warns about potential data<br />

races, it does not provide hints on how to resolve the conflicts. Conflict resolution<br />

is still left to programmers. The high rate of false positives (about 30%) may<br />

leave programmers in doubt whether they deal with an actual conflict or a false

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!