Tinyos Tutorial
Tinyos Tutorial
TinyOS Tutorial
Mo Sha
CSE 520S Fall 2011
TinyOS Installation
TinyOS Community
http://www.tinyos.net/
Various installation options listed under Getting started section
make System
/opt/tinyos-2.1.1 ($TOSROOT)
apps
support
make
sdk
tools
tos
COMPONENT=[MainComponentC]
SENSORBOARD=[boardtype] # if needed
include $(MAKERULES)
make System
Useful commands
motelist
make telosb
mica2/micaz: mib510,/dev/ttyXYZ
telosb: bsl,/dev/ttyXYZ
make clean
make docs [platform]
Generate docs
10
11
C:\cygwin\bin
http://students.cec.wustl.edu/~ms31/520S/
Program mote
12
13
Homework
14
15
Outline
16
17
128KB
Instruction
EEPROM
250kbps
TI MSP430 microcontroller
2 AA
4KB Data
EEPROM
Chipcon
CC1000 radio,
38K or 19K baud,
Manchester,
315, 433, or
900MHz
Quantity:
56
19
Atmel
ATmega128L P
7.3827MHz (8 MIPS)
SPI bus
3 LEDs
UART 2
512KB
External
Flash
Memory
ADC 0-7
UART 1
I2C Bus
51 pin I/O Connector
MPR2400 MICAz
MICA2Dot interface
Serial interface
to laptop
2.4GHz
250kbps
MICA2 interface
ISPJTAG
Quantity: 7
Block data
to laptop
Quantity: 3
5V Power
Reset
21
51 pin MICA2
Interface
2 Axis
Accelerometer
22
Tone Detector
Light and
Temperature
Microphone
GPS
Accelerometer
Light
Temperature
Humidity
Barometric Pressure
2KB EEPROM Conf.
Magnetometer
Quantity: 1
Quantity: 3
23
24
Temperature/Humidity sensor
7 single-ended or 3 differential ADC
channels
6 digital I/O channels
Quantity: 1
Quantity: 15
25
26
Outline
zZz
handlePacket
readSensor
sendResponse
28
29
Components != Objects
event command
startDone()
start()
provides
SplitControl
NetworkHandlerP
provides
SplitControl
AppLogicP
NetworkHandlerP
AnotherHandlerP
ActiveMessageC
ActiveMessageC
ActiveMessageC
uses Receive
provides
Receive
ActiveMessageC
NetworkHandlerC
30
31
Interfaces
Modules
interface Receive {
event message_t * Receive(message_t * msg, void * payload,
uint8_t len);
command void * getPayload(message_t * msg, uint8_t * len);
command uint8_t payloadLength(message_t * msg);
}
33
Modules
35
Modules: Tasks
error_t retval;
retval = post handlePacket();
// retval == SUCCESS if task was scheduled, or FAIL if not
implementation {
...
task void legalTask() {
// OK
}
task bool illegalTask() {
// Error: cant have a return value!
}
task void anotherIllegalTask(bool param1) {
// Error: cant have parameters!
}
}
task1
task2
task1
task3
task1
36
37
call Leds.led0Toggle();
// Invoke the led0Toggle command on the Leds interface
InterfaceName.CommandOrEventName
e.g.
implementation {
command error_t SplitControl.start() {
// Implements SplitControls start() command
}
...
signal SplitControl.startDone();
// Invoke the startDone event handler on the SplitControl interface
39
module ExampleModuleP {
uses interface Receive;
uses interface Leds;
}
implementation {
event message_t Receive.receive(message_t * msg, void * payload,
uint8_t len) {
// Just toggle the first LED
call Leds.led0Toggle();
return msg;
}
...
}
40
41
implementation {
uint8_t sharedCounter;
implementation {
uint8_t sharedCounter;
Task is scheduled
immediately, but
executes later
}
42
43
TOSThreads
nesC can catch some, but not all, potential race conditions
If youre absolutely sure that theres no race condition (or
dont care if there is), use the norace keyword:
implementation {
norace uint8_t sharedCounter;
async event void Alarm1.fired() {
sharedCounter++;
call Alarm2.start(200);
}
async event void Alarm2.fired() {
sharedCounter--;
call Alarm1.start(200);
}
Race condition is
impossible; events
are mutually
exclusive
}
44
45
Configurations
Example-BLink
configuration NetworkHandlerC {
provides interface SplitControl;
}
implementation {
components NetworkHandlerP as NH,
ActiveMessageP as AM;
//NH.Receive -> AM.Receive;
//SplitControl = NH.SplitControl;
NH.Receive -> AM;
SplitControl = NH;
}
Three files:
1.Makefile
2.BlinkAppC.nc
3.BlinkC.nc
46
47
Makefile
BlinkAppC.nc
COMPONENT=BlinkAppC
include $(MAKERULES)
configuration BlinkAppC
{
}
implementation
{
components MainC, BlinkC, LedsC;
components new TimerMilliC() as Timer0;
components new TimerMilliC() as Timer1;
components new TimerMilliC() as Timer2;
BlinkC -> MainC.Boot;
BlinkC.Timer0 -> Timer0;
BlinkC.Timer1 -> Timer1;
BlinkC.Timer2 -> Timer2;
BlinkC.Leds -> LedsC;
}
48
BlinkC.nc
#include "Timer.h"
module BlinkC {
uses interface Timer<TMilli> as Timer0;
uses interface Timer<TMilli> as Timer1;
uses interface Timer<TMilli> as Timer2;
uses interface Leds;
uses interface Boot;
}
49
Outline
implementation
{
event void Boot.booted()
{
call Timer0.startPeriodic( 250 );
call Timer1.startPeriodic( 500 );
call Timer2.startPeriodic( 1000 );
}
event void Timer0.fired()
{
dbg("BlinkC", "Timer 0 fired @
%s.\n", sim_time_string());
call Leds.led0Toggle();
}
event void Timer1.fired() {..}
event void Timer2.fired() { }
}
50
51
High-Level Summary
52
53
AppLogicP
NetworkHandlerP
AnotherHandlerP
uses Receive
uses Receive
uses Receive
module BooleanSensorP {
provides interface Read<bool>;
}
RadioP
54
return &buffer2;
return &buffer3;
AppLogicP
NetworkHandlerP
AnotherHandlerP
uses Receive
uses Receive
uses Receive
55
RadioP
56
57
Parameterized Wiring
Parameterized Wiring
AppLogicP
Network
HandlerP
Another
HandlerP
uses Receive
uses Receive
uses Receive
RadioP
}
...
}
58
59
Unique Parameters
61
uniqueCount()
Defaults
uniqueCount(X)
module RadioP {
expands to # of times
...
unique(X) appears in
}
the application
implementation {
int16_t state[uniqueCount(RadioP) ];
...
}
}
62
63
Outline
64
65
module MyAppP {
uses interface Boot;
}
implementation {
event void Boot.booted() {
// Initialize app here
}
...
}
Message Addressing
67
68
69
Split-Phase Operation
interface AMSend {
command error_t send(am_addr_t addr, message_t * msg,
uint8_t len);
command error_t cancel(message_t * msg);
event void sendDone(message_t * msg, error_t error);
command uint8_t maxPayloadLength();
command void* getPayload(message_t * msg, uint8_t len);
}
interface Receive {
event message_t* receive(message_t * msg, void *
payload, uint8_t len);
}
}
70
71
interface Packet {
command void clear(message_t * msg);
interface AMPacket {
command am_addr_t address();
command am_group_t localGroup();
command
command
command
command
72
73
interface PacketAcknowledgements {
async command error_t requestAck(message_t* msg);
async command error_t noAck(message_t* msg);
async command bool wasAcked(message_t* msg);
}
Active Messaging
74
msg
75
Network Types
Sending a Message
typedef struct {
uint16_t field1;
bool field2;
} bad_message_t;
// Can have endianness problems
// if sent to a host with a
// different architecture
enum {
AM_SENSORREADING = 240,
};
typedef nx_struct {
nx_uint16_t field1;
nx_bool field2;
} good_message_t;
77
Sending a Message
Sending a Message
implementation {
...
message_t output;
task void sendData() {
sensor_reading_t * reading =
(sensor_reading_t *)call Packet.getPayload(&output,
sizeof(sensor_reading_t));
reading->temperature = lastTemperatureReading;
reading->humidity = lastHumidityReading;
...
}
}
78
79
Sending a Message
Receiving a Message
80
implementation {
...
event message_t * Receive.receive(message_t * msg,
void * payload, uint8_t len) {
am_addr_t from = call AMPacket.source(msg);
sensor_reading_t * data = (sensor_reading_t *)payload;
...
return msg;
}
}
81
Networking Components
Networking Components
components ActiveMessageC;
MyAppP.RadioPowerControl -> ActiveMessageC;
83
Basic Operation
84
configuration MyCtpAppC {
}
implementation {
components AppLogicP;
components CollectionC;
...
module AppLogicP {
uses interface StdControl as
RoutingControl;
uses interface RootControl;
...
}
implementation {
...
configuration MyCtpAppC {
}
implementation {
components AppLogicP;
components CollectionC;
...
85
module AppLogicP
...
uses interface
uses interface
uses interface
...
}
implementation {
...
{
Send;
Receive;
Packet;
...
Initializing CTP
86
Sending/Receiving Packets
87
Dissemination
Basic Operation
88
89
Sending Data to a PC
90
91
SomeMessage
OtherMessage
MoteIF
92
.
.
.
93
C/C++
Python
C#
94
Outline
95
97
98
Sensor Components
module MyAppP {
uses interface Read<uint16_t> as AccelX;
...
}
configuration MyAppC {
implementation {
}
...
implementation {
task void readAccelX() {
components MyAppP;
if(call AccelX.read() != SUCCESS)
components new AccelXC();
post readAccelX();
// X axis accelerator component
}
// defined by mts300 sensorboard
event void AccelX.readDone(error_t err,
MyAppP.AccelX -> AccelXC;
uint16_t reading) {
...
if(err != SUCCESS) {
}
post readAccelX();
return;
}
// Handle reading here
}
...
}
99
boards)
100
External Sensors
External Sensors
Digital I/O: wire directly into HplMsp430GeneralIOC component
interface HplMsp430GeneralIO {
command void makeInput();
command void makeOutput();
component HplMsp430GeneralIOC {
provides interface HplMsp430GeneralIO
provides interface HplMsp430GeneralIO
provides interface HplMsp430GeneralIO
provides interface HplMsp430GeneralIO
provides interface HplMsp430GeneralIO
provides interface HplMsp430GeneralIO
provides interface HplMsp430GeneralIO
provides interface HplMsp430GeneralIO
provides interface HplMsp430GeneralIO
provides interface HplMsp430GeneralIO
...
}
as
as
as
as
as
as
as
as
as
as
ADC0;
ADC1;
ADC2;
ADC3;
ADC4;
ADC5;
ADC6;
ADC7;
DAC0;
DAC1;
Outline
102
Hard-Learned Lessons
104
106
107
Defaults to 26
Command-line: CC2420_CHANNEL=xx make ...
Makefile: PFLAGS = -DCC2420_DEF_CHANNEL=xx
Defaults to 0x22
Makefile: DEFAULT_LOCAL_GROUP=xx (any 16-bit value)
(Small request: please do not use channels 12, 14, 22, or 25!)
108
109
LEDs
printf()
interface Leds {
async command void led0On();
async command void led0Off();
async command void led0Toggle();
async command void led1On();
async command void led1Off();
async command void led1Toggle();
async command void led2On();
async command void led2Off();
async command void led2Toggle();
async command uint8_t get();
async command void set(uint8_t val);
}
111
printf()
BaseStation
CFLAGS += -I$(TOSDIR)/lib/printf
java net.tinyos.tools.Listen
[-comm serial@[port]:[speed]]
java net.tinyos.tools.PrintfClient
[-comm serial@[port]:[speed]]
112
113
TOSSIM
e.g., does not emulate sensing and does not reproduce timing of
real microcontrollers
0 1 -90.80
1 0 -95.95
0 2 -97.48
2 0 -102.10
0 3 -111.33
3 0 -115.49
0 4 -104.82
40 -110.09
...
Real measurements
Samples included in TinyOS
($TOSDIR/lib/tossim/topologies)
Generate one based on various parameters
(http://www.tinyos.net/
tinyos-2.x/doc/html/tutorial/usctopologies.html)
(from 15-15-sparse-mica2-grid.txt)
115
116
Real measurements
Samples included in TinyOS
($TOSDIR/lib/tossim/noise)
-39
-98
-98
-98
-99
-98
-94
-98
...
http://docs.tinyos.net/index.php/TOSSIM_Live
(from meyer-heavy.txt)
117
118
Avrora + MSPsim
Safe TinyOS
http://compilers.cs.ucla.edu/avrora/
119
http://www.cs.utah.edu/~coop/safetinyos/
Nathan Cooprider, Will Archer, Eric Eide, David Gay, and John Regehr, Efficient
Memory Safety for TinyOS, Proceedings of 5th ACM Conference on Embedded
Networked Sensor Systems (SenSys 2007), 2007.
120
Demo Example
Three files:
1.Makefile
2.DemoMessage.h
3.DemoAppC.nc
4.DemoP.nc
121
122
Makefile
DemoMessage.h
COMPONENT=DemoAppC
include $(MAKERULES)
#ifndef __DEMOMESSAGE_H
#define __DEMOMESSAGE_H
enum
{
AM_DEMO_MSG = 231,
};
typedef nx_struct demo_msg
{
nx_uint16_t lastReading;
} demo_msg_t;
#endif
123
124
DemoAppC.nc
#include "DemoMessage.h"
configuration DemoAppC{}
implementation{
components DemoP, MainC;
DemoP.Boot -> MainC.Boot;
components LedsC;
DemoP.Leds -> LedsC;
components new HamamatsuS10871TsrC() as PhotoSensor;
DemoP.Read -> PhotoSensor;
components ActiveMessageC;
DemoP.RadioControl -> ActiveMessageC;
components new AMSenderC(AM_DEMO_MSG),
new AMReceiverC(AM_DEMO_MSG);
DemoP.AMSend -> AMSenderC;
DemoP.Receive -> AMReceiverC;
DemoP.Packet -> AMSenderC;
components new TimerMilliC();
DemoP.Timer -> TimerMilliC;
}
DemoP.nc
module DemoP
{
uses interface Boot;
uses interface Leds;
uses interface Read<uint16_t>;
uses interface SplitControl as RadioControl;
uses interface AMSend;
uses interface Receive;
uses interface Packet;
uses interface Timer<TMilli>;
}
125
126
DemoP.nc
DemoP.nc
implementation
{
message_t buf;
task void readSensor();
task void sendBuffer();
event void Boot.booted()
{
if(call RadioControl.start() != SUCCESS)
call Leds.led0On();
}
DemoP.nc
task void sendBuffer()
{
if(call AMSend.send(AM_BROADCAST_ADDR,
&buf, sizeof(demo_msg_t)) != SUCCESS)
post sendBuffer();
}
event void AMSend.sendDone(message_t * jkdsakljads, error_t err)
{
if(err != SUCCESS)
post sendBuffer();
}
event message_t * Receive.receive(message_t * m,void * payload,uint8_t size)
{
demo_msg_t * dpayload = (demo_msg_t *)payload;
call Leds.set(dpayload->lastReading / 200);
return m;
}
event void RadioControl.stopDone(error_t err) {}
129
128