Nesc a programming language for motes l.jpg
Sponsored Links
This presentation is the property of its rightful owner.
1 / 24

nesC: A Programming Language for Motes PowerPoint PPT Presentation


  • 229 Views
  • Uploaded on
  • Presentation posted in: General

nesC: A Programming Language for Motes. David Gay, Phil Levis, Eric Brewer, Rob von Behren, Nikita Borisov, Mike Chen, David Culler Intel Research, UC Berkeley. The State of the Motes. TinyOS programs hard to write No compiler: verbose, unwieldy syntax many compile-time checks missing

Download Presentation

nesC: A Programming Language for Motes

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


nesC:A Programming Languagefor Motes

David Gay, Phil Levis, Eric Brewer, Rob von Behren, Nikita Borisov, Mike Chen, David Culler

Intel Research, UC Berkeley


The State of the Motes

  • TinyOS programs hard to write

    • No compiler:

      • verbose, unwieldy syntax

      • many compile-time checks missing

    • No support for common idioms:

      • state-machine-like programs

      • split-phase operations

      • atomicity guarantees, etc


A Long-term Solution

  • We are working on an improved language

    • Component-based

    • Better support for common idioms

      • split-phase ops, state-machines, etc

    • Clean atomicity model

  • Very much in the design/investigation stage


A Short-term Solution: nesC

  • A cleaned up language for TinyOS

  • Goals:

    • Easier to use

    • Allow whole-program optimisations

    • Base for language experimentation

  • Pronounced “nestlé”


nesC: Easier to Use

  • Nicer syntax

  • Check errors

    • Missing connections

    • Type errors in connections

    • Cycles, incorrect directions

  • Interfaces:

    • Group related functionality (caller, callee):

      • sendMsg:

        • users: call send(m), implement sendDone(m)

        • implementer: implement send(m), call sendDone(m)

    • Concise wiring


comp3

comp1:

C code

comp4

comp2:

.desc

application:

.desc

The Old Model

  • Components

    • .comp: specification

    • .C: behaviour

    • .desc: select and wire

  • specification:

    • accepts commands

    • uses commands

    • signals events

    • handles events


The Old Model, continued

  • 4 kinds of components:

    • .desc only (ex: cnt_to_leds):

      • top-level components and wiring for an application

    • .C and .comp (ex: CLOCK):

      • a component implemented in C

    • .desc and .comp (ex: GENERIC_COMM):

      • a component implemented by connecting other components

    • .C, .comp and .desc (ex: INT_TO_RFM):

      • a component implemented in C with predefined wiring to other components


comp2:

configuration

application:

configuration

The nesC Model

  • Components: 1 file

    • specification

    • implementation

      • module: C behaviour

      • configuration:select and wire

  • specification

    • provides interface

    • requires interface

comp3

comp1:

module

comp4


The nesC Model, continued

  • 2 kinds of components

    • module: was .C and .comp

    • configuration: was .desc and .comp

  • What happened to the other 2 kinds of components ?

    • .desc only (ex: cnt_to_leds):

      • use a configuration with empty specification { }

    • .C, .comp and .desc (ex: INT_TO_RFM):

      • use a configuration and module (2 files)

      • naming convention: IntToRfm (configuration), IntToRfmM (module)

      • allows module to be re-used with different wiring


Interfaces

  • Group related functionality, e.g.:

    • split-phase operation (send, sendDone)

    • standard control interface: init, power

  • Specifies bi-directional calls (defines, uses):

    interface SendMsg {

    defines command result_t send(uint16_t to, TOS_MsgPtr msg);

    uses event result_t sendDone(TOS_MsgPtr msg, result_t ok);

    }

  • if component C with interface I has function f:

    • if I is required and f is uses, C must define f

    • if I is provided and f is defines, C must define f


Some Interfaces

interface Leds {

defines {

command result_t init();

command result_t redOn();

command result_t redOff();

command result_t redToggle();

...

}

}

interface StdControl {

defines {

command result_t init();

command result_t power(char mode);

}

}

interface Clock {

defines command result_t setRate(char interval, char scale);

uses event result_t fire();

}


Some More Interfaces

interface ReceiveMsg {

uses event TOS_MsgPtr receive(TOS_MsgPtr m);

}

  • But where did the Active Message type go ?

  • But where did the ADC port go ?

interface SendMsg {

defines command result_t send(uint16_t to, TOS_MsgPtr msg);

uses event result_t sendDone(TOS_MsgPtr msg, result_t ok);

}

interface ADC {

defines command result_t getData();

defines command result_t getContinuousData();

uses event result_t dataReady(uint16_t data);

}


Specify a numeric parameter for an interface in a component:

argument value specified in configurations

dynamic dispatch (receive, sendDone), implicit argument (send)

Like the current scheme for receiving active messages

Used also for ADC ports, exclusive EEPROM access

configuration MyApp ... implementation {

uses MyMain, GenericComm;

MyMain.Msg1 -> GenericComm.Send[12];

MyMain.Msg2 -> GenericComm.Receive[99];

}

module MyMain {

requires interface Send Msg1;

requires interface Receive Msg2;

}

implementation {

event Msg2.receive(MsgPtr m) {

call Msg1.send(myMsg);

}

}

Parameterised Interfaces

interface Receive {

uses event receive(MsgPtr m);

}

interface Send {

defines command send(MsgPtr m);

uses event sendDone(MsgPtr m);

}

configuration GenericComm {

provides interface Send[char id];

provides interface Receive[char id];

}

implementation { ... }


Miscellaneous Features

  • default events and commands (cf: _NULL_FUNC)

    • some commands, events not always connected

    • specify default behaviour in the absence of connection, e.g.:

      default event TOS_MsgPtr receive(TOS_MsgPtr msg) { return msg; }

  • includes is used to include C types/constants/etc for use in an interface or component

    • these types are accessible to all components that use the interface or component

    • use, e.g., to share packet format specification across components

  • nesC source code is not preprocessed


Implementation

  • nesc1 takes a “closed” component (no interfaces) and:

    • Checks nesC errors

      • Unknown/multiply-defined interfaces, components, etc

      • Connections (missing, cyclical, type-incorrect, wrong direction)

    • Checks (most) C errors

    • Generates one C-file for the application

      • Includes only reachable code (prunes out unreachable functions)

      • Generated in reverse-topological-call-order

        • Allows gcc’s inliner to do a much better inlining job

  • avr-gcc compiles nesc1 output

    • Generated code has #line directives, so clean error messages


Status

  • Compiler complete (some bugs expected)

  • Basic infrastructure and components for Mica

    • (old) radio stack

    • ADC, Clock, Leds, EEPROM, serial port

  • Apps ported:

    • Blink, CntTo{Leds,Rfm,LedsAndRfm}, RfmToLeds

    • SenseToLeds, Chirp, Oscilloscope, EEPROMTest

    • GenericBase


Status: Code Size


Plans

  • Goal: Switch all TinyOS C code to nesC

    • Stage 1: convert all “standard” components & apps

      • Who: The TinyOS team

      • Support: Mica, Rene2, all sensor boards

    • Stage 1a: Phil Levis will “port” TOSSIM to nesC

    • Stage 1b: Eric Brewer will write porting guide, nesC tutorial

    • Stage 2: distribute nesC in next TinyOS release

    • Stage 3: discontinue support for macros/perl scripts

  • Goal: Improve nesC

    • See Eric’s talk


Open Issues

  • Naming Convention (Java-inspired)

  • Interface design

  • Revisit some component designs

  • Directory structure


Conclusions

  • nesC much nicer to use than TinyOS

    • No more obscure C compiler warnings/errors

    • No more obscure bugs due to typos

    • No more obscure infinite loops due to wiring restrictions

  • nesC produces smaller code than TinyOS

    • Prunes unreachable code

    • Inlining across component boundaries

  • The best is yet to come!

    • Short-term: multiple instantiation, better inlining selection, packet format specification

    • Long-term: language improvements for bug prevention


Packet Format Specification

  • Write a C file with the packet type:

    // IntMsg.th: The message type for IntToRfm/RfmToInt

    typedef struct {

    char val;

    int src;

    } IntMsg;

    enum {

    AM_INTMSG = 4

    };

  • Use it in nesC components via includes

  • Automatic generation of corresponding Java type and marshaller/unmarshaller


C1

C2

C3

Components

  • components

    module C1 {

    requires interface triangle;

    } implementation { ... }

    module C2 {

    provides interface triangle in;

    requires {

    interface triangle out;

    interface rectangle side; }

    } implementation { ... }

    configuration C3 {

    provides interface triangle;

    provides interface rectangle;

    } implementation { ... }


C1

C2

C2

C3

C3

Configurations

  • Connect components

    configuration app { }

    implementation {

    uses c1, c2, c3;

    c1 -> c2; // implicit interface sel.

    c2.out -> c3.triangle;

    c3 <- c2.side;

    }

  • Partial configurations:

    component c2c3 {

    provides interface triangle t1;

    }

    implementation {

    uses c2, c3;

    t1 -> c2.in;

    c2.out -> c3.triangle;

    c3 <- c2.side;

    }


“C” implementation of components

all top-level declarations private, except those specified in the components interface

module C2 {

provides interface send in;

requires interface send out;

} implementation {

enum { ready, busy } state;

command in.send(Message m) {

if (state == busy) return 0;

state = busy;

call out.send(m);

return 1;

}

event out.send_done(Message m) {

state = ready;

signal in.send_done(m);

}

...

}

Modules


  • Login