Title: David Culler, Jason Hill, Robert Szewczyk, Alec Woo
1TinyOS Programming Boot Camp
- David Culler, Jason Hill, Robert Szewczyk, Alec
Woo - U.C. Berkeley
- 2/9/2001
2Plan for the Day
- Quick application demos
- I. Composing TinyOS Applications 1000-1130
- II. Deeper look at TOS Concepts
1130-1230 - Lunch w/ discussion
- III. Networked Sensor HW
130-220 - IV. Current TOS Components
220-310 - V. Comm.- arbitration routing
310-400 - VI. Hacking your own application 400-500
- discussion feedback
500-600 - Hands in groups for each part
3Quick Demos
- Array of Networked Photo sensors
- Magnetometer signal analysis
- Ad hoc routing
4Why an OS for Tiny Networked Sensors?
- Make program sensors networks a matter of,
well,programming - Convenient abstractions of common functionality
- Provide framework for innovation and development
- Explore OS concepts in this novel regime
- No UI, stand alone, power constrained
- Unusually application specific HW and SW
- Multiple flows, concurrency intensive bursts
- Limited peripheral control interconnect
- Extremely passive vigilance
- Robustness and unpredictability
- Systematic support for essential programming style
5TOS Approach
- Stylized programming model with extensive static
information - Program graph of TOS components
- TOS component command/event interface
behavior - Rich expression of concurrency
- Events propagate across many components
- Tasks provide internal concurrency
- Regimented storage management
- Current implementation is very simple
- Broad range of alternative execution mechanisms
6TinyOS concepts
- Program graph of components (.desc) sched.
- Component interface (.comp)
- Commands that it accepts
- Events that it signals
- Commands that it uses
- Events that it handles
- Component implementation (.c)
- Functions that implement interface
- Frame internal state
- Tasks internal concurrency
- Uses only internal namespace
- Scheduling and storage model
- Shared stack, static frames
- Events prempt tasks, tasks do not
- Events can signal events or call commands
- Commands dont signal events
- Either can post tasks
7TinyOS Application by Composition
- Application graph of components scheduler
sensing application
application
Routing Layer
routing
Messaging Layer
messaging
packet
Radio byte
Temp
UART byte
byte
photo
SW
HW
RFM
i2c
ADC
bit
clocks
8Plan for Part I
- Gloss over OS concepts
- Walk through 4 small examples
- cnt_to_leds gt displays counter on LEDS
- sensor_to_leds gt displays sensor value on LEDs
- cnt_to_rfm gt counter as radio packet
- rfm_to_leds gt display packet data on LEDs
- You will put them together to make distributed
sensor - Show you
- composing applications from components
- command/event interfaces
- event-driven execution
- active message operation
9Example apps/cnt_to_led.desc
include modules MAIN COUNTER INT_TO_LEDS CLOCK
MAINMAIN_SUB_INIT COUNTERCOUNTER_INIT
MAINMAIN_SUB_START COUNTERCOUNTER_START COUNTE
RCOUNTER_CLOCK_EVENT CLOCKCLOCK_FIRE_EVENT COUNT
ERCOUNTER_SUB_CLOCK_INIT CLOCKCLOCK_INIT COUNTE
RCOUNTER_SUB_OUTPUT_INIT INT_TO_LEDSINT_TO_LEDS_
INIT COUNTERCOUNTER_OUTPUT INT_TO_LEDSINT_TO_LED
S_OUTPUT
apps/cnt_to_led.desc
10graphical cnt_to_led.desc
main_sub_start
main_sub_init
counter_init
counter_start
clock_event
counter_output
counter_sub_clock_init
counter_sub_output_init
clock_init
int_to_leds_init
clock_fire_event
int_to_leds_output
11.comp component interface file
TOS_MODULE COUNTER ACCEPTS char
COUNTER_START(void) char COUNTER_INIT(void)
HANDLES void COUNTER_CLOCK_EVENT(void) char
COUNTER_OUTPUT_COMPLETE(char success) USES
char COUNTER_SUB_CLOCK_INIT(char interval,
char scale) char COUNTER_SUB_OUTPUT_INIT(
) char COUNTER_OUTPUT(int
value) SIGNALS
COUNTER.comp
12Implemention COUNTER.c
include "tos.h" include "COUNTER.h" //Frame
Declaration define TOS_FRAME_TYPE
COUNTER_frame TOS_FRAME_BEGIN(COUNTER_frame)
char state TOS_FRAME_END(COUNTER_frame)
//Commands accepted char TOS_COMMAND(COUNTER_INIT)
() VAR(state) 0 / initialize output
component / return TOS_CALL_COMMAND(COUNTER_SUB
_OUTPUT_INIT)() char TOS_COMMAND(COUNTER_START
)() / initialize clock component and start
event processing / return TOS_CALL_COMMAND(COUN
TER_SUB_CLOCK_INIT)(tick2ps)
COUNTER.c
13COUNTER.c - rudimentary event processing
//Events handled / Clock Event Handler
update LED state as 3-bit counter and set LEDs to
match / void TOS_EVENT(COUNTER_CLOCK_EVENT)()
VAR(state) TOS_CALL_COMMAND(COUNTER_OUTPUT)
(VAR(state)) / Output Completion Event
Handler Indicate that notification was
successful / char TOS_EVENT(COUNTER_OUTPUT_COMPLE
TE)(char success) return 1
Events may propagate or call commands Generic
output cmd
14Quick TOS summary
- TOS_FRAME_BEGIN, TOS_FRAME_END to declare a
component frame - VAR(foo) to access a
variable (foo) in the frame - TOS_COMMAND to declare a
command - TOS_CALL_COMMAND to call a command
- TOS_EVENT to declare an
event handler - TOS_SIGNAL_EVENT to signal and
event - TOS_TASK to declare a task
(part II) - TOS_POST_TASK to post a task
15Little hands on
- Makefile
- Set GROUP_ID in Makefile
- generic definitions and rules
- select application description
- DESC apps/cnt_to_leds.desc
- make clean
- make
- Programming
- seat sensor node in lab-board bay
- insert in parallel port
- make install as root or setuid uisp
- Glitches
- powered? priviledge?
- -dlpt3 (IBM thinkpad)
16Little debugging
- Select same desc in MakefilePC
- make clean
- make f MakefilePC
- run main
- use printf freely
- compiled away except in FullPC
- gdb main
- break COUNTER_INIT_COMMAND
- break COUNTER_CLOCK_EVENT_EVENT
- naming conventions?
- connections named by the implementing function
with type suffix (see super.h)
17Event-driven Processing
include modules MAIN SENS_OUTPUT INT_TO_LEDS C
LOCK PHOTO MAINMAIN_SUB_INIT
SENS_OUTPUTSENS_OUTPUT_INIT MAINMAIN_SUB_START
SENS_OUTPUTSENS_OUTPUT_START SENS_OUTPUTSENS_OU
TPUT_CLOCK_EVENT CLOCKCLOCK_FIRE_EVENT SENS_OUTPU
TSENS_OUTPUT_SUB_CLOCK_INIT CLOCKCLOCK_INIT SEN
S_OUTPUTSENS_OUTPUT_SUB_OUTPUT_INIT
INT_TO_LEDSINT_TO_LEDS_INIT SENS_OUTPUTSENS_OUTP
UT_OUTPUT_COMPLETE INT_TO_LEDSINT_TO_LEDS_DONE SE
NS_OUTPUTSENS_OUTPUT_OUTPUT INT_TO_LEDSINT_TO_LE
DS_OUTPUT SENS_OUTPUTSENS_DATA_INIT
PHOTOPHOTO_INIT SENS_OUTPUTSENS_GET_DATA
PHOTOPHOTO_GET_DATA SENS_OUTPUTSENS_DATA_READY
PHOTOPHOTO_DATA_READY
apps/sens_to_leds.desc
18Asynchronous Sensor Interface
TOS_MODULE PHOTO JOINTLY IMPLEMENTED_BY
PHOTO ACCEPTS char PHOTO_INIT(void) char
PHOTO_GET_DATA(void) char PHOTO_PWR(char
mode) SIGNALS char PHOTO_DATA_READY(int
data) USES char SUB_ADC_INIT(void) char
SUB_ADC_GET_DATA(char port) HANDLES char
PHOTO_ADC_DONE(int data)
system/PHOTO.desc
19Event Driven Sensor Data
char TOS_EVENT(SENS_OUTPUT_CLOCK_EVENT)() return
TOS_CALL_COMMAND(SENS_GET_DATA)() char
TOS_EVENT(SENS_DATA_READY)(int data)
TOS_CALL_COMMAND(SENS_OUTPUT_OUTPUT)((data gtgt 2)
0x7) return 1
- clock event handler initiates data collection
- sensor signals data ready event
- data event handler calls output command
- common pattern
SENS_OUTPUT.c
20Working with application graphs
21Component graph approach
- Efficient Modularity
- Assemble just what you need
- Narrow, robust interfaces
- Promote sharing, reuse, and innovation
- Retarget to new apps and new devices
- Facilitate interpositioning
- especially with FSMs and flows
22Alternative output device
include modules MAIN COUNTER INT_TO_RFM CLOCK
MAINMAIN_SUB_INIT COUNTERCOUNTER_INIT
MAINMAIN_SUB_START COUNTERCOUNTER_START COUNTE
RCOUNTER_CLOCK_EVENT CLOCKCLOCK_FIRE_EVENT COUNT
ERCOUNTER_SUB_CLOCK_INIT CLOCKCLOCK_INIT COUNTE
RCOUNTER_SUB_OUTPUT_INIT INT_TO_RFMINT_TO_RFM_IN
IT COUNTERCOUNTER_OUTPUT_COMPLETE
INT_TO_RFMINT_TO_RFM_COMPLETE COUNTERCOUNTER_OUT
PUT INT_TO_RFMINT_TO_RFM_OUTPUT
INT_TO_RFM
apps/cnt_to_rfm.desc
23Hierarchical Components
- modules may also be .desc
include modules LEDS INT_TO_LEDSINT_TO_LEDS
_SUB_INIT LEDSLEDS_INIT INT_TO_LEDSINT_TO_LEDS_L
EDy_on LEDSYELLOW_LED_ON INT_TO_LEDSINT_TO_LEDS_
LEDy_off LEDSYELLOW_LED_OFF INT_TO_LEDSINT_TO_LE
DS_LEDr_on LEDSRED_LED_ON INT_TO_LEDSINT_TO_LEDS
_LEDr_off LEDSRED_LED_OFF INT_TO_LEDSINT_TO_LEDS
_LEDg_on LEDSGREEN_LED_ON INT_TO_LEDSINT_TO_LEDS
_LEDg_off LEDSGREEN_LED_OFF
INT_TO_LEDS
hardware.h
INT_TO_LEDS.desc
24module with joint description
TOS_MODULE INT_TO_LEDS JOINTLY IMPLEMENTED_BY
INT_TO_LEDS ACCEPTS char INT_TO_LEDS_INIT(void)
char INT_TO_LEDS_OUTPUT(int val) USES
char INT_TO_LEDS_SUB_INIT(void) char
INT_TO_LEDS_LEDy_on(void) char
INT_TO_LEDS_LEDy_off(void) char
INT_TO_LEDS_LEDr_on() char
INT_TO_LEDS_LEDr_off() char
INT_TO_LEDS_LEDg_on() char
INT_TO_LEDS_LEDg_off() SIGNALS
INT_TO_LEDS.comp
25More involved example comm graph
include modules GENERIC_COMM INT_TO_RFMINT_
TO_RFM_SUB_MSG_SEND_DONE GENERIC_COMMCOMM_MSG_SEN
D_DONE INT_TO_RFMINT_TO_RFM_SUB_INIT
GENERIC_COMMCOMM_INIT INT_TO_RFMINT_TO_RFM_SUB_S
END_MSG GENERIC_COMMCOMM_SEND_MSG INT_TO_RFMINT_
READING AMAM_MSG_HANDLER_4
INT_TO_RFM.desc
include modules AM PACKETOBJ
SEC_DED_RADIO_BYTE RFM AMAM_INIT
GENERIC_COMMCOMM_INIT AMAM_POWER
GENERIC_COMMCOMM_POWER AMAM_SEND_MSG
GENERIC_COMMCOMM_SEND_MSG AMAM_MSG_SEND_DONE
GENERIC_COMMCOMM_MSG_SEND_DONE ....
system/GENERIC_COMM.desc
26cnt_to_rfm.desc expanded
COUNTER
INT_TO_RFM
hardware.h
AM
PACKETOBJ
SEC_DED_RADIO_BYTE
RFM
hardware.h
27Communication
28Sending an Active Message
- Declaring buffer storage in a frame
- Requesting Transmission
- Naming a handler
- Done completion signal
INT_TO_RFM.c
29Message Storage
TOS_FRAME_BEGIN(INT_TO_RFM_frame) char
pending TOS_Msg msg TOS_FRAME_END(INT_TO_RF
M_frame) typedef struct char val
int_to_led_msg
- Component that originates message provides buffer
- TOS_Msg type provides header and trailer wrapper,
so copies are avoided - Application data referenced as msg.data
INT_TO_RFM.c
30Send Message
char TOS_COMMAND(INT_TO_RFM_OUTPUT)(int
val) int_to_led_msg message
(int_to_led_msg)VAR(msg).data if
(!VAR(pending)) message-gtval val if
(TOS_COMMAND(INT_TO_RFM_SUB_SEND_MSG)(TOS_MSG_BCAS
T, AM_MSG(INT_READING), VAR(msg)))
VAR(pending) 1 return 1 return
0
msg buffer
31Completion Event
char TOS_EVENT(INT_TO_RFM_SUB_MSG_SEND_DONE)(TOS_M
sgPtr sentBuffer) if (VAR(pending)
sentBuffer VAR(data)) VAR(pending)
0 TOS_SIGNAL_EVENT(INT_TO_RFM_COMPLETE)(1)
return 1 return 0
- Underlying message layer notifies all sending
components of completion event - may need to resume activity after others
completion - provides reference to sent buffer to identify
action - Here event propagated as output done
32Handling Active Messages
- Declaring a handler
- TOS_MSG_EVENT
- Firing a handler
- automatic upon arrival of corresponding message
- behaves like any other event
- Buffer management
- strict ownership exchange
33Declaring a handler
TOS_MsgPtr TOS_MSG_EVENT(INT_READING)(TOS_MsgPtr
val) ... return val
- Declared using TOS_MSG_EVENT
- Gains ownership to buffer passed in msg
- accessed as val.data
- MUST return ownership to a buffer
- If lifetime(buffer) lt lifetime(handler), return
incoming - otherwise, return free buffer
- no free buffer gt must punt operation and return
incoming
34Assigning a Active Message Id
include modules GENERIC_COMM INT_TO_RFMINT_
TO_RFM_SUB_MSG_SEND_DONE GENERIC_COMMCOMM_MSG_SEN
D_DONE INT_TO_RFMINT_TO_RFM_SUB_INIT
GENERIC_COMMCOMM_INIT INT_TO_RFMINT_TO_RFM_SUB_S
END_MSG GENERIC_COMMCOMM_SEND_MSG INT_TO_RFMINT_
READING AMAM_MSG_HANDLER_4
INT_TO_RFM.desc
- Application .desc binds named handler to
AM_MSG_HANDLER_x
35Another Example
TOS_MsgPtr TOS_MSG_EVENT(INT_READING)(TOS_MsgPtr
msg) int_to_led_msg message
(int_to_led_msg)msg-gtdata TOS_CALL_COMMAND(RFM_
TO_LEDS_LED_OUTPUT)(message-gtval) return msg
RFM_TO_LED.c
36Composition Summary
- Application described by a graph of modules
- module may be component or description
- description may be rooted in a component
- Current Release Structure
- tos4.2 application components (including
Makefile) - tos4.2/apps application descriptions
- tos4.2/system system components
- Command/Event interface gt .comp
- TOS_COMMAND, TOS_EVENT, TOS_FRAME, VAR
- TOS_Msg, TOS_MsgPtr, TOS_MSG_EVENT, AM_MSG
37Hands-On Exercises for Part I
- Basic communication
- Build node as cnt_to_rfm
- Build 2nd node as rfm_to_led
- Convince yourself that the two work
- set aside the rfm_to_led node
- Basic Sensor
- Build node as sens_to_leds
- convince yourself that it works.
- Build your own sens_to_rfm.desc
- turn on the rfm_to_led node
- demonstrate a working wireless, distributed
sensor - hint1 .desc files are enough
- hint2 build sens_to_led_and_rfm.desc to debug