An Introduction to nesC
Vinay Kumar Singh
Dongseo University
Outline
Introduction
TinyOS concepts
nesC concepts
Example
References
Conclusion.
TinyOS Execution Contexts
events
Tasks
commands
Interrupts
Hardware
Events generated by interrupts preempt tasks
Tasks do not preempt tasks
Both essential process state transitions
nesC
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.
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”.
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
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
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;
}
C1
C2
C3
C2
C3
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
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
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
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();”
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);
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
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;
}
Blink.nc(Complete configuration)
© Copyright 2026 Paperzz