introduction to tinyos programming

45
Feb 2007 TinyOS/nesC Basic Concepts 1 Introduction to TinyOS Programming Topics TinyOS execution model Async and atomic code Configuration and wiring Appendix TinyOS Programming Tips (courtesy of Prof. Phil Levis – Stanford Univ.)

Upload: jack

Post on 15-Jan-2016

57 views

Category:

Documents


0 download

DESCRIPTION

Introduction to TinyOS Programming. Topics TinyOS execution model Async and atomic code Configuration and wiring Appendix TinyOS Programming Tips (courtesy of Prof. Phil Levis – Stanford Univ.). TinyOS Process Categories. Events Commands Tasks. Application Code X. App_Y. C O M M A - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Introduction to TinyOS Programming

Feb 2007TinyOS/nesC Basic Concepts 1

Introduction to TinyOS Programming

TopicsTinyOS execution modelAsync and atomic codeConfiguration and wiring

AppendixTinyOS Programming Tips (courtesy of Prof. Phil Levis – Stanford Univ.)

Page 2: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 2 Feb 2007

TinyOS Process Categories

1. Events2. Commands3. Tasks

Application Code X

E

V

E

N

T

S

C

O

M

M

A

D

S

App_Y

App_Z

TASK

Events

Commands

Page 3: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 3 Feb 2007

TinyOS Process Categories

1. Events Time critical Interrupts cause Events (Timer, ADC, Sensors) Short duration

2. Commands Control services Sensor actuation Synchronous/asynchronous calls (split phase with callback

event)

3. Tasks Time flexible (delayed processing) Run sequentially by TOS Scheduler Run to completion with respect to other tasks

Page 4: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 4 Feb 2007

TinyOS Execution Model

E3

TOSH_SIGNAL ISR

CMD1

EVENT 1

TASK 1

CMD 2

EVENT 2

TASK2

TASK2

TASK3

T3

TinyOS Task First-in First-Out Queue & Scheduler

TASK1

POST T1

TASK1POST T2

POST T3

TASK2

TASK3

TASK3

SleepSleep

INTERRUPT

TinyOS STATE

HP

L T

inyO

S L

ayer

A

PP

Time

T3

Page 5: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 5 Feb 2007

Concurrency

Tasks and interrupts (foreground and background operations) Tasks cannot preempt other tasks Interrupts can preempt tasks Interrupts can preempt other interrupts, but not important for

this course TOSH_INTERRUPT() – interrupt allowed TOSH_SIGNAL() – interrupt forbidden

Scheduler Two level scheduling - interrupts (vector) and tasks (queue) Queue of tasks is FIFO No local state associated with tasks

Programmer must manage own internal state when tasks need it Danger: task queue overflows (because no dynamic memory) Scheduler puts processor to sleep when no event/command

is running and task queue is empty

Page 6: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 6 Feb 2007

TinyOS Execution Model (revisited)

TASK#1

TASK#2

TASK#3

TASK#n

TASK QUEUE

TASK(m)

if queue !Empty: execute TASK

Task Return

TOS KERNEL SCHEDULER

EVENT Handler

Command(s)

Call Command(B)

Return

ISR

Event Return

ADC

TIMER1

UART0

SPI

INT0

INTERRUPTVECTORs

Command(s)

Call Command(A)

Return

IF TASK QUE

EMPTY then

SLEEP

No TASKS pending

TIMER0 Time OutWakeup

INT

ER

RU

PT

INTERRUPT

SLEEP(Interrupts Enabled)

Page 7: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 7 Feb 2007

TinyOS Theory of Execution: Events & Tasks

Consequences of an event Runs to completion Preempt tasks and other

events

What can an event do? signal events call commands post tasks

Consequences of a task No preemption mechanism Keep code as small execution

pieces to not block other task too long

To run a long operations, create a separate task for each operation, rather than using on big task

What can initiate (post) tasks? Within a command Within an event, or Within another task

Page 8: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 8 Feb 2007

nesC Model

Two key concepts1. Interfaces

uses provides

2. Components modules configurations

An application is a particular system of components

What makes this good for Mote-based wireless sensors?

Component A

Component B

Component D

ComponentC

Application

configuration

Component E

Component F

Page 9: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 9 Feb 2007

Each Mote Runs a Single Application

Properties All memory resources are known statically Rather than a general-purpose OS, applications are

built from a subset of system components coupled with application-specific code

The hardware/software boundary varies depending on the application, wireless platform, and I/O devices

Challenges Driven by interaction with the environment (interrupts) Limited computational and power resources Soft real-time behavior (radio management and sensor

polling)

Page 10: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 10 Feb 2007

Applications are Written by Assembling Components

CC1000

Radio Packet

UART

Serial Packet

ADC

Temp photo

Active Messages

clocks

by

tep

ac

ke

t

Route map router sensor applicationa

pp

lic

ati

on

HW

SW

Consequence: No dynamic memory allocationReason: No way to know if system will run out of memory unless static memory checking is used.

Page 11: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 11 Feb 2007

Applications are Written by Assembling Components

Anatomy of an application Main component for initialization, start, stop Connected graph of components

Anatomy of a component Interfaces Implementation Default handlers

Page 12: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 12 Feb 2007

How Mote Apps Start

int main() { call hardwareInit(); //init hardware pins

TOSH_sched_init(); //init scheduler

call StdControl.init(); //init user app call StdControl.start(); //start user app

while(1) { TOSH_run_task(); //infinite spin loop for task }}

Page 13: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 13 Feb 2007

nesC Component Types

ComponentsComponents

ConfigurationsConfigurationsModulesModules

A collection of other components put together by “wiring” syntax.

Does not use C-like code

Can also provide and use interfaces

Provides, uses, and implements interface(s)

Contains C-like code

Page 14: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 14 Feb 2007

Why modules and configurations?

The reason for the distinction between modules and configurations is to allow a developer to “snap together” applications using pre-build components without additional programming.

For example, a developer could provide a configuration that simply wires together one or more pre-existing modules.

The idea is for developers to provide a set of components, a “library,” that can be re-used in a wide range of applications.

Page 15: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 15 Feb 2007

nesC Component Structure – General

Specification section Identified by the keyword configuration or module

List of interfaces that component uses, provides Alias interfaces as new name

Implementation section Identified by the keyword implementation

Defines internal workings May include other components

and associated “wiring”

Generalized component

Frame

Functions

implementation

provides

uses

Interface_A

Interface_B

NOTE: This model applies to both modules and configurations

configuration|module

Page 16: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 16 Feb 2007

nesC Interface

Defines interaction boundary between modules and configurations

Define “public” methods that a component can use

Provides = Exposes functionality to others

Uses = Requires another component

An interface a collection of one or more commands () and/or events ()

Interface_A Interface_B

Interface_C

FrameFunctions

Uses

configuration|module

Commands

Event

Events

Command

Provides

Event Cmd

Page 17: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 17 Feb 2007

nesC Interface usage

Interface user must implement events ()

Interface provider must implement commands ()

Used for grouping functionality, like Standard control interface (e.g., init, start, stop)

Split-phase operation (e.g., send, sendDone)

interface Send { command void send(TOS_Msg *m); event void sendDone();}

interfaceSend

MultiHopEngineM

RadioCRCPacket

Send.nc

providesuses

Page 18: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 18 Feb 2007

nesC Commands and Events

command () Passed parameters pushed

onto stack Non-blocking Return status Can call lower level

commands

event () Callback interface (Server signals client) Can call commands, post tasks, signal other events Hardware interrupt triggers are lowest level events Passed parameters pushed onto stack Can pre-empt tasks

FrameFunctions

Component

EventsCommands

Page 19: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 19 Feb 2007

Using Commands and Events with Call and Signal

call Executes a command immediately

Flow down the configuration layers Issued to lower level – uses library code

Control returns to calling component Standard C function -- parameters on

stack

signal Executes an event immediately

Flows up the configuration layers Issued to higher level -- provides callback

Control returns to signaling component Standard C function – parameters on

stack

Component1

Component3

Interface

Interface

Functionssignal event1 call command1

Component

Interface

Interface

Page 20: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 20 Feb 2007

nesC Interface Examples

module MyAppM { provides interface StdControl;

uses interface ADC; uses interface Timer; uses interface Send;}implementation { …}

interface StdControl { command void init(); command void start(); command void stop();}

interface ADC { command void getData(); event void dataReady(int data);}

interface Timer { command void start(int interval); command void stop(); event void fired();}

interface Send { command void send(TOS_Msg *m); event void sendDone();}

Page 21: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 21 Feb 2007

in /MoteWorks/tos/interfaces/

Page 22: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 22 Feb 2007

nesC Module Components

Modules implements interfaces

A Module has: Frame (internal state) Functions (computation) Interface (events, commands)

Frame Global variables and data One per component Statically allocated Fixed size

Functions Implementation of:

Commands, events, tasks Commands and Events are simply C function calls

Interface_A Interface_B

Interface_C

FrameFunctions

Uses

Provides

Component

Commands

Events

Events

Commands

Page 23: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 23 Feb 2007

nesC Module – A Bare Minimum Module

An implementation of an interface Written in C code, no wiring

module ModuleName { provides interface StdControl;}implementation { // ========== FRAME =========

// ========== FUNCTIONS ===== command result_t Std.init() { return SUCCESS; } command result_t Std.start() { return SUCCESS; } command result_t Std.stop() { return SUCCESS;}

Component

Frame

Functions

provides

module

implementation

uses

Interface_A

Interface_B

Page 24: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 24 Feb 2007

Frame State

Modules maintain local and persistent state. Module states or variables are statically allocated Each Module has a separate variable name space Variables declared in Command and Event are local and allocated on the

stack

module fooM { provides interface I1; uses interface I2;}

implementation { uint8_t count=0;

command void I1.increment() { count++; }

event uint8_t I2.get() { return count; }}

Call I1.increment(); //first callCall I1.increment(); //second callsignal I2.get(); //return 2

Page 25: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 25 Feb 2007

nesC Configuration Components

Components that are configurations are made by wiring together other components No code, just wiring

GenericConfiugration.nc

provides

configuration

uses

Interface_A

Interface_B

configuration D { provides interface_A;uses interface_B;

} implementation { components C1, C2; X = C1.X; X = C2.X;}

implementation

C1

DC2

GenericConfiguration.nc

Page 26: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 26 Feb 2007

nesC Wiring Syntax

Binds (connects) the User to an Provider’s implementation User.interface -> Provider.interface

Example MyApp_Timer.Timer -> TimerC.Timer[unique("Timer")];

Connected elements must be compatible Interface to interface, command to command, event to

event Example: you can only wire interface Send to Send,

but cannot connect Send to Receive

Page 27: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 27 Feb 2007

1. Alias or pass through linkage endpoint1 = endpoint2

2. Direct linkage, style 1 endpoint1 -> endpoint2

3. Direct linkage, style 2endpoint1 <- endpoint2

which is equivalent to: endpoint2 -> endpoint1

Three nesC Wiring Statements

configuration C { provides interface X as

Xprovider; uses interface X as Xuser;} implementation { Xuser = Xprovider;}

C.nc

C1D

C2

D1

D2

C

Page 28: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 28 Feb 2007

nesC Filename Convention

nesC file suffix: .ncC is for configuration (Clock, ClockC)

“C” distinguishes between an interface and the component that provides it

M is for module (Timer, TimerC, TimerM) “M” when a single component has both: a configuration

and a module

I is for interface? Very often, interfaces have no suffix.

interface Clock { ...}

Clock.nc

configuration ClockC { ...}

implementation {…}

ClockC.nc

interface Timer { ...}

Timer.nc

configuration TimerC { ...}

implementation {…}

TimerC.nc

module TimerM { ...}

implementation {…}

TimerM.nc

Page 29: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 29 Feb 2007

Concurrency (Review)

Tasks and interrupts (foreground and background operations) Tasks cannot preempt other tasks Interrupts can preempt tasks Interrupts can preempt other interrupts, but not important for

this course TOSH_INTERRUPT() – interrupt allowed TOSH_SIGNAL() – interrupt forbidden

Scheduler Two level scheduling - interrupts (vector) and tasks (queue) Queue of tasks is FIFO No local state associated with tasks

Programmer must manage own internal state when tasks need it Danger: task queue overflows (because no dynamic memory) Scheduler puts processor to sleep when no event/command

is running and task queue is empty

Page 30: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 30 Feb 2007

nesC Features for Concurrency

post Puts a function on a task queue Must be void foo(void)

atomic Interrupts can preempt execution Turn off interrupts with atomic{ }e.g., to implement a

semaphoreasync

Use async to tell compiler that this code can be called from an interrupt context – used to detect potential race conditions

norace Use norace to tell compiler it was wrong about a race condition

existing (the compiler usually suggests several false positives)

task void do-work() { //declares a task that does work}post do-work();

Page 31: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 31 Feb 2007

atomic Keyword

atomic keyword is used to denote a block of code that runs uninterrupted (interrupts disabled) Prevents race conditions

When should it be used? Required to update global variables that are referenced in async event handlers

Must use atomic block in all other functions and tasks where variable is referenced

nesC compiler with generate warning messages for global variables that need atomic blocks (see example below)

SensorAppM.nc:44: warning: non-atomic accesses to shared variable ‘voltage’

Page 32: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 32 Feb 2007

Shared States and atomic

atomic keyword Disables all interrupts, therefore use with caution and intention Affects code block within {…} that follows it Useful for locking a resource with a semaphore

Example

Compiles to:cli(); // disable interruptslda r1, busy // load busy to registerjnz r1, inUse // check busystr busy, 1 // set busy to true

inUse:sbi(); // enable interrupts

No interrupts will disrupt code flow

atomic {if (!busy)

busy = TRUE;}

Page 33: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 33 Feb 2007

atomic Syntax Example

From MoteWorks/tos/system/TimerM.nc

Page 34: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 34 Feb 2007

async versus sync

async Code Code that is reachable from at least one interrupt handler

sync Code Commands, events, or tasks only reachable from tasks

Any update to shared state (memory) that is reachable from asynchronous code is a potential data race. nesC reports an error for any command or event that is

asynchronous code and that was not declared with the async keyword.

This ensures that code that was not written to execute safely in an interrupt handler is not called inadvertently.

Asynchronous events must use split-phase processing and return quickly to re-enable interrupts as soon as possible Post a task for delayed processing

Page 35: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 35 Feb 2007

async Syntax

async event result_t Clock.fire() {post HandleFire();

return SUCCESS; }

tinyos-1.x/tos/system/TimerM.nc

Post task “decouples” the async event

async attribute used to indicate command or event is part of an asynchronous flow

async processes are “decoupled” by posting a task A task is always synchronous

Page 36: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 36 Feb 2007

AVR C Libraries

Atmel platforms implicitly include AVR C Libraries MoteWorks 2.0 includes avr-libc 1.2.3

Included library files <avr/io.h> Register Names, I/O read/write macros <avr/signal.h> Interrupt handlers <avr/interrupt.h> Interrupt handlers <avr/wdt.h> Watchdog timer <avr/pgmspace.h> Reading from program space <avr/eeprom.h> Internal EEPROM Read/Write

Page 37: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 37 Feb 2007

QUIZ

1. In what power state does TinyOS spend most of its time?2. What type of memory management strategy is used by

TinyOS?3. What is the purpose of the TinyOS hardware abstraction

layer?4. What are the two types of software components in

TinyOS applications?5. What is the difference between uses and provides?6. What is the difference between commands and events?

Page 38: Introduction to TinyOS Programming

Feb 2007TinyOS/nesC Basic Concepts 38

Q & A: Basic TinyOS and nesC ConceptsTopics TinyOS Architecture,

Organization, and Components nesC Programming Language TinyOS Execution Model

Appendix TinyOS 2.0 Programming Tips

(courtesy of Prof. Phil Levis – Stanford Univ.)

Page 39: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 39 Feb 2007

nesC Interface – The StdControl Interface

The StdControl interface (in /MoteWorks/tos/interfaces/StdControl.nc) is a very common interface in nesC programming.

StdControl defines three commands: init(),start(), and stop().

init() is called when a component is first initialized start() is called to execute a component stop() is called when a components is stopped init() can

be called multiple times but will never be called after either start() or stop() are called.

interface StdControl {  command result_t init();  command result_t start();  command result_t stop();}

Page 40: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 40 Feb 2007

nesC Keywords -- Specification

Keyword Description

component Building blocks of a nesC application. Can be a module or a configuration

module A basic component implemented in nesC

configuration A component made from wiring other components

interface A collection of event and command definitions

implementation Contains code & variables for module or configuration

provides Defines interfaces provided by a component

uses Defines interfaces used by a module or configuration

as Alias an interface to another name

command Direct function call exposed by an interface

event Callback message exposed by an interface

Page 41: Introduction to TinyOS Programming

Feb 2007TinyOS/nesC Basic Concepts 41

Appendix: TinyOS Programming Tips By Phil Levis guide to TinyOS 2.0 Programming Guide

Note: Not all TinyOS 2.0 concepts apply to MoteWorks

Last update: June 28, 2006

Page 42: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 42 Feb 2007

TinyOS Programming Hints – Condensed (1 of 4)

Programming Hint 1: It’s dangerous to signal events from commands, as you might cause a very long call loop, corrupt memory and crash your program.

Programming Hint 2: Keep tasks short.

Programming Hint 3: Keep code synchronous when you can. Code should be async only if its timing is very important or if it might be used by something whose timing is important.

Programming Hint 4: Keep atomic sections short, and have as few of them as possible. Be careful about calling out to other components from within an atomic section.

Programming Hint 5: Only one component should be able to modify a pointer’s data at any time. In the best case, only one component should be storing the pointer at any time.

Page 43: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 43 Feb 2007

TinyOS Programming Hints – Condensed (2 of 3)

Programming Hint 6: Allocate all state in components. If your application requirements necessitate a dynamic memory pool, encapsulate it in a component and try to limit the set of users.

Programming Hint 7: Conserve memory by using enums rather than const variables for integer constants, and don’t declare variables with an enum type.

*Programming Hint 8: In the top-level configuration of a software abstraction, auto-wire init to MainC. This removes the burden of wiring init from the programmer, which removes unnecessary work from the boot sequence and removes the possibility of bugs from forgetting to wire.

*Programming Hint 9: If a component is a usable abstraction by itself, its name should end with C. If it is intended to be an internal and private part of a larger abstraction, its name should end with P. Never wire to P components from outside your package (directory).

*TinyOS 2.0 specific

Page 44: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 44 Feb 2007

TinyOS Programming Hints – Condensed (3 of 4)

Programming Hint 10: Use the as keyword liberally.

Programming Hint 11: Never ignore combine warnings.

Programming Hint 12: If a function has an argument which is one of a small number of constants, consider defining it as a few separate functions to prevent bugs. If the functions of an interface all have an argument that’s almost always a constant within a large range, consider using a parameterized interface to save code space. If the functions of an interface all have an argument that’s a constant within a large range but only certain valid values, implement it as a parameterized interface but expose it as individual interfaces, to both minimize code size and prevent bugs.

Programming Hint 13: If a component depends on unique, then #define a string to use in a header file, to prevent bugs from string typos.*TinyOS 2.0 specific

Page 45: Introduction to TinyOS Programming

TinyOS/nesC Basic Concepts 45 Feb 2007

TinyOS Programming Hints – Condensed (4 of 4)

*Programming Hint 14: Never, ever use the “packed” attribute.

*Programming Hint 15: Always use platform independent types when defining message formats.

*Programming Hint 16: If you have to perform significant computation on a platform independent type or access it many (hundreds or more) times, then temporarily copying it to a native type can be a good idea.

*TinyOS 2.0 specific