[Tinyos-2-commits] CVS: tinyos-2.x/doc/html/tutorial lesson12.html, NONE, 1.1.2.1

Henri DF henridf at users.sourceforge.net
Fri Nov 3 08:54:30 PST 2006


Update of /cvsroot/tinyos/tinyos-2.x/doc/html/tutorial
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv14653

Added Files:
      Tag: tinyos-2_0_devel-BRANCH
	lesson12.html 
Log Message:
Checking in lesson 12, by Guillermo Barrenetxea (who doesn't have write access)


--- NEW FILE: lesson12.html ---
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <title>TinyOS Tutorial Lesson 12: Network Protocols</title>
  <link href="../../stylesheets/tutorial.css" rel="stylesheet"
 type="text/css">
</head>
<body>
<div class="title">Lesson 12: Network Protocols<br>
</div>
<div class="subtitle">Last updated Nov 3 2006</div>
<p>This lesson introduces the two basic network primitives of Tinyos-2:
Dissemination and Collection.<br>
</p>
<h1>Dissemination<br>
</h1>
<p>The goal of a dissemination protocol is to reliably deliver a piece of data to every
node in the network. It allows administrators
to reconfigure, query, and reprogram a network. Reliability is
important because it makes the operation robust to temporary
disconnections or high packet loss.&nbsp; Dissemination is&nbsp; fully
explained in TEP 118.<br>
</p>
<p>In TinyOS 2.x, dissemination provides two interfaces: DisseminationValue and
DisseminationUpdate. Let's take a look at these two interfaces:<br>
</p>

<p>tos/lib/net/DisseminationUpdate.nc:<br>
</p>
<pre>interface DisseminationUpdate&lt;t&gt; {<br>  command void change(t* newVal);<br>}</pre>

<p>tos/lib/net/DisseminationValue.nc:<br>
</p>
<pre>interface DisseminationValue&lt;t&gt; {<br>  command const t* get();<br>  event void changed();<br>}</pre>
<span style="font-family: monospace;"></span>

<p>DisseminationUpdate is used by producers. The command <span
 style="font-weight: bold; font-style: italic;">DisseminationUpdate.change()</span> should be
called each time the producer wants to disseminate a new value, passing this
 new value as a parameter.<br>
DisseminationValue is for consumers. The event <span
 style="font-weight: bold; font-style: italic;">DisseminationValue.changed()</span> is
signalled each time the disseminated value is changed (the producer has
called <span style="font-weight: bold; font-style: italic;">change</span>),
and the command<span style="font-style: italic;"> <span
 style="font-weight: bold;">get</span></span> allows to obtain this new
value. <br>
</p>
We build now a simple application (EasyDissemination) where one node
(the producer) periodically disseminates the value of a counter to rest
of the nodes in the network (consumers).
As a first step, c<code></code>reate a new directory in <tt>apps</tt>
named <span style="font-family: monospace;">EasyDissemination</span>:
<pre>$ cd tinyos-2.x/apps<br>$ mkdir EasyDissemination<br></pre>
Inside this directory, create a file <code>EasyDisseminationC.nc</code>,
which
has this code:
<pre>#include &lt;Timer.h&gt;<br><br>module EasyDisseminationC {<br>  uses interface Boot;<br>  uses interface DisseminationValue&lt;uint16_t&gt; as Value;<br>  uses interface DisseminationUpdate&lt;uint16_t&gt; as Update;<br>  uses interface Leds;<br>  uses interface Timer&lt;TMilli&gt;;<br>}<br><br>implementation {<br><br>  uint16_t counter;<br><br>  task void ShowCounter() {<br>    if (counter &amp; 0x1) <br>      call Leds.led0On();<br>    else <br>      call Leds.led0Off();<br>    if (counter &amp; 0x2) <br>      call Leds.led1On();<br>    else <br>      call Leds.led1Off();<br>    if (counter &amp; 0x4) <br>      call Leds.led2On();<br>    else<br>      call Leds.led2Off();<br>  }<br>  <br>  event void Boot.booted() {<br>    counter = 0;<br>    if ( TOS_NODE_ID  == 1 ) <br>      call Timer.startPeriodic(2000);<br>  }<br><br>  event void Timer.fired() {<br>    counter = counter + 1;<br>    // show counter in leds<br>    post ShowCounter();<br>    // disseminate counter value<br>    call Update.change(&amp;counter);<br>  }<br><br>  event void Value.changed() {<br>    const uint16_t* newVal = call Value.get();<br>    // show new counter in leds<br>    counter = *newVal;<br>    post ShowCounter();<br>  }<br>}<br></pre>
We assume that the&nbsp; base station is the node with ID = 1. First
note that the base station will periodically (every 2 seconds)
increment a 3-bit counter, display the counter using its three leds,&nbsp; and disseminate it
through the network. This is done using the change command provided in
the DisseminationUpdate interface:<br>
<pre>    call Update.change(&amp;counter);</pre>
Second, note that when a node receives a change notification, it
updates its counter value and shows it on the leds:<br>
<pre>  event void Value.changed() {<br>    const uint16_t* newVal = call Value.get();<br>    // show new counter in leds<br>    counter = *newVal;<br>    post ShowCounter();<br>  }<br></pre>
The <code>EasyDisseminationAppC.nc</code>
provides the needed wiring:
<pre>configuration EasyDisseminationAppC {}<br>implementation {<br>  components EasyDisseminationC;<br><br>  components MainC;<br>  EasyDisseminationC.Boot -&gt; MainC;<br><br>  components new DisseminatorC(uint16_t, 0x1234) as Diss16C;<br>  EasyDisseminationC.Value -&gt; Diss16C;<br>  EasyDisseminationC.Update -&gt; Diss16C;<br><br>  components LedsC;<br>  EasyDisseminationC.Leds -&gt; LedsC;<br><br>  components new TimerMilliC();<br>  EasyDisseminationC.Timer -&gt; TimerMilliC;<br>}<br></pre>
<p>Note that both Dissemination interfaces we use are provided by the
module DisseminatorC. <br>
This module provides&nbsp; the Dissemination service:<br>
</p>
<p>tos/lib/net/Dissemination/DisseminationC.nc:</p>
<prehead></prehead>
<pre> generic configuration DisseminatorC(typedef t, uint16_t key) {<br>  provides interface DisseminationValue&lt;t&gt;;<br>  provides interface DisseminationUpdate&lt;t&gt;;<br>}<br></pre>
Note that we need to specify to the Disseminartor module a type t and a
key.&nbsp; In our case, the value we&nbsp; want to&nbsp; disseminate is
just an unsigned&nbsp; two-byte counter. The key allows to have
different instances of DisseminatroC. <br>
<br>
To compile this program we use create the following Makefile:<br>
<pre>COMPONENT=EasyDisseminationAppC<br>CFLAGS += -I$(TOSDIR)/lib/net<br><br>include $(MAKERULES)<br></pre>
Now install this program into several nodes (make sure you have one
base station, that is, one node whose ID is 1) and see how the counter
displayed in the base station is "disseminated" to all the nodes
belonging to the network. You will also notice that dissemination works across
resets, i.e., if you reset a node it will rapidly re-'synchronize' and display
the correct value after it reboots.
<br>
<br>
For more information, read TEP118 [Dissemination].<br>
<br>
<h1>Collection<br>
</h1>
<p>Collection is the complementary operation to disseminating and it
consists in "collecting" the data generated in the network into a base
stations. The general approach used is to build one
or more collection <em>trees</em>, each of which is rooted at a base
station. When a node has data which needs to be collected, it
sends the data up the tree, and it forwards collection data that
other nodes send to it. <br>
</p>
<p>We build now a simple application (EasyCollection) where nodes
periodically send information to a base station which collects all the
data.<br>
As a first step, c<code></code>reate a new directory in <tt>apps</tt>
named <span style="font-family: monospace;">EasyCollection</span>:
</p>
<pre>$ cd tinyos-2.x/apps<br>$ mkdir EasyCollection<br></pre>
Inside this directory, create a file <code>EasyCollectionC.nc</code>,
which
has the following code:
<pre>#include &lt;Timer.h&gt;<br><br>module EasyCollectionC {<br>  uses interface Boot;<br>  uses interface SplitControl as RadioControl;<br>  uses interface StdControl as RoutingControl;<br>  uses interface Send;<br>  uses interface Leds;<br>  uses interface Timer&lt;TMilli&gt;;<br>  uses interface RootControl;<br>  uses interface Receive;<br>}<br>implementation {<br>  message_t packet;<br>  bool sendBusy = FALSE;<br><br>  typedef nx_struct EasyCollectionMsg {<br>    nx_uint16_t data;<br>  } EasyCollectionMsg;<br><br>  event void Boot.booted() {<br>    call RadioControl.start();<br>  }<br>  <br>  event void RadioControl.startDone(error_t err) {<br>    if (err != SUCCESS)<br>      call RadioControl.start();<br>    else {<br>      call RoutingControl.start();<br>      if (TOS_NODE_ID == 1) <br>	call RootControl.setRoot();<br>      else<br>	call Timer.startPeriodic(2000);<br>    }<br>  }<br><br>  event void RadioControl.stopDone(error_t err) {}<br><br>  void sendMessage() {<br>    EasyCollectionMsg* msg = (EasyCollectionMsg*)call Send.getPayload(&amp;packet);<br>    msg-&gt;data = 0xAAAA;<br>    <br>    if (call Send.send(&amp;packet, sizeof(EasyCollectionMsg)) != SUCCESS) <br>      call Leds.led0On();<br>    else <br>      sendBusy = TRUE;<br>  }<br>  event void Timer.fired() {<br>    call Leds.led2Toggle();<br>    if (!sendBusy)<br>      sendMessage();<br>  }<br>  <br>  event void Send.sendDone(message_t* m, error_t err) {<br>    if (err != SUCCESS) <br>      call Leds.led0On();<br>    sendBusy = FALSE;<br>  }<br>  <br>  event message_t* <br>  Receive.receive(message_t* msg, void* payload, uint8_t len) {<br>    call Leds.led1Toggle();    <br>    return msg;<br>  }<br>}<br></pre>
<p>&nbsp;Lets take a look at this program. First note that all nodes
turn on the radio into the Boot sequence:<br>
</p>
<p></p>
<pre>&nbsp; event void Boot.booted() {<br>&nbsp;&nbsp;&nbsp; call RadioControl.start();<br>&nbsp; }</pre>
<p>Once we are sure that the radio is on, we start the routing sub-system
(that
is, to generate the collection <span style="font-style: italic;">tree</span>):<br>
</p>
<pre>call RoutingControl.start();</pre>
Next we need need to specify the root of the collection tree, that is,
the node that will receive all the data packets. For this, we use the
interface RootControl:<br>
tos/lib/net/RootControl.nc<br>
<pre>interface RootControl {<br>    command error_t setRoot();<br>    command error_t unsetRoot();<br>    command bool isRoot();<br>}<br></pre>
<p>This interface controls whether the current node is a root of the
tree. Using the setRoot() command and assuming that the base station ID
is 1, we select the root of the collection <span
 style="font-style: italic;">tree</span> as follows:<br>
</p>
<pre>if (TOS_NODE_ID == 1) <br>&nbsp;&nbsp;&nbsp; call RootControl.setRoot();  <br>else<br>    call Timer.startPeriodic(2000);</pre>
<p>The remaining nodes in the network periodically generate some data
and send it to the base station.&nbsp; To send and receive data we use
two interfaces that will be wired to the collection tree. That is, when
we call the send command, the data packet will be sent through the
collection tree.&nbsp; Similarly, the receive event will be only called
in the root of the tree, that is, in the base station. When the base
station receives a "collected" packet it just toggle a led.&nbsp; Now
we will see how to wire these interfaces .<br>
The <code>EasyCollectionAppC.nc</code>
provides the needed wiring:<br>
</p>
<pre>configuration EasyCollectionAppC {}<br>implementation {<br>  components EasyCollectionC, MainC, LedsC, ActiveMessageC;<br>  components CollectionC as Collector;<br>  components new CollectionSenderC(0xee);<br>  components new TimerMilliC();<br><br>  EasyCollectionC.Boot -&gt; MainC;<br>  EasyCollectionC.RadioControl -&gt; ActiveMessageC;<br>  EasyCollectionC.RoutingControl -&gt; Collector;<br>  EasyCollectionC.Leds -&gt; LedsC;<br>  EasyCollectionC.Timer -&gt; TimerMilliC;<br>  EasyCollectionC.Send -&gt; CollectionSenderC;<br>  EasyCollectionC.RootControl -&gt; Collector;<br>  EasyCollectionC.Receive -&gt; Collector.Receive[0xee];<br>}<br></pre>
<p>Most of the collection interfaces (RoutingControl, RootControl and
Receive) are provided by the CollectionC module.&nbsp; The send
interface is provided by CollectionSenderC which is
a&nbsp; virtualized collection sender abstraction module.<br>
This is an extract of the signature of the CollectionC module and
CollectionSenderC:<br>
tos/lib/net/ctp/CollectionC.nc<br>
</p>
<pre>configuration CollectionC {<br>  provides {<br>    interface StdControl;<br>    interface Send[uint8_t client];<br>    interface Receive[collection_id_t id];<br>    interface Receive as Snoop[collection_id_t];<br>    interface Intercept[collection_id_t id];<br><br>    interface Packet;<br>    interface CollectionPacket;<br>    interface CtpPacket;<br><br>    interface CtpInfo;<br>    interface CtpCongestion;<br>    interface RootControl;    <br>  }<br></pre>
<p>tos/lib/net/ctp/CollectionSenderC:<br>
</p>
<pre>  generic configuration CollectionSenderC(collection_id_t collectid) {<br>&nbsp; provides {<br>&nbsp;&nbsp;&nbsp; interface Send;<br>&nbsp;&nbsp;&nbsp; interface Packet;<br>&nbsp; }</pre>
<p>Note that the sender and receive interfaces requires a
collection_id_t to differentiate different possible collections trees. <br>
Note also that the CollectionC module provides some other
interfaces in addition to the ones used in this example. As we explained
previously, the CollectionC module generates a collection tree that
will be using for
the routing. These interfaces can be used get information or modify
this routing tree. For instance, if we want to obtain information about
this tree we use
the CtpInfo interface&nbsp; (see tos/lib/net/ctp/CtpInfo.nc) and if we
want to indicate/query if any node/sink is congested we use the
CtpCongestion interface (see tos/lib/net/ctp/CtpCongestion.nc)<br>
</p>
<p>Finally, to compile this program we create the following
Makefile:<br>
</p>
<pre>COMPONENT=EasyCollectionAppC<br>CFLAGS += -I$(TOSDIR)/lib/net \<br>          -I$(TOSDIR)/lib/net/le \<br>          -I$(TOSDIR)/lib/net/ctp<br>include $(MAKERULES)<br></pre>
Now install this program into several nodes (make sure you have one
base station, that is, one node whose ID is 1) and see how all the
packets generated in the nodes are collected in the base station.<br>
<br>
For more information, read TEP119&nbsp; [Collection].<br>
<br>
<h1>To experiment further <br>
</h1>
If you want to experiment with a more complex application take a look
at apps/test/TestNetwork/ which combines dissemination and collection
into a single application.<br>
<br>
<h1>Related Documentation</h1>
<ul>
  <li><a href="../tep108.html">TEP 118: Dissemination</a></li>
  <li><a href="../tep119.html">TEP 119: Collection</a><br>
  </li>
</ul>
<p>
</p>
<hr><br>
<center>
<p>&lt;&nbsp;<b><a href="lesson1.html">Previous Lesson</a></b> |&nbsp; <b><a
 href="index.html">Top</a></b> &nbsp;|&nbsp; <b><a href="lesson3.html">Next
Lesson </a>&nbsp;&gt;</b>
</p>
</center>
</body>
</html>



More information about the Tinyos-2-commits mailing list