Tinyos PDF
Tinyos PDF
Ø Critique #1
q D. Gay, P. Levis, R. von Behren, M. Welsh, E. Brewer, and D. Culler, The nesC
Language: A Holistic Approach to Networked Embedded Systems, ACM
Conference on Programming Language Design and Implementation (PLDI),
June 2003.
q Due on 1/30 (Tuesday)
1
IoT Operating Systems
Chenyang Lu
2
TinyOS and nesC
Ø TinyOS: OS for wireless sensor networks.
Ø nesC: programming language for TinyOS.
Chenyang Lu 3
Mica2 Mote
Chenyang Lu 4
Epic Core
3V
I/O (some shared)
RAM 10 KB 8 ADC (12 bit)
2 DAC (12 bit)
Flash 48 KB 1 I2C Unique
2.5 x 2.5 cm 1 JTAG hardware ID
1 1-Wire
TI MSP430 2 SPI
2 UART
CC2420 radio
802.15.4 16 MB
6LoWPAN/IPv6 Clock 4/8 MHz 8 general, 8 Flash memory
interrupt, and 5
special pin
connectors
5
TelosB
Ø Six major I/O devices
Ø Possible Concurrency
q I2C, SPI, ADC
Ø Energy Management
q Turn peripherals on only when needed
q Turn off otherwise
6
Hardware Constraints
Chenyang Lu 7
Software Challenges
Chenyang Lu 8
Traditional OS
Ø Multi-threaded
Ø Preemptive scheduling
Ø Threads:
q ready to run;
q executing on the CPU;
q waiting for data. executing
gets
CPU preempted needs
data
gets data
ready waiting
needs data
Chenyang Lu 9
Limitations of Traditional OS
Ø Multi-threaded + preemptive scheduling
q Preempted threads waste memory
q Context switch overhead
Ø I/O
q Blocking I/O: waste memory on blocked threads
q Polling (busy-wait): waste CPU cycles and power
Chenyang Lu 10
Example: Preemptive Priority Scheduling
Ø Each process has a fixed priority (1 highest);
Ø P1: priority 1; P2: priority 2; P3: priority 3.
P3 released
P2 released P1 released
P2 P1 P2 P3
0 10 20 30 40 50 60
time
Chenyang Lu 11
Context Switch
process 1
PC
registers
process 2
CPU
...
memory
Chenyang Lu 13
TinyOS Solutions
Ø Efficient modularity
q Application= scheduler + graph of components
q Compiled into one executable
q Only needed components are complied/loaded
Ø Concurrency: event-driven architecture
Chenyang Lu 14
Example: Surge
Sur geC
StdControl
Chenyang Lu 15
Typical Application
D. Culler et. Al., TinyOS boot camp presentation, Feb 2001
Chenyang Lu 16
Two-level Scheduling
Ø Events handle interrupts
q Interrupts trigger lowest level events
q Events can signal events, call commands, or post tasks
Ø Tasks perform deferred computations
Ø Interrupts preempt tasks and interrupts
Preempt Tasks
POST FIFO
events
commands
commands
Interrupts
Time
Hardware
Chenyang Lu 17
Multiple Data Flows
Chenyang Lu 18
Sending a Message
Chenyang Lu 19
Scheduling
Ø Interrupts preempt tasks
q Respond quickly
q Event/command implemented as function calls
Chenyang Lu 20
Space Breakdown…
3500
Interrupts
3000
Message Dispatch
Initilization
C-Runtime
2500 Scheduler: 144 Bytes code
Light Sensor
Clock Totals: 3430 Bytes code
2000
226 Bytes data
Bytes
Scheduler
1500 Led Control
Messaging Layer
1000 Packet Layer
Radio Interface
500 Routing Application
Radio Byte Encoder
0
D. Culler et. Al., TinyOS boot camp presentation, Feb 2001
Chenyang Lu 21
Power Breakdown…
Chenyang Lu 22
Time Breakdown…
Packet reception
Components work breakdown CPU Utilization Energy (nj/Bit)
AM 0.05% 0.20% 0.33
Packet 1.12% 0.51% 7.58
Radio handler 26.87% 12.16% 182.38
Radio decode thread 5.48% 2.48% 37.2
RFM 66.48% 30.08% 451.17
Radio Reception - - 1350
Idle - 54.75% -
Total 100.00% 100.00% 2028.66
Chenyang Lu 23
Advantages
Ø Small memory footprint
q Only needed components are complied/loaded
q Single stack for tasks
Ø Power efficiency
q Put CPU to sleep whenever the task queue is empty
q TinyOS 2 (ICEM) provides power management for peripherals.
Ø Efficient modularity
q Event/command interfaces between components
q Event/command implemented as function calls
Ø Concurrency-intensive operations
q Event/command + tasks
Chenyang Lu 24
Critiques
Ø Virtual memory?
Chenyang Lu 25
nesC
Ø Programming language for TinyOS and applications
Ø Static language
q No function pointer
q No malloc
q Call graph and variable access are known at compile time
Chenyang Lu 26
Application
Ø Interfaces Ø Implementation
q provides interface q module: C behavior
q uses interface q configuration: select & wire
module TimerP {
StdControl Timer provides {
interface StdControl;
TimerP interface Timer;
}
Clock uses interface Clock;
...
}
Chenyang Lu 27
Interface
interface Clock {
command error_t setRate(char interval, char scale);
event error_t fire();
}
interface Send {
command error_t send(message_t *msg, uint16_t length);
event error_t sendDone(message_t *msg, error_t success);
}
interface ADC {
command error_t getData();
event error_t dataReady(uint16_t data);
}
Chenyang Lu 28
module SurgeP {
provides interface StdControl;
uses interface ADC;
Module
uses interface Timer;
uses interface Send;
}
implementation {
bool busy;
norace uint16_t sensorReading;
async event result_t Timer.fired() {
bool localBusy;
atomic {
localBusy = busy;
busy = TRUE;
}
if (!localBusy)
call ADC.getData();
return SUCCESS;
}
async event result_t ADC.dataReady(uint16_t data) {
sensorReading = data;
post sendData();
return SUCCESS;
} ...
}
Chenyang Lu 29
Configuration
StdControl Timer
configuration TimerC {
provides {
interface StdControl;
StdControl Timer
interface Timer;
TimerP }
}
Clock
implementation {
components TimerP, HWClock;
StdControl = TimerP.StdControl;
Clock
Timer = TimerP.Timer;
HWClock
TimerP.Clock -> HWClock.Clock;
TimerC }
Chenyang Lu 30
Example: Surge
Sur geC
StdControl
Chenyang Lu 31
Concurrency
Chenyang Lu 32
A Race Condition
module SurgeP { ... }
implementation {
bool busy;
norace uint16_t sensorReading;
async event result_t Timer.fired() {
if (!busy) {
busy = TRUE;
call ADC.getData();
}
return SUCCESS;
}
task void sendData() { // send sensorReading
adcPacket.data = sensorReading;
call Send.send(&adcPacket, sizeof adcPacket.data);
return SUCCESS;
}
async event result_t ADC.dataReady(uint16_t data) {
sensorReading = data;
post sendData();
return SUCCESS;
}
Chenyang Lu 33
Atomic Sections
atomic {
<Statement list>
}
Chenyang Lu 34
Prevent Race
module SurgeP { ... }
implementation {
bool busy;
norace uint16_t sensorReading;
async event result_t Timer.fired() {
bool localBusy;
disable atomic {
interrupt
localBusy = busy;
test-and-set
busy = TRUE;
}
enable
interrupt if (!localBusy)
call ADC.getData();
return SUCCESS;
}
Chenyang Lu 35
nesC Compiler
Ø Race-free invariant: any update of a shared variable
q isfrom SC only, or
q occurs within an atomic section.
Ø Fix
q Make access to shared variables atomic.
q Move access to shared variables to tasks.
Chenyang Lu 36
Results
Ø Tested on full TinyOS code, plus applications
q 186 modules (121 modules, 65 configurations)
q 20-69 modules/app, 35 average
q 17 tasks, 75 events on average (per application) - lots of concurrency!
Ø Fixed races:
q Add atomic sections
q Post tasks (move code to task context)
Chenyang Lu 37
Optimization: Inlining
Chenyang Lu 38
Overhead for Function Calls
Ø Caller: call a function
q Push return address to stack
q Push parameters to stack
q Jump to function
Ø Callee: return
q Pop return address from stack
q Push return value to stack
q Jump back to caller
Many overhead instructions
Ø Caller: return for function calls!
q Pop return value
Chenyang Lu 39
Principles Revisited
Ø Support TinyOS components
q Interface, modules, configuration
Ø Static language
q No malloc, no function pointers
Chenyang Lu 40
Critiques
Ø No dynamic memory allocation
q Bound memory footprint
q Allow offline footprint analysis
q How to size buffer when data size varies dynamically?
Chenyang Lu 41
Commercial IoT OS
Ø Contiki: open-source, multi-threaded OS, plain C.
Chenyang Lu 42
Reading
Ø D. Gay, P. Levis, R. von Behren, M. Welsh, E. Brewer, and D. Culler, The nesC
Language: A Holistic Approach to Networked Embedded Systems.
Ø http://www.tinyos.net/
Chenyang Lu 43