370 likes | 455 Views
TinyOS Programming Boot Camp. David Culler, Jason Hill, Robert Szewczyk, Alec Woo U.C. Berkeley 2/9/2001. Plan for the Day. Quick application demos I. Composing TinyOS Applications 10:00-11:30 II. Deeper look at TOS Concepts 11:30-12:30 Lunch w/ discussion
E N D
TinyOS Programming Boot Camp David Culler, Jason Hill, Robert Szewczyk, Alec Woo U.C. Berkeley 2/9/2001
Plan for the Day • Quick application demos • I. Composing TinyOS Applications 10:00-11:30 • II. Deeper look at TOS Concepts 11:30-12:30 • Lunch w/ discussion • III. Networked Sensor HW 1:30-2:20 • IV. Current TOS Components 2:20-3:10 • V. Comm.- arbitration & routing 3:10-4:00 • VI. Hacking your own application 4:00-5:00 • discussion & feedback 5:00-6:00 Hand’s in groups for each part TOS Bootcamp Part I
Quick Demos • Array of Networked Photo sensors • Magnetometer signal analysis • Ad hoc routing TOS Bootcamp Part I
Why 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 TOS Bootcamp Part I
TOS 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 TOS Bootcamp Part I
Messaging Component Internal State Internal Tasks Commands Events TinyOS 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 don’t signal events • Either can post tasks TOS Bootcamp Part I
UART Packet Radio Packet TinyOS Application by Composition • Application = graph of components + scheduler sensing application application Routing Layer routing Messaging Layer messaging packet Radio byte UART byte Temp byte photo SW HW RFM ADC i2c bit clocks TOS Bootcamp Part I
Plan for Part I • Gloss over OS concepts • Walk through 4 small examples • cnt_to_leds => displays counter on LEDS • sensor_to_leds => displays sensor value on LEDs • cnt_to_rfm => counter as radio packet • rfm_to_leds => 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 TOS Bootcamp Part I
Example: apps/cnt_to_led.desc include modules{ MAIN; COUNTER; INT_TO_LEDS; CLOCK; }; MAIN:MAIN_SUB_INIT COUNTER:COUNTER_INIT MAIN:MAIN_SUB_START COUNTER:COUNTER_START COUNTER:COUNTER_CLOCK_EVENT CLOCK:CLOCK_FIRE_EVENT COUNTER:COUNTER_SUB_CLOCK_INIT CLOCK:CLOCK_INIT COUNTER:COUNTER_SUB_OUTPUT_INIT INT_TO_LEDS:INT_TO_LEDS_INIT COUNTER:COUNTER_OUTPUT INT_TO_LEDS:INT_TO_LEDS_OUTPUT TOS Bootcamp Part I apps/cnt_to_led.desc
generic init i/f MAIN clock i/f output i/f COUNTER CLOCK INT_TO_LEDS graphical cnt_to_led.desc main_sub_start main_sub_init counter_init counter_start counter_output clock_event counter_sub_clock_init counter_sub_output_init clock_init int_to_leds_init clock_fire_event int_to_leds_output TOS Bootcamp Part I
.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{ }; TOS Bootcamp Part I COUNTER.comp
Command Handshake: • return value == 0 • cmd not accepted or other error • Event Handshake similar Implemention: 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(COUNTER_SUB_CLOCK_INIT)(tick2ps); } TOS Bootcamp Part I COUNTER.c
COUNTER.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_COMPLETE)(char success){ return 1; } Events may propagate or call commands Generic output cmd TOS Bootcamp Part I
Quick 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 TOS Bootcamp Part I
Little 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? • -dlpt=3 (IBM thinkpad) TOS Bootcamp Part I
Little 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) TOS Bootcamp Part I
Event-driven Processing include modules{ MAIN; SENS_OUTPUT; INT_TO_LEDS; CLOCK; PHOTO; }; MAIN:MAIN_SUB_INIT SENS_OUTPUT:SENS_OUTPUT_INIT MAIN:MAIN_SUB_START SENS_OUTPUT:SENS_OUTPUT_START SENS_OUTPUT:SENS_OUTPUT_CLOCK_EVENT CLOCK:CLOCK_FIRE_EVENT SENS_OUTPUT:SENS_OUTPUT_SUB_CLOCK_INIT CLOCK:CLOCK_INIT SENS_OUTPUT:SENS_OUTPUT_SUB_OUTPUT_INIT INT_TO_LEDS:INT_TO_LEDS_INIT SENS_OUTPUT:SENS_OUTPUT_OUTPUT_COMPLETE INT_TO_LEDS:INT_TO_LEDS_DONE SENS_OUTPUT:SENS_OUTPUT_OUTPUT INT_TO_LEDS:INT_TO_LEDS_OUTPUT SENS_OUTPUT:SENS_DATA_INIT PHOTO:PHOTO_INIT SENS_OUTPUT:SENS_GET_DATA PHOTO:PHOTO_GET_DATA SENS_OUTPUT:SENS_DATA_READY PHOTO:PHOTO_DATA_READY TOS Bootcamp Part I apps/sens_to_leds.desc
Asynchronous 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); }; TOS Bootcamp Part I system/PHOTO.desc
Event 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 >> 2) &0x7); return 1; } • clock event handler initiates data collection • sensor signals data ready event • data event handler calls output command • common pattern TOS Bootcamp Part I SENS_OUTPUT.c
Working with application graphs TOS Bootcamp Part I
Component 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 TOS Bootcamp Part I
MAIN COUNTER CLOCK Alternative output device include modules{ MAIN; COUNTER; INT_TO_RFM; CLOCK; }; MAIN:MAIN_SUB_INIT COUNTER:COUNTER_INIT MAIN:MAIN_SUB_START COUNTER:COUNTER_START COUNTER:COUNTER_CLOCK_EVENT CLOCK:CLOCK_FIRE_EVENT COUNTER:COUNTER_SUB_CLOCK_INIT CLOCK:CLOCK_INIT COUNTER:COUNTER_SUB_OUTPUT_INIT INT_TO_RFM:INT_TO_RFM_INIT COUNTER:COUNTER_OUTPUT_COMPLETE INT_TO_RFM:INT_TO_RFM_COMPLETE COUNTER:COUNTER_OUTPUT INT_TO_RFM:INT_TO_RFM_OUTPUT INT_TO_RFM TOS Bootcamp Part I apps/cnt_to_rfm.desc
MAIN COUNTER LED hardware.h CLOCK Hierarchical Components • modules may also be .desc include modules{ LEDS; }; INT_TO_LEDS:INT_TO_LEDS_SUB_INIT LEDS:LEDS_INIT INT_TO_LEDS:INT_TO_LEDS_LEDy_on LEDS:YELLOW_LED_ON INT_TO_LEDS:INT_TO_LEDS_LEDy_off LEDS:YELLOW_LED_OFF INT_TO_LEDS:INT_TO_LEDS_LEDr_on LEDS:RED_LED_ON INT_TO_LEDS:INT_TO_LEDS_LEDr_off LEDS:RED_LED_OFF INT_TO_LEDS:INT_TO_LEDS_LEDg_on LEDS:GREEN_LED_ON INT_TO_LEDS:INT_TO_LEDS_LEDg_off LEDS:GREEN_LED_OFF INT_TO_LEDS hardware.h INT_TO_LEDS.desc TOS Bootcamp Part I
module 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{ }; TOS Bootcamp Part I INT_TO_LEDS.comp
More involved example: comm graph include modules{ GENERIC_COMM; }; INT_TO_RFM:INT_TO_RFM_SUB_MSG_SEND_DONE GENERIC_COMM:COMM_MSG_SEND_DONE INT_TO_RFM:INT_TO_RFM_SUB_INIT GENERIC_COMM:COMM_INIT INT_TO_RFM:INT_TO_RFM_SUB_SEND_MSG GENERIC_COMM:COMM_SEND_MSG INT_TO_RFM:INT_READING AM:AM_MSG_HANDLER_4 INT_TO_RFM.desc include modules{ AM; PACKETOBJ; SEC_DED_RADIO_BYTE; RFM; }; AM:AM_INIT GENERIC_COMM:COMM_INIT AM:AM_POWER GENERIC_COMM:COMM_POWER AM:AM_SEND_MSG GENERIC_COMM:COMM_SEND_MSG AM:AM_MSG_SEND_DONE GENERIC_COMM:COMM_MSG_SEND_DONE .... system/GENERIC_COMM.desc TOS Bootcamp Part I
MAIN CLOCK cnt_to_rfm.desc expanded COUNTER INT_TO_RFM hardware.h AM PACKETOBJ SEC_DED_RADIO_BYTE RFM hardware.h TOS Bootcamp Part I
Communication TOS Bootcamp Part I
Sending an Active Message • Declaring buffer storage in a frame • Requesting Transmission • Naming a handler • Done completion signal TOS Bootcamp Part I INT_TO_RFM.c
Message Storage • Component that originates message provides buffer • TOS_Msg type provides header and trailer wrapper, so copies are avoided • Application data referenced as msg.data TOS_FRAME_BEGIN(INT_TO_RFM_frame) { char pending; TOS_Msg msg; } TOS_FRAME_END(INT_TO_RFM_frame); typedef struct{ char val; } int_to_led_msg; INT_TO_RFM.c TOS Bootcamp Part I
access appln msg buffer cast to defined format application specific ready check build msg request transmission destination identifier get handler identifier mark busy Send 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->val = val; if (TOS_COMMAND(INT_TO_RFM_SUB_SEND_MSG)(TOS_MSG_BCAST, AM_MSG(INT_READING), &VAR(msg))) { VAR(pending) = 1; return 1; } } return 0; } msg buffer TOS Bootcamp Part I
Completion Event • Underlying message layer notifies all sending components of completion event • may need to resume activity after other’s completion • provides reference to sent buffer to identify action • Here event propagated as output done char TOS_EVENT(INT_TO_RFM_SUB_MSG_SEND_DONE)(TOS_MsgPtr sentBuffer){ if (VAR(pending) && sentBuffer == &VAR(data)) { VAR(pending) = 0; TOS_SIGNAL_EVENT(INT_TO_RFM_COMPLETE)(1); return 1; } return 0; } TOS Bootcamp Part I
Handling 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 TOS Bootcamp Part I
Declaring a handler • 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) < lifetime(handler), return incoming • otherwise, return free buffer • no free buffer => must punt operation and return incoming TOS_MsgPtr TOS_MSG_EVENT(INT_READING)(TOS_MsgPtr val){ ... return val; } TOS Bootcamp Part I
Assigning a Active Message Id include modules{ GENERIC_COMM; }; INT_TO_RFM:INT_TO_RFM_SUB_MSG_SEND_DONE GENERIC_COMM:COMM_MSG_SEND_DONE INT_TO_RFM:INT_TO_RFM_SUB_INIT GENERIC_COMM:COMM_INIT INT_TO_RFM:INT_TO_RFM_SUB_SEND_MSG GENERIC_COMM:COMM_SEND_MSG INT_TO_RFM:INT_READING AM:AM_MSG_HANDLER_4 • Application .desc binds named handler to AM_MSG_HANDLER_x INT_TO_RFM.desc TOS Bootcamp Part I
Another Example TOS_MsgPtr TOS_MSG_EVENT(INT_READING)(TOS_MsgPtr msg){ int_to_led_msg* message = (int_to_led_msg*)msg->data; TOS_CALL_COMMAND(RFM_TO_LEDS_LED_OUTPUT)(message->val); return msg; } TOS Bootcamp Part I RFM_TO_LED.c
Composition 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 => .comp • TOS_COMMAND, TOS_EVENT, TOS_FRAME, VAR • TOS_Msg, TOS_MsgPtr, TOS_MSG_EVENT, AM_MSG TOS Bootcamp Part I
Hands-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 TOS Bootcamp Part I