Difference between revisions of "Declarative programming with MansOS"

From DiLab
Jump to: navigation, search
Line 20: Line 20:
* statements describing sensors (<code>read</code>), such as temperature, voltage or light sensors
* statements describing sensors (<code>read</code>), such as temperature, voltage or light sensors
* <code>when</code> statements - code block that start with a conditional expressions and in turn can contain blocks of other statements
* <code>when</code> statements - code block that start with a conditional expressions and in turn can contain blocks of other statements
* statements describing where the output of the system should go (<code>sendto</code>), such as serial port, radio, or network protocols
* statements describing where the output of the system should go (<code>output</code>), such as serial port, radio, or network protocols


Each of the <code>use</code>, <code>read</code>, and <code>sendto</code> statements has the following syntax:
Each of the <code>use</code>, <code>read</code>, and <code>output</code> statements has the following syntax:
&lt;statement&gt; &lt;name&gt;, &lt;parameterN&gt; [&lt;parameter1 value&gt;],
&lt;statement&gt; &lt;name&gt;, &lt;parameterN&gt; [&lt;parameter1 value&gt;],
&lt;parameter2&gt; [&lt;parameter2 value&gt;], ..., &lt;parameterN&gt; [&lt;parameterN value&gt;];
&lt;parameter2&gt; [&lt;parameter2 value&gt;], ..., &lt;parameterN&gt; [&lt;parameterN value&gt;];


For <code>sendto</code> statements, a list of packet fields can also be specified.
For <code>output</code> statements, a list of packet fields can also be specified. This list can contain:
* lt;fieldName&gt; -- a field which correspond to a sensor in the system;
* lt;fieldName&gt; lt;number&gt; -- the same, but included in the packet not once, but a ''number'' of times;
* const&lt;FieldName&gt; &lt;value&gt; - fields with constant values (for example, some ID of the mote). The names of these fields must start with "const", and they shouldn't correspond to any sensor names;
If the list is omitted, all active sensors are included in the packet.


SeAdScript supports C-style comments. Comments start with double slash ("//") and last until the end of the line.
SeAdScript supports C-style comments. Comments start with double slash ("//") and last until the end of the line.
Line 66: Line 70:
= Outputs =
= Outputs =


Specified with the <code>sendto</code> keyword.
Specified with the <code>output</code> keyword.


Examples:
Examples:
Line 82: Line 86:


The following syntax is supported:
The following syntax is supported:
sendto &lt;name&gt; {field1, field2, ..., fieldWithConstantValue1 value1, fieldWithConstantValue2 value2, ...},
output &lt;name&gt; {field1, field2, ..., fieldN &lt;timesToInclude&gt;, ... , constField1 value1, constaField2 value2, ...},
&lt;parameter1&gt; [&lt;parameter1 value&gt;], ..., &lt;parameterN&gt; [&lt;parameterN value&gt;];
&lt;parameter1&gt; [&lt;parameter1 value&gt;], ..., &lt;parameterN&gt; [&lt;parameterN value&gt;];


The field list is optional, but if present, it must be non-empty.
In this case, not all sensors in the system are included in the packet, but only the ones specified in the field list. Each name of non constant-valued field must correspond to a sensor active on the system.


= Constants (NOT SUPPORTED YET!) =
Also, if any fields with value are specified, then all packets are going to contain these fields and have them filled with the value specified.

A boolean or integer constant can be declared by using this syntax:
const &lt;name&gt; &lt;value&gt;;

Afterwards, it can be used everywhere when and scalar value is required.


= States (NOT SUPPORTED YET!) =

The language is not fully declarative, it has some statements with side effects. In particular, finite-state machine abstractions are built in the language.

A state of the system can be specified by ''state'' keyword. The syntax is:
state &lt;name&gt; [&lt;initial value&gt;];

States can take boolean or integer values, including symbolic constants.

Once declared, the state can be

Code example:
state temperatureCritical false;
when Sensors.Temperature > 50:
set temperatureCritical true;
when Sensors.Temperature < 40:
set temperatureCritical false;
when temperatureCritical:
use RedLed, period 100ms;


= Conditions (NOT SUPPORTED YET!) =
= Conditions (NOT SUPPORTED YET!) =
Line 95: Line 125:
statement1;
statement1;
statement2;
statement2;
elsewhen <condition>:
else when <condition>:
statement1;
statement1;
statement2;
statement2;
end
end


Conditions:
Condition:
* System.time - time elapsed
* System.time - time elapsed
* System.RTC - clock time, requires real time clock present on the mote
* System.RTC - clock time, requires real time clock present on the mote
* System.isDaytime - whether the current time is in day, real time clock present on the mote
* System.isDaytime - whether the current time is in day, real time clock present on the mote
* MAC.isBaseStationNearby - whether as base station is reachable via radio
* MAC.isBaseStationNearby - whether as base station is reachable via radio

== Using sensors in conditions ==

Each sensor present in the system can also be used in a condition:
when Voltage.value < 1234:
use RedLed, turn_on;

A condition can also be made on sensor failing or working correctly:
when Light.failed:
use RedLed, turn_on;
when not Light.failed:
use GreenLed, period 1s;

== Combining conditions ==

Two or more conditions can be combined together with logical connectives <code>and</code>, and <code>or</code>. If multiple are specified, <code>and</code> has higher priority. Unary <code>not </code> can also be used to invert a value of an condtion.

when <condition1> and not <condition>2:
statement1;

= Code inclusion (NOT SUPPORTED YET!) =

Both C code and configuration file fragments can be included in a SeAdScript program.

...


= Code examples =
= Code examples =
Line 125: Line 180:
read Light, period 2s;
read Light, period 2s;
sendto Serial, baudrate 38400;
output Serial, baudrate 38400;


Examples for syntactic sugar for conditions. Base case syntax:
Examples for syntactic sugar for conditions. Base case syntax:
Line 197: Line 252:
// send data to serial
// send data to serial
sendto Serial;
output Serial;
// also send data to radio
// also send data to radio
sendto Radio;
output Radio;
</pre>
</pre>


Line 234: Line 289:


// by default, output all data read to serial port; the baudrate is 38400 by default, but specify it explicitly
// by default, output all data read to serial port; the baudrate is 38400 by default, but specify it explicitly
sendto Serial, baudrate 38400;
output Serial, baudrate 38400;


// also output to radio (aggregate=yes means put all data in one packet; by default on for radio, off for serial port)
// also output to radio (aggregate=yes means put all data in one packet; by default on for radio, off for serial port)
sendto Radio, aggregate yes;
output Radio, aggregate yes;


// also output to MAC protocol, but only when a base station is detected nearby
// also output to MAC protocol, but only when a base station is detected nearby
sendto Network, protocol MAC_CSMA, when MAC.baseStationIsReachable;
output Network, protocol CSMA_MAC, when MAC.baseStationIsReachable;


// also output to higher level network-stack
// also output to higher level network-stack
sendto Network, protocol Socket, port 100;
output Network, protocol Socket, port 100;


// save light sensor values (but not humidity sensor!) to flash in case battery voltage is above 2.7V
// save light sensor values (but not humidity sensor!) to flash in case battery voltage is above 2.7V
sendto Flash {Light, APDS9300}, when System.voltage > 2.7V;
output Flash {Light, APDS9300}, when System.voltage > 2.7V;
</pre>
</pre>

Revision as of 13:34, 2 December 2011

Quick Start

Go to mansos/apps/sadlang/Blink and type

make <architecture>

in command line.

If you haven't used MansOS before, the tutorial will be helpful.

mansos/apps/sadlang/ contains Blink and other SeAdScript example applications. The file main.sl in every subfolder contains SeAdScript source code for the particular application.

Overview

SeAdScript (Sensor Application Development Script) is a declarative application specification language.

SeAdScript code is stored in files with the extension .sl.

Source file can contain the following kind of statements:

  • statements describing systems parameters (parameter), such as the routing protocol used or system's energy budget
  • statements describing actuators and other active agents (use), such as LEDs or debug output agents (use Print)
  • statements describing sensors (read), such as temperature, voltage or light sensors
  • when statements - code block that start with a conditional expressions and in turn can contain blocks of other statements
  • statements describing where the output of the system should go (output), such as serial port, radio, or network protocols

Each of the use, read, and output statements has the following syntax:

<statement> <name>, <parameterN> [<parameter1 value>],
       <parameter2> [<parameter2 value>], ..., <parameterN> [<parameterN value>];

For output statements, a list of packet fields can also be specified. This list can contain:

  • lt;fieldName> -- a field which correspond to a sensor in the system;
  • lt;fieldName> lt;number> -- the same, but included in the packet not once, but a number of times;
  • const<FieldName> <value> - fields with constant values (for example, some ID of the mote). The names of these fields must start with "const", and they shouldn't correspond to any sensor names;

If the list is omitted, all active sensors are included in the packet.

SeAdScript supports C-style comments. Comments start with double slash ("//") and last until the end of the line.

The language at the moment is case partially-sensitive - i.e. all keywords must be in small case, while identifiers are not case sensitive.

Actuators

Specified with the use keyword.

Examples:

  • Led
  • RedLed
  • GreenLed
  • BlueLed
  • Print (NOT SUPPORTED YET!)

Parameters:

  • period - toggle period
  • on_time - time when turned on, seconds after system's start
  • off_time - time when turned off, seconds after system's start
  • blink, blinkTwice, blinkTimes <n> - for LEDs

Sensors

Specified with the read keyword.

Examples:

  • Light
  • Humidity
  • Temperature (NOT SUPPORTED YET!)
  • InternalVoltage (NOT SUPPORTED YET!)
  • InternalTemperature (NOT SUPPORTED YET!)
  • ADC channels (NOT SUPPORTED YET!)

Parameters:

  • period - read period

Outputs

Specified with the output keyword.

Examples:

  • Serial port (USB)
  • Radio
  • MAC protocol
  • Network socket

Parameters:

  • aggregate - whether to send all in one packet or each value individually
  • baudrate - serial port baudrate, by default 38400
  • crc - whether to add checksum for packets, by default on for radio

Specifying individual fields

The following syntax is supported:

output <name> {field1, field2, ..., fieldN  <timesToInclude>, ... , constField1 value1, constaField2 value2, ...},
   <parameter1> [<parameter1 value>], ..., <parameterN> [<parameterN value>];

The field list is optional, but if present, it must be non-empty.

Constants (NOT SUPPORTED YET!)

A boolean or integer constant can be declared by using this syntax:

const <name> <value>;

Afterwards, it can be used everywhere when and scalar value is required.


States (NOT SUPPORTED YET!)

The language is not fully declarative, it has some statements with side effects. In particular, finite-state machine abstractions are built in the language.

A state of the system can be specified by state keyword. The syntax is:

state <name> [<initial value>];

States can take boolean or integer values, including symbolic constants.

Once declared, the state can be

Code example:

state temperatureCritical false;
when Sensors.Temperature > 50:
    set temperatureCritical true;
when Sensors.Temperature < 40:
    set temperatureCritical false;
when temperatureCritical:
    use RedLed, period 100ms;

Conditions (NOT SUPPORTED YET!)

Syntax:

when <condition>:
    statement1;
    statement2;
else when <condition>:
    statement1;
    statement2;
end

Conditions:

  • System.time - time elapsed
  • System.RTC - clock time, requires real time clock present on the mote
  • System.isDaytime - whether the current time is in day, real time clock present on the mote
  • MAC.isBaseStationNearby - whether as base station is reachable via radio

Using sensors in conditions

Each sensor present in the system can also be used in a condition:

when Voltage.value < 1234:
     use RedLed, turn_on;

A condition can also be made on sensor failing or working correctly:

when Light.failed:
     use RedLed, turn_on;
when not Light.failed:
     use GreenLed, period 1s;

Combining conditions

Two or more conditions can be combined together with logical connectives and, and or. If multiple are specified, and has higher priority. Unary not can also be used to invert a value of an condtion.

when <condition1> and not <condition>2:
    statement1;

Code inclusion (NOT SUPPORTED YET!)

Both C code and configuration file fragments can be included in a SeAdScript program.

...

Code examples

Blink with some extras:

use RedLed, period 1s, on_time 1500ms, off_time 4500ms;

Conditional blink of all three leds:

// blink red led periodically
use RedLed, period 1000ms;
// blink green led; faster at the start
when System.time < 5s:
    use GreenLed, period 100ms;
else:
    use GreenLed, period 1000ms;
// turn on blue led once the program has started
use BlueLed, on_time 2000ms;

Light sensor reading:

read Light, period 2s;

output Serial, baudrate 38400;

Examples for syntactic sugar for conditions. Base case syntax:

when System.time < 5s:
    use BlueLed, period 100ms;
end

One-liner:

when System.time < 5s: use BlueLed, period 100ms;

Another one-liner:

use BlueLed, period 100ms, when System.time < 5s;

Else-when syntax:

when System.time < 2s:
    use BlueLed, period 100ms;
    use RedLed, period 200ms;
elsewhen System.time < 6s:
    use BlueLed, period 500ms;
    use RedLed, period 1000ms;
else:
    use BlueLed, period 2000ms;
    use RedLed, period 3000ms;
end

Just turn on a led when a constant condition is true:

when 1 < 2 use BlueLed, turn_on;

A larger example:

 // do nothing, just declare that red LED will be used in the program
 use RedLed;
 
 // red led is on when system starts
 use RedLed, turn_on;
 
 // red led is turned off when a condition is fullfilled
 // (conditions are checked in the main loop at least once per minute)
 use RedLed, turn_off, when 1 < 2;
 
 // blue led is always on in daytime
 when System.isDaytime: use BlueLed, turn_on;
 
 // blue led blinks periodically in night
 when System.isDaytime = false: use BlueLed, period 1000;
 
 // alternatively:
 when System.isDaytime:
      use BlueLed, turn_on;
 else:
      use BlueLed, period 1000;
 end
 
 // compilation error
 // when System.isDaytime = false use BlueLed, period 2000;
 
 // blink one time on radio rx
 use GreenLed, blinkOnce, when System.radioRx;
 
 // blink two times on radio rx error
 use GreenLed, blinkTwice, when System.radioRxError;

 // blink three times on radio tx
 use GreenLed, blinkTimes 3, when System.radioTx;
 
 // during daytime also read sensors
 when System.isDaytime
      read Light, period 2s;
      read Humidity, period 2s;
 end
 
 // send data to serial
 output Serial;
 
 // also send data to radio
 output Radio;

Another larger example:

// define system parameters
parameter battery 2700mAh;
parameter routingProtocol GPSR;

// blink red led periodically
use RedLed, period 1000ms;

// turn green led on once the program has started
use GreenLed, on_time 2000ms;

// blink blue led; faster at the start
when System.time < 5s:
     use BlueLed, period 100ms;
else:
     use BlueLed, period 1000ms;
end

// read onboard light sensor once every 10 seconds
read Light, period 10s;

// read a specific sensor once every 10 seconds
read APDS9300, period 10s;

// define a constant time value
const PERIOD 10s;

read Humidity, period PERIOD;

// by default, output all data read to serial port; the baudrate is 38400 by default, but specify it explicitly
output Serial, baudrate 38400;

// also output to radio (aggregate=yes means put all data in one packet; by default on for radio, off for serial port)
output Radio, aggregate yes;

// also output to MAC protocol, but only when a base station is detected nearby
output Network, protocol CSMA_MAC, when MAC.baseStationIsReachable;

// also output to higher level network-stack
output Network, protocol Socket, port 100;

// save light sensor values (but not humidity sensor!) to flash in case battery voltage is above 2.7V
output Flash {Light, APDS9300}, when System.voltage > 2.7V;