1.44k likes | 1.68k Views
An Introduction to nesC and TinyOS. 13/1/2007. overview NesC TinyOS Example detail. Characteristics of Network Sensors. Small physical size and low power consumption Concurrency-intensive operation multiple flows, not wait-command-respond => never poll, never block
E N D
An Introduction to nesC and TinyOS 13/1/2007
overview • NesC • TinyOS • Example • detail
Characteristics of Network Sensors • Small physical size and low power consumption • Concurrency-intensive operation • multiple flows, not wait-command-respond => never poll, never block • Limited Physical Parallelism and Controller Hierarchy • primitive direct-to-device interface • Asynchronous and synchronous devices => interleaving flows, events, energy management • Diversity in Design and Usage • application specific, not general purpose • huge device variation => efficient modularity => migration across HW/SW boundary • Robust Operation • numerous, unattended, critical => narrow interfaces sensors actuators storage network
Anatomy of a 3rd generation mote (mica2) • Constraints • 4KB RAM • 128KB Program Flash Memory • >25mA (Tx), <15uA (sleep) at 3.3V • 8MHz Microcontroller • 19.2Kbps (at 433 or 916MHz) • Other exciting details • 512KB Measurement Flash • 4KB Configuration EEPROM • 10bit ADC • 3 LEDs • 51pin expansion connector • Transmission range ~500ft outdoor • Runs on 2 AA batteries
AVR Peripherals • UART • Serial communication with the PC • SPI – Serial Peripheral Interface • Synchronous serial communication • Interface to Radio in the Mote • ADC • Analog – Digital Converter • Digitizing sensor readings • I/O Ports • General Purpose Input Output pins (GPIO) • Used to light up LEDs in Mote
Radio Power Management • Radio has very high power consumption • Tx power is range dependant - 49.5 mW (0 dBm) • Rx power is also very high - 28.8 mW • Power-down sleep mode - 0.6 uW • Above data for CC1000, 868 MHz (Check out CC1000 data-sheets for more numbers) • Radio power management critical • Idle state channel monitoring power = Rx Power • Put radio to sleep when not in use • But then, how do we know when somebody is trying to contact us ?
AVR Power Management • Low Power operation – 15 mW @ 4 MHz • Multiple Sleep Modes • Sleep Modes: Shutdown unused components • Idle Mode – 6 mW • CPU OFF, all peripherals ON • CPU “woken up” by interrupts • Power Down Mode – 75 uW • CPU and most peripherals OFF • External Interrupts, 2 Wire Interface, Watchdog ON • Power Save Mode – 120 uW • Similar to Power Down • Timer0 continues to run “asynchronously”
Typical sensor network operation • Sensing Subsystem • Keep the very low power sensors on all the time on each node in the network • Processingq power sensors interrupt (trigger) processor when “events” are identified OR • Processor wakes up periodically on clock interrupt, takes a sample from sensor, processes it, and goes back to sleep. • Radio subsystem • Processor wakes up radio when event requires collaborative processing or multi-hop routing. • Tiered architectures of above subsystems can be envisaged in other platforms
by comparison traditional ... • Highly Constrained resources • processing, storage, bandwidth, power • Applications spread over many small nodes • self-organizing Collectives • highly integrated with changing environment and network • communication is fundamental • Concurrency intensive in bursts • streams of sensor data and network traffic • Robust • inaccessible, critical operation
So, how do we write programs for motes? • Write C-style programs using a language for embedded software development (e.g., nesc) • Use a cross-compiler to build a binary image for a mote MCU (e.g., avr-gcc). • Use a programmer (e.g., uisp) to load the binary onto a mote • Event driven execution: • Messages received over radio, discrete event sensors generate interrupts when they detect things, timers go off. • We write handlers (functions) that are called in response to various events. • We write tasks to do background processing
What are TinyOS and nesC? • TinyOS is a collection of software modules that can be glued together to build applications. Examples: • GenericComm: send and receive radio packets • TimerC: start timers and get notified when they expire • ADC: sample light and temperature data, among others • UART: communicate over the serial interface • LedsC: make pretty lights blink • TinyOS is also a FIFO scheduler: • Interrupts are handled immediately • Background tasks are scheduled (put on a queue are are executed when there’s nothing more important to do) • NesC is the language in which TinyOS modules are written • To define modules and the interfaces that connect them • Can create configurations, which are hierarchies of glued together modules
TinyOS Goals (claims) • Flexibility • new sensor network nodes keep emerging • Telos, iMote, mica2, mica2Dot, etc. • Flexible hardware/software interface • Future designs may require different HW/software interfaces and may move service (MAC, e.g.) into hardware or software • Modularity • Component model • Sensor Network Challenges • Address the specific and unusual challenges of sensor networks: • limited resources, concurrency- intensive operation, a need for robustness, and application-specific requirements.
Each mote runs a single application • Properties • All memory resources are known statically • Rather than employing a general-purpose OS, applications are built from a suite of reusable system components coupled with application-specific code • The hardware/software boundary varies depending on the application and hardware platform; it is important to design software for flexible decomposition • Challenges: • Driven by interaction with the environment (interrupts) • Limited resources (motes) • Reliability • Soft real-time requirements (radio management and sensor polling) • Lacking common service • Time synchronization
The nesC programming language: moving away from perl • NesC started with a perl script • Pretended to be a lexer and parser • Offered no compile-time support for error detection • Component model wasn’t there yet • Now it is a systems programming language for motes • Interrupt-driven programming model • integrates reactivity to the environment, concurrency, and communication • Provides whole-program optimizations and compile-time data race detection (does it work?) • Does it simplify application development? • reduce code size? • eliminate many sources of potential bugs?
TinyOS • application = scheduler + graph of components • event-driven architecture • single shared stack • NO kernel, process/memory management, virtual memory
Graph of components = individual components + relations Individual components = command/event interface + behavior Behavior = Event + Command + Internal Tasks Program = graph of components + FIFO scheduler.
Application = Graph of Components Route map router sensor appln application Active Messages Serial Packet Radio Packet packet Temp photo SW HW UART Radio byte ADC byte clocks RFM bit
Modules includes Foo; module SendLightM{ provides { interface StdControl; } uses { interface ADC; interface Timer; interface SendMsg; } } implementation { #include “FooConstants.h” int x; // a frame variable task void work(){ // do something } command result_t StdControl.start(){ call Timer.start(TIMER_REPEAT, 1000); return SUCCESS; } event result_t Timer.fired(){ post work(); } } • A module has: • Frame (internal state) • Tasks (computation) • Interface (events, commands) • Frame : • one per component • statically allocated • fixed size • Keyword “includes” goes before module declaration • Semantic equivalent of #include, with caveats: No cpp directives allowed • Practical hack: put #include in implementation block • Commands and events are function calls • Application: linking/glueing interfaces (events, commands)
nesC details • clarifications: • “C” distinguishes between an interface and the component that provides it • “M” when a single component has both: a configuration, a module • 命名规则: • nesC files suffix: .nc • C stands for Configuration (Clock, ClockC) • M stands for Module (Timer, TimerC, TimerM)
nesC LED Application Counter Radio configuration configuration Application • the nesC model: • interfaces: • uses • provides • components: • modules • configurations • application:= graph of components • Why is this a good choice for a sensor net language? Component D Component F
How to periodically sense light and transmit it I know how to tell someone when some time has gone by TimerC.nc And I can transmit messages over a radio! I know how to return a light value Photo.nc GenericComm.nc
How to periodically sense light and transmit it I know how to tell someone when some time has gone by I’m the glue that ties these modules together TimerC.nc And I can transmit messages over a radio! I know how to return a light value SendLightM.nc Photo.nc GenericComm.nc
How to periodically sense light and transmit it I am a user of the services these other modules provide TimerC.nc SendLightM.nc Photo.nc GenericComm.nc
How to periodically sense light and transmit it Specifically, I use the interfaces that these modules provide TimerC.nc Timer SendLightM.nc SendMsg ADC Photo.nc GenericComm.nc
How to periodically sense light and transmit it TimerC.nc module SendLightM{ provides { interface StdControl; } uses { interface ADC; interface Timer; interface SendMsg; } } implementation { // . . . } Photo.nc GenericComm.nc
interface • 定义公共接口 • used for grouping functionality, like: • standard control interface (init, start, stop) • 描述交互: • interface provider 实现 commands • interface user 实现 events • commands:一个函数 • events: • can call commands, signal events, post tasks, • 不能由command触发事件,可能造成长时间占用处理器 • 可以抢占任务 • 事件一般是由intterutp触发的 interface Timer { // type is: TIMER_ONE_SHOT // or TIMER_REPEAT command result_t start(char type, uint32_t period); command result_t stop(); event result_t fired(); }
Interface example interface StdControl { command result_t init (); command result_t start (); command result_t stop (); } interface Timer { command result_t start (char type, uint32_t interval); command result_t stop (); event result_t fired (); } interface SendMsg { command result_t send (uint16_t addr, uint8_t len, TOS_MsgPtr p); event result_t sendDone (); } interface ReceiveMsg { event TOS_MsgPtr receive (TOS_MsgPtr m); }
Moudle • A module has: • Frame (internal state) • Tasks (computation) • Interface (events, commands) • Frame : • one per component • statically allocated • fixed size • “includes” • Commands and events are function calls • Application: linking/glueing interfaces (events, commands)
command result_t StdControl.start() { call SubControl.start(); return call Timer.start(TIMER_REPEAT, 1000); } command result_t StdControl.stop() { call SubControl.stop(); return call Timer.stop(); } event result_t Timer.fired() { cc = !cc; if (cc) call Leds.redOn(); else call Leds.redOff(); sendx(cc); return SUCCESS; } event result_t Send.sendDone(TOS_MsgPtr msg, result_t success) { if (success ==1) call Leds.greenToggle(); single? return SUCCESS; } } • Includes xx.h • module BlinkM { • provides { • interface StdControl; • } • uses { • interface Timer; • interface Leds; • interface SendMsg as Send; interface StdControl as SubControl; • } • } • implementation { • int cc =0; • TOS_Msg data; • typedef struct IntMsg { • uint16_t val; • uint16_t src; • } IntMsg; • command result_t StdControl.init() { • call Leds.init(); • return call SubControl.init(); • }
configuration Blink { • } • implementation { • components Main, BlinkM, SingleTimer, LedsC,GenericComm as Comm; • Main.StdControl -> SingleTimer.StdControl; • Main.StdControl -> BlinkM.StdControl; • BlinkM.Timer -> SingleTimer.Timer; • BlinkM.Leds -> LedsC; • BlinkM.Send -> Comm.SendMsg[4]; • BlinkM.SubControl -> Comm; }
Blink example See blink Example source Entry point Main stdControl Interface BadgeM implements stdControl interface BlinkM Leds Interface GenericComm provides interface to send a messgas and BadgeM implements the sendDone event handler. Timer Interface TimerC provides the interface for Setting timer interrupt parameters BadgeM implements the event handler for fired event LedsC TimerC Clock Interface HPLClock provides the interface for Setting timer interrupt parameters TimerC implements the event handler for fired event . . . . . . HPLClock Set Interrupt Specific parameters ISR calls clock fired Event handler LED Hardware Clock
Event and Commands in BlinkM Command Event Main Starts FIFO Function Tasks Start Start BlinkM FIFO Scheduler BlinkM timer fired Fired Start Fired event handler posts timerMhandlerfire task And singleonetimer task TimerM Schedules The task setInterval Fired HPLClock redtoggle Fired Leds Clock ISR (TOSH_INTERRUPT)
How to periodically sense light and transmit it module SendLightM{ provides { interface StdControl; } uses { interface ADC; interface Timer; interface SendMsg; } } implementation { // use timer to // periodically sample // light } configuration TimerC { provides { interface StdControl; interface Timer[uint8_t id]; } uses { // . . . } } Implementation { // manage one shot & periodic // timers }
How to periodically sense light and transmit it configuration SenseLightC { } implementation { components Main, SendLightM, TimerC; Main.StdControl -> SendLightM.StdControl; Main.StdControl -> TimerC; SendLightM.Timer -> TimerC.Timer[unique(“Timer”)]; } module SendLightM{ provides { interface StdControl; } uses { interface ADC; interface Timer; interface SendMsg; } } implementation { // use timer to // periodically sample // light } configuration TimerC { provides { interface StdControl; interface Timer[uint8_t id]; } uses { // . . . } } Implementation { // manage one shot & periodic // timers }
How to periodically sense light and transmit it interface Timer { // type is: TIMER_ONE_SHOT // or TIMER_REPEAT command result_t start(char type, uint32_t period); command result_t stop(); event result_t fired(); } configuration SenseLightC { } implementation { components Main, SendLightM, TimerC; Main.StdControl -> SendLightM.StdControl; Main.StdControl -> TimerC; SendLightM.Timer -> TimerC.Timer[unique(“Timer”)]; } module SendLightM{ provides { interface StdControl; } uses { interface ADC; interface Timer; interface SendMsg; } } implementation { // use timer to // periodically sample // light } configuration TimerC { provides { interface StdControl; interface Timer[uint8_t id]; } uses { // . . . } } Implementation { // manage one shot & periodic // timers }