]> oss.titaniummirror.com Git - tinyos-2.x.git/commitdiff
Update to tutorials to redirect them to the wiki now instead of directly being modifi...
authorklueska <klueska>
Mon, 28 Jan 2008 05:59:55 +0000 (05:59 +0000)
committerklueska <klueska>
Mon, 28 Jan 2008 05:59:55 +0000 (05:59 +0000)
15 files changed:
doc/html/tutorial/index.html
doc/html/tutorial/lesson1.html
doc/html/tutorial/lesson10.html
doc/html/tutorial/lesson11.html
doc/html/tutorial/lesson12.html
doc/html/tutorial/lesson13.html
doc/html/tutorial/lesson15.html
doc/html/tutorial/lesson16.html
doc/html/tutorial/lesson2.html
doc/html/tutorial/lesson3.html
doc/html/tutorial/lesson4.html
doc/html/tutorial/lesson5.html
doc/html/tutorial/lesson6.html
doc/html/tutorial/lesson7.html
doc/html/tutorial/lesson8.html

index 5e9cd27e1d3ec62bbd8843feb65b999b1a466008..5597c265ce42d146d058e2751d2b0f776df2ef27 100644 (file)
-<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
-<html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" ^M   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
-  <title>TinyOS Tutorial</title>
-  <link href="../../stylesheets/tutorial.css" rel="stylesheet" type="text/css">
+<title>klueska.com</title>
 </head>
-
+<frameset>
+<frame src="http://docs.tinyos.net/index.php/TinyOS_Tutorials" name="redir_frame" />
+<noframes>
 <body>
-
-      <div class="title">TinyOS 2.0 Tutorials </div>
-      <div class="subtitle">Last updated 30 Aug 2007</div>
-
-         <p>
-      These brief tutorials are intended to get you started with TinyOS. They show
-      you the basics of writing, compiling, and installing TinyOS applications.
-      They introduce the basic TinyOS abstractions: computation, communication,
-      sensing, and storage. The later tutorials go a little deeper into some of
-      the more advanced areas of TinyOS, such as handling interrupts,
-      power management, and how platforms are organized.
-      </p>
-      
-      <h1><a href="lesson1.html">Lesson 1: TinyOS</a></h1>
-      
-      <dd>Lesson 1 introduces the major concepts of TinyOS: components, modules,
-       configurations and interfaces. It shows you how to compile and install
-       a TinyOS program on a mote.
-      </dd>
-
-      <h1><a href="lesson2.html">Lesson 2: Modules and the TinyOS Execution Model</a></h1>
-      
-      <dd>Lesson 2 explains the TinyOS execution model, looking more closely
-       at modules. It explains events, commands and their relationships to
-       interfaces in greater depth, introducing split-phase operations.
-       It explains tasks, the basic mechanism in TinyOS for components to
-       cooperatively share the processor.
-      </dd>
-
-      <h1><a href="lesson3.html">Lesson 3: Mote-mote radio communication</a></h1>
-      
-      <dd> Lesson 3 introduces the TinyOS communication model. There is an exercise that
-       illustrates sending and receiving messages.
-      </dd>
-
-      <h1><a href="lesson4.html">Lesson 4: Mote-PC serial communication and SerialForwarder</a></h1>
-      
-      <dd> Lesson 4 introduces the the TinyOS toolchain for PCs
-           and laptops to communicate with motes. It describes the
-           concept of a packet source, the <code>mig</code> tool,
-           and SerialForwarder.
-      </dd>
-
-      <h1><a href="lesson5.html">Lesson 5: Sensing</a></h1>
-      
-      <dd>Lesson 5 explains how to sample sensors in TinyOS. There is an exercise that
-       periodically samples a sensor and displays the value on the leds. 
-      </dd>
-
-      <h1><a href="lesson6.html">Lesson 6: Boot Sequence</a></h1>
-      
-      <dd>Lesson 6 details the boot sequence and, in doing so, answers the question, "But where is main()?".
-      </dd>
-
-      <h1><a href="lesson7.html">Lesson 7: Storage</a></h1>
-      
-      <dd> Lesson 7 introduces the TinyOS storage model. Sample
-       applications illustrate the use of the Mount, ConfigStorage,
-       LogRead and LogWrite interfaces.  
-      </dd>
-      
-      <h1><a href="lesson8.html">Lesson 8: Resource Arbitration and Power Management</a></h1>
-
-      <dd> Lesson 8 introduces the TinyOS resource arbitration and power management model. There are two 
-      exercises in this tutorial.  The first one illustrates how to gain access to predefined shared resources.
-      The second one illustrates how to create your own shared resource.  In both tutorials, the process for controlling
-      the power states of the resource is presented.
-      </dd>
-
-<h1>Lesson 9: Concurrency</h1>
-
-<dd> Lesson 9 introduces the TinyOS concurrency model. Tasks are revisited and async code is introduced. 
-This tutorial is currently unfinished.
-</dd>
-
-<h1><a href="lesson10.html">Lesson 10: Platforms</a></h1>
-
-<dd> Lesson 10 provides a better understanding of the difference between "make
-micaz" and "make telosb," including how these commands map into underlying
-files, directories, and definitions. It is not necessary for most TinyOS
-developers, but is included as a starter's guide for people who wish to
-understand the make system better or wish to design a new platform.
-</dd>
-
-<h1><a href="lesson11.html">Lesson 11: TOSSIM</a></h1>
-
-<dd> Lesson 11 introduces TOSSIM, a TinyOS simulator. TOSSIM allows
-       you to compile your TinyOS applications into a simulation
-       framework, where you can perform reproducible tests and debug
-       your code with standard development tools.
-</dd>
-
-<h1><a href="lesson12.html">Lesson 12: Network Protocols</a></h1>
-
-<dd> Lesson 12 introduces two basic multihop protocols,
-     Dissemination and Collection. Dissemination reliably
-     delivers small data items to every node in a network,
-     while collection delivers small data items from every node
-     in a network to designated collection roots.
-</dd>
-
-<h1><a href="lesson13.html">Lesson 13: TinyOS Toolchain</a></h1>
-
-<dd> Lesson 13 describes the details of the TinyOS toolchain, including
-the build system, how to create your own Makefile, and how to find out
-more information on the various tools included with TinyOS.
-</dd>
-
-<h1>Lesson 14: Building a simple but full-featured application</h1>
-
-<dd> Lesson 14 goes through the process of building a simple anti-theft
-application using many of the features and services of TinyOS 2. Lesson 14
-is found in the tinyos-2.x/apps/AntiTheft directory. The powerpoint slides
-found there (also available in pdf form) go over the basic principles of 
-TinyOS, and show how to build the accompanying AntiTheft application. Please
-start by reading the README.txt file in the AntiTheft directory.
-
-<p>To run the AntiTheft demo you will need mica2 or micaz motes, and
-some mts310 sensor boards (you can also use mts300 boards, though you
-will lose the movement detection functionality). If you do not have this
-hardware, the slides and AntiTheft code should still provide a good
-overview of TinyOS 2.
-</dd>
-<h1><a href="lesson15.html">Lesson 15: The TinyOS printf Library</a></h1>
-
-<dd> Lesson 15 describes the details of using the TinyOS <code>printf</code> library to
-print debug messages to your PC from a TinyOS application running on a mote.
-</dd>
-
-<h1><a href="lesson16.html">Lesson 16: Writing Low Power Sensing Applications</a></h1>
-<dd>
-    This lesson demonstrates how to write low power sensing applications in TinyOS.  At 
-       any given moment, the power consumption of a wireless sensor node is a function of its
-       microcontroller power state, whether the radio, flash, and sensor peripherals are on, 
-       and what operations active peripherals are performing.  This tutorial shows you 
-       how to best utilize the features provided by TinyOS to keep the power consumption 
-       of applications that use these devices to a minumum.
-</dd>
+<p>Sorry, your browser does not support frames. Please <a href="http://docs.tinyos.net/index.php/TinyOS_Tutorials" target="_top">go here</a>.</p>
 </body>
-</html>
+</noframes>
+</frameset>
+</html>
\ No newline at end of file
index d461a6a6d63a3b85e534100481ff90a531cb679d..697767b9bc89d3eb518789f2dd0cf05491d5fff7 100644 (file)
-<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
-<html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" ^M   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
-  <title>TinyOS Tutorial Lesson 1: TinyOS Component Model</title>
-  <link href="../../stylesheets/tutorial.css" rel="stylesheet" type="text/css">
+<title>klueska.com</title>
 </head>
-
+<frameset>
+<frame src="http://docs.tinyos.net/index.php/Getting_Started_with_TinyOS" name="redir_frame" />
+<noframes>
 <body>
-
-<div class="title">Lesson 1: Getting Started with TinyOS and nesC</div>
-<div class="subtitle">Last updated April 8 2007</div>
-
-      <h1>Introduction</h1>
-
-      <p>This lesson shows you how to compile a TinyOS program and
-        install it on a mote, introduces the basic concepts and syntax of 
-       the TinyOS component model, and shows you how to generate
-        and navigate TinyOS's source code documentation.</p>
-
-      <h1>Compiling and Installing</h1>
-      
-      <p>As a first exercise, you'll compile and install a very simple
-       TinyOS application called Blink. If you don't have mote
-       hardware, you can compile it for TOSSIM, the TinyOS simulator.</p>
-      
-      <p>You compile TinyOS applications with the program
-       <tt>make</tt>.  TinyOS uses a powerful and extensible make
-       system that allows you to easily add new platforms and
-       compilation options.  The makefile system definitions are
-       located in tinyos-2.x/support/make.</p>
-
-      <p>The first step is to check that your environment is set up 
-         correctly. Run the <code>tos-check-env</code> command:</p>
-
-<pre>
-$ tos-check-env
-</pre>
-
-      <p>This script checks pretty much everything that the TinyOS
-         environment needs. Most of the warnings should be somewhat
-         self-explanatory, if you are at all accustomed to a UNIX
-         environment. If you are having trouble with warnings, your
-         best bet is to join and ask questions on the 
-         <A HREF="https://mail.millennium.berkeley.edu/mailman/listinfo/tinyos-help">tinyos-help</A> email list. It's almost always the
-         case that if you've run into a problem, someone else has too.
-         Searching the <A HREF="http://mail.millennium.berkeley.edu/pipermail/tinyos/">help archives</A> can therefore be
-         useful.</p>
-
-      <p>If your system says some command is not available, then
-         chances are you need to install the TinyOS tools (tos-*) RPM.
-         Please refer to your installation instructions. If you have
-         installed the RPM, then look in /usr/bin and /usr/local/bin
-         for tos-check-env. If you have downloaded from CVS rather than
-         used RPMs, then you need to compile and build the tools.
-         Go to <code>tinyos-2.x/tools/tinyos</code> and type:</p>
-
-<pre>
-$ configure
-$ make 
-$ make install
-</pre>
-
-      <p>On Linux systems, you will either need superuser abilities or
-         access to <code>sudo</code>  for the last command.</p>
-
-
-      <p>The second thing to check is that you have the TinyOS build system
-       enabled. This involves the MAKERULES environment variable. In a shell,
-       type</p>
-
-       <pre>
-  printenv MAKERULES
-        </pre>
-
-      <p>You should see <tt>/opt/tinyos-2.x/support/make/Makerules</tt>. If
-       your TinyOS tree is installed somewhere besides the standard place,
-       you might not see <tt>/opt</tt>, but rather a different initial path.
-       If MAKERULES is not set (printenv prints nothing), you need to set it.
-       Depending on your shell, this involves using either <tt>export</tt> (bash)
-       or <tt>setenv</tt> (csh, tcsh). If you don't know about shell environment
-       variables, this
-       <A HREF="http://www.ee.surrey.ac.uk/Teaching/Unix/unix8.html">tutorial</A>
-       should help.</p>
-       
-      <p>The make command to compile a TinyOS application is 
-       <code>make</code>&nbsp;<i>[platform]</i>, executed from the 
-       application's directory. To compile Blink, go the <code>apps/Blink</code>
-       directory and depending on which hardware you have, type <tt>make micaz</tt>,
-       <tt>make mica2</tt>, <tt>make telosb</tt>, or, for simulation, type
-       <tt>make micaz sim</tt>.</p> You should see output such as this:
-
-      <pre>
-dark /root/src/tinyos-2.x/apps/Blink -4-> make telosb
-mkdir -p build/telosb
-    compiling BlinkAppC to a telosb binary
-ncc -o build/telosb/main.exe -Os -O -mdisable-hwmul -Wall -Wshadow
--DDEF_TOS_AM_GROUP=0x7d -Wnesc-all -target=telosb -fnesc-cfile=build/telosb/app.c
--board=   BlinkAppC.nc -lm 
-    compiled BlinkAppC to build/telosb/main.exe
-            2782 bytes in ROM
-              61 bytes in RAM
-msp430-objcopy --output-target=ihex build/telosb/main.exe build/telosb/main.ihex
-    writing TOS image
-      </pre>
-
-      <p>If you compile for TOSSIM, you will see a much longer message,
-       as building TOSSIM requires several steps, such as building shared
-       libraries and scripting support.</p>
-
-      <p>If you are running Cygwin and see the error message "The procedure entry point basename could not be located in the dynamic link library cygwin1.dll" then you need to install the other Cygwin nesC RPM (step 4 of the <A HREF="../install-tinyos.html">install instructions</A> or step 2 of the <A HREF="../upgrade-tinyos.html">upgrade instructions</A>)</p>
-
-      <h2>Making sure you're invoking the right version of the nesC compiler</h2>
-
-      <p>If you see an error message along the lines of this:</p>
-
-<pre>
-BlinkAppC.nc:46: syntax error before `new'
-make: *** [exe0] Error 1
-</pre>
-
-      <p>Then you are invoking an older version of the nesc compiler. 
-         Check by typing <tt>ncc --version</tt>. You should see:</p>
-
-<pre>
-ncc: 1.2.1
-nescc: 1.2.6
-</pre>
-
-   
-      <p>Followed by some information on what version of the C compiler
-      is being used. If you see different versions than those above,
-      your compilation problems are most probably due to the fact that
-      make is invoking the wrong version. This can easily happen if 
-      you are upgrading from TinyOS 1.x. You might have passed the
-      tos-check-env because you have the right compiler on your system,
-      but for some reason make is invoking the wrong one.</p>
-
-      <p><tt>ncc</tt> is a script that invokes the full compiler, 
-      <tt>nescc</tt>. It lives in <tt>tinyos-2.x/tools/tinyos/ncc</tt>.
-      If you've installed from an RPM, then the RPM put the new
-      version of <tt>ncc</tt> in <tt>/usr/bin</tt>. You can see which
-      version make is invoking by typing <tt>which ncc</tt>:
-
-<pre>
-$ which ncc
-/usr/local/bin/ncc
-$ /usr/local/bin/ncc --version
-Unknown target mica
-Known targets for TinyOS directory /opt/tinyos-2.x/tos
-and the specified include directories are:
-none.
-</pre>
-
-      <p>In this case, the version of ncc is so old that it doesn't even
-      respond to the <tt>--version</tt> flag. In contrast,</p>
-
-<pre>
-$ /usr/bin/ncc --version
-ncc: 1.2.1
-nescc: 1.2.5
-</pre>
-
-      <p>The best solution to this problem is to move the old ncc to
-      a different name (keep in around in case you need to go back
-      to your old setup):</p>
-
-<pre>
-$ mv /usr/local/bin/ncc /usr/local/bin/ncc.old
-$ which ncc
-/usr/bin/ncc
-</pre>      
-
-      <p>You can apply the same process for <tt>nescc</tt>:</p>
-
-<pre>
-$ nescc --version
-ncc: 1.1.2
-$ which nescc
-/usr/local/bin/nescc
-$ /usr/bin/nescc --version
-nescc: 1.2.5
-$ mv /usr/local/bin/nescc /usr/local/bin/nescc.old
-$ which nescc
-/usr/bin/nescc
-</pre>
-     
-      <p>Now that we've compiled the application it's time to program the
-       mote and run it.  The next step depends on what family of mote you
-         are programming.</p>
-
-      <ul>
-        <li><A HREF="#mica">Installing on a mica-family mote</A></li>
-        <li><A HREF="#telos">Installing on a telos-family mote</A></li>
-        <li><A HREF="#tinynode">Installing on a tinynode mote</A></li>
-        <li><A HREF="#eyes">Installing on an eyesIFX-family mote</A></li>
-        <li><A HREF="#intel">Installing on an IntelMote2</A></li>
-      </ul> 
-      
-      <h2><A NAME="mica">Installing on a mica-family mote (micaz, mica2, mica2dot)</A></h2>
-      
-      <p>This example uses a Mica2 mote and the
-       serial-based programming board (<span
-         style="font-family: monospace;">mib510</span>). Instructions on how to
-       use other programming boards are <a href="programmers.html">here</a>.
-       To download your program onto the mote, place the mote board (or mote
-       and sensor stack) into the bay on the programming board, as shown
-       below. You can either supply a 3 or 5 volt supply to the connector on the
-       programming board or power the node directly. The green LED (labeled PWR)
-       on the programming board will be on when power is supplied. If you are
-       using batteries to power the mote, be sure the mote is switched on (the
-       power switch should be towards the connector). The ON/OFF switch on the
-        mib510 board should normally be left in the OFF position. Only switch it
-       to ON if you have problems programming the mote and when you are done
-       programming, switch it back to OFF (when the switch is ON the mote 
-       cannot send data to the PC). </p>
-
-      <p>Plug the 9-pin connector into the serial port of a computer
-       configured with the TinyOS tools, using a pass-through (not null-modem!) 
-       DB9 serial cable. If your computer does not have a serial port, you can
-        easily obtain DB9-serial-to-USB cables. </p>
-
-      <center>
-       <table border="0" cellspacing="2" cellpadding="3" hspace="4">
-         <tbody>
-           <tr>
-             <td><img src="img/mica-offboard.jpg" height="240" width="320"></td>
-             <td><img src="img/mica-onboard.jpg" height="240" width="320"></td>
-           </tr>
-           <tr>
-             <td><i>Mica2 mote next to the programming board</i></td>
-             <td><i>Mica2 mote connected to the programming board</i></td>
-           </tr>
-         </tbody>
-       </table>
-      </center>
-
-<p>Type: 
-<pre>make mica2 reinstall mib510,<i>serialport</i></pre>
-where <i>serialport</i> is the serial port device name. Under Windows, if
-your serial port is <tt>COM<i>n</i>:</tt>, you must use
-<tt>/dev/ttyS<i>n-1</i></tt> as the device name. On Linux, the device name
-is typically <tt>/dev/ttyS</tt><i>n</i> for a regular serial port and
-<tt>/dev/ttyUSB<i>n</i></tt> or <tt>/dev/usb/tts/<i>n</i></tt> for a
-USB-serial cable (the name depends on the Linux distribution). Additionally,
-on Linux, you will typically need to make this serial port world writeable.
-As superuser, execute the following command:
-<pre>chmod 666 <i>serialport</i></pre>
-<p>
-If the installation is successful you should see something like the
-following (if you don't, try repeating the <tt>make</tt> command): </p>
-      
-      <pre>
-cp build/mica2/main.srec build/mica2/main.srec.out
-    installing mica2 binary using mib510
-uisp -dprog=mib510 -dserial=/dev/ttyUSB1 --wr_fuse_h=0xd9 -dpart=ATmega128 
-     --wr_fuse_e=ff  --erase --upload if=build/mica2/main.srec.out
-Firmware Version: 2.1
-Atmel AVR ATmega128 is found.
-Uploading: flash
-
-Fuse High Byte set to 0xd9
-
-Fuse Extended Byte set to 0xff
-rm -f build/mica2/main.exe.out build/mica2/main.srec.out
-      </pre>
-
-
-       <A name="#telos"><h2>Installing on telos-family mote (telosa, telosb)</h2></A>
-<p>Telos motes are USB devices, and can be plugged into any USB port:
-      <center>
-       <table border="0" cellspacing="2" cellpadding="3" hspace="4">
-         <tbody>
-           <tr>
-             <td><img src="img/telos.jpg" height="240" width="320"></td>
-             <td><img src="img/telos2.jpg" height="240" width="320"></td>
-           </tr>
-           <tr>
-             <td><i>Telos mote</i></td>
-             <td><i>Telos mote plugged into a USB port</i></td>
-           </tr>
-         </tbody>
-       </table>
-      </center>
-       
-      <p>Because Telos motes are USB devices, they register with
-         your OS when you plug them in. Typing <code>motelist</code>
-         will display which nodes are currently plugged in:</p>
-<pre>
-$ motelist
-Reference  CommPort   Description
----------- ---------- ----------------------------------------
-UCC89MXV   COM4       Telos (Rev B 2004-09-27)
-</pre>
-
-<p><i>motelist</i> tells you which ports have motes attached. Under
-Windows, it displays the mote's COM port (in this case 4), under Linux it
-displays just the USB serial port number (e.g., 2). Confusingly, the
-Windows version of the code installer (<tt>tos-bsl</tt>) takes the COM port
-number - 1 as it's argument (in this case 3); under Linux it takes the USB
-device name (e.g., /dev/ttyUSB2 or /dev/tts/usb/2 if motelist reports that
-the mote is device 2). On Linux, as with the mica programmers, you will
-typically need to make the USB serial port world writeable.  As superuser,
-execute the following command: 
-<pre>chmod 666 <i>usb-device-name</i></pre>
-
-Now you can install the application using one of:</p>
-
-<pre>
-  make telosb reinstall bsl,3            # Windows example
-  make telosb reinstall bsl,/dev/ttyUSB2 # Linux example
-</pre>
-
-<p>This would compile an image suitable for the telosb platform and install
-it with a mote ID of 2 on a mote connected to COM4 on Windows or
-/dev/ttyUSB2 on Linux. If you have a single mote installed, you can skip
-the bsl and device name/number arguments. Again, see the Getting Started
-Guide for your chosen platform for the exact make parameters.</p>
-
-<p>You should see something like this scroll by:</p>
-
-<pre>
-    installing telosb binary using bsl
-tos-bsl --telosb -c 16 -r -e -I -p build/telosb/main.ihex.out
-MSP430 Bootstrap Loader Version: 1.39-telos-8
-Mass Erase...
-Transmit default password ...
-Invoking BSL...
-Transmit default password ...
-Current bootstrap loader version: 1.61 (Device ID: f16c)
-Changing baudrate to 38400 ...
-Program ...
-2782 bytes programmed.
-Reset device ...
-rm -f build/telosb/main.exe.out-2 build/telosb/main.ihex.out
-</pre>
-
-             
-<A name="tinynode"><h2>Installing on a TinyNode mote</h2></A>
-<p>There are different ways to program a TinyNode mote depending on how
-it is connected to your computer. The most common case is to connect
-it to a serial port using either the standard extension board (SEB) or
-the MamaBoard. <i>(The other possible methods are to use a Mamaboard with a Digi
-Connect ethernet adaptor and program a node over the network, or to
-use a JTAG adaptor. These are not covered in this tutorial; please
-refer to the Tinynode documentation for further details.)</i>
-
-<p>To install an application on a TinyNode mote using the
-serial port, enter the following command, taking care to
-replace <tt>/dev/ttyXXX</tt> with the file device corresponding to the
-serial port that the tinynode is plugged into.</p>
-
-<pre>
-  make tinynode reinstall bsl,/dev/XXX
-</pre>
-
-As with the telos and eyesIFX platforms, this command will reprogram your
-mote using the <tt>tos-bsl</tt> utility, and you will see similar
-output on your screen as given above for telos.
-
-<A NAME="eyes"><h2>Installing on an eyesIFX-family mote</h2></A>
-
-<p>The eyesIFX motes have a mini-B USB connector, allowing easy
-programming and data exchange over the USB. The on-board serial-to-USB
-chip exports two separate serial devices: a lower-numbered one used
-exclusively for serial data communication, and a higher-numbered one
-used for programming of the microcontroller.</p>
-
-      <center>
-       <table border="0" cellspacing="2" cellpadding="3" hspace="4">
-         <tbody>
-           <tr>
-             <td><img src="img/eyesIFX.jpg" height="140" width="320"></td>
-             <td><img src="img/eyesIFX_usb.jpg" height="240" width="320"></td>
-           </tr>
-           <tr>
-             <td><i>eyesIFXv2 mote</i></td>
-             <td><i>eyesIFXv2 mote attached to a USB cable</i></td>
-           </tr>
-         </tbody>
-       </table>
-      </center>
-
-
-
-<p>The actual programming is performed by the <i>msp430-bsl</i> script,
-conveniently invoked using the same <i>make</i> rules as for the telos
-motes. In the most basic form:</p>
-
-<pre>
-  make eyesIFX install bsl
-</pre>
-
-<p>the install script defaults to programming using the /dev/ttyUSB1
-device on Linux and COM1 on Windows, giving output similar to this:</p>
-
-<pre>
-    installing eyesIFXv2 binary using bsl
-msp430-bsl --invert-test --invert-reset --f1x -c /dev/ttyUSB1 -r -e -I -p build/eyesIFXv2/main.ihex.out
-MSP430 Bootstrap Loader Version: 2.0
-Mass Erase...
-Transmit default password ...
-Invoking BSL...
-Transmit default password ...
-Current bootstrap loader version: 1.61 (Device ID: f16c)
-Program ...
-2720 bytes programmed.
-Reset device ...
-rm -f build/eyesIFXv2/main.exe.out build/eyesIFXv2/main.ihex.out
-</pre>
-
-<p> The programming device can also be explicitly set as a parameter
-of the <i>bsl</i> command using shorthand or full notation:</p>
-
-<pre>
-  make eyesIFX install bsl,USB3
-  make eyesIFX install bsl,/dev/ttyUSB3
-</pre>
-
-<p>The eyesIFX motes can be programmed over the provided JTAG interface
-with the help of the  msp430-jtag script:</p>
-
-<pre>
-  make eyesIFX install jtag
-</pre>
-
-<p>producing output as in the following:</p>
-
-<pre>
-    installing eyesIFXv2 binary using the parallel port jtag adapter
-msp430-jtag  -Iepr build/eyesIFXv2/main.ihex.out
-MSP430 parallel JTAG programmer Version: 2.0
-Mass Erase...
-Program...
-2720 bytes programmed.
-Reset device...
-Reset and release device...
-</pre>
-
-
-<A NAME="intel"><h2>Installing on an IntelMote2</h2></A>
-
-  
-<h1>Installation options</h1>
-
-<p>You can now test the program by unplugging the mote from the
-programming board and turning on the power switch (if it's not already
-on). With any luck the three LEDs should be displaying a counter
-incrementing at 4Hz.</p>
-
-<p>The <tt>reinstall</tt> command told the make system to
-install the currently compiled binary: it skips the
-compilation process. Type <tt>make clean</tt> to clean up all
-of the compiled binary files, then type, e.g., <tt>make telosb install</tt>
-This will recompile Blink and install it on one action.</p>
-
-<p>Networking almost always requires motes to have unique identifiers.
-When you compile a TinyOS application, it has a default unique
-identifier of 1. To give a node a different identifier, you can specify
-it at installation. For example, if you type <tt>make telosb install.5</tt>
-or <tt>make telosb reinstall.5</tt>, you will install the application
-on a node and give it 5 as its identifier.</b></p>
-
-<p>For more information on the build system, please see <a
-href="lesson13.html">Lesson 13</a>.
-       
-<h1>Components and Interfaces</h1>
-
-      <p>Now that you've installed Blink, let's look at how
-       it works. Blink, like all TinyOS code, is written
-       in nesC, which is C with some additional language
-       features for components and concurrency.</p>
-               
-      <p>A nesC application consists of one or more <i>components</i>
-       assembled, or <i>wired</i>, to form an application executable.
-       Components define two scopes: one for their specification which
-       contains the names of their <i>interfaces</i>, and a second scope for their
-       implementation. A component <i>provides</i> and <i>uses</i>
-       interfaces. The provided interfaces are intended to represent
-       the functionality that the component provides to its user in its
-       specification; the used interfaces represent the functionality the
-       component needs to perform its job in its implementation.</p>
-      
-      <p>Interfaces are bidirectional: they specify a set of
-       <i>commands</i>, which are functions to be implemented by the
-       interface's provider, and a set of <i>events</i>, which are functions
-       to be implemented by the interface's user. For a component to call the
-       commands in an interface, it must implement the events of that
-       interface. A single component may use or provide multiple interfaces
-       and multiple instances of the same interface.</p>
-      
-      <p>The set of interfaces which a component provides together with the
-       set of interfaces that a component uses is considered that component's
-       <i>signature</i>.</p>
-             
-      <h2>Configurations and Modules</h2>
-      
-      <p>There are two types of components in nesC: <i>modules</i> and
-       <i>configurations</i>. Modules provide the implementations of one or more
-       interfaces. Configurations are used to assemble other components
-       together, connecting interfaces used by components to interfaces
-       provided by others. Every nesC
-       application is described by a top-level configuration that wires
-       together the components inside.</p>
-
-      <h1>Blink: An Example Application</h1>
-
-      <p>Let's look at a concrete example:
-       <tt><a href="../../../apps/Blink">Blink</a></tt> in the TinyOS
-       tree. As you saw, this application displays a counter on the
-       three mote LEDs. In actuality, it simply causes the LED0 to to turn on and off at
-       .25Hz, LED1 to turn on and off at .5Hz, and LED2 to turn on and off at
-       1Hz. The effect is as if the three
-       LEDs were displaying a binary count of one to seven every two
-       seconds. </p>
-
-<p>Blink is composed of two <b>components</b>: a <b>module</b>, called
-"<tt>BlinkC.nc</tt>", and a <b>configuration</b>, called
-"<tt>BlinkAppC.nc</tt>".  Remember that all applications require a
-top-level configuration file, which is typically named after the
-application itself. In this case <tt>BlinkAppC.nc</tt> is the
-configuration for the Blink application and the source file that the
-nesC compiler uses to generate an executable file. <tt>BlinkC.nc</tt>,
-on the other hand, actually provides the <i>implementation</i> of the
-Blink application. As you might guess, <tt>BlinkAppC.nc</tt> is used
-to wire the <tt>BlinkC.nc</tt> module to other components that the
-Blink application requires. </p>
-
-<p>The reason for the distinction between modules and configurations
-is to allow a system designer to build applications out of existing
-implementations. For example, a designer could provide a configuration
-that simply wires together one or more modules, none of which she
-actually designed.  Likewise, another developer can provide a new set
-of library modules that can be used in a range of applications. </p>
-
-<p>Sometimes (as is the case with <tt>BlinkAppC</tt> and
-<tt>BlinkC</tt>) you will have a configuration and a module that go
-together. When this is the case, the convention used in the TinyOS
-source tree is:</p>
-
-
-<CENTER>
-<table border="1"  cellspacing="1" cellpadding="1">
-<tbody>
-
-<tr>
-<td>File Name </td>
-<td>File Type </td>
-</tr>
-
-<tr>
-<td><tt>Foo.nc</tt></td>
-<td>Interface </td>
-</tr>
-
-<tr>
-<td><tt>Foo.h</tt></td>
-<td>Header File</td>
-</tr>
-         
-<tr>
-<td><tt>FooC.nc </tt></td>
-<td>Public Module</td>
-</tr>
-
-<tr>
-<td><tt>FooP.nc</tt></td>
-<td>Private Module</td>
-</tr>
-
-
-</tbody>
-</table>
-</CENTER>
-
-<p>While you could
-name an application's implementation module and associated top-level
-configuration anything, to keep things simple we suggest that you
-adopt this convention in your own code. There are several other 
-conventions used in TinyOS;  
-<a href="../tep3.html">TEP 3</a>
-specifies the coding standards and best current practices.
-
-<h1>The BlinkAppC.nc Configuration</h1>
-
-<p>The nesC compiler compiles a nesC application when given the file
-containing the top-level configuration. Typical TinyOS applications
-come with a standard Makefile that allows platform selection and
-invokes ncc with appropriate options on the application's top-level
-configuration.
-
-<p>Let's look at <tt>BlinkAppC.nc</tt>, the configuration for this
-application first:
-
-<pre></pre>
-<prehead>apps/Blink/BlinkAppC.nc:</prehead>
-<pre>
-configuration BlinkAppC {
-}
-implementation {  
-  components MainC, BlinkC, LedsC;
-  components new TimerMilliC() as Timer0;
-  components new TimerMilliC() as Timer1;
-  components new TimerMilliC() as Timer2;
-
-  BlinkC -> MainC.Boot;
-  BlinkC.Timer0 -> Timer0;
-  BlinkC.Timer1 -> Timer1;
-  BlinkC.Timer2 -> Timer2;
-  BlinkC.Leds -> LedsC;
-}
-</pre>
-
-<p>The first thing to notice is the key word <tt>configuration</tt>,
-which indicates that this is a configuration file. The first two
-lines,
-
-<pre></pre>
-<prehead>apps/Blink/BlinkAppC.nc:</prehead>
-<pre>
-configuration BlinkAppC {
-}
-</pre>
-
-simply state that this is a configuration called <tt>BlinkAppC</tt>.
-Within the empty braces here it is possible to specify <tt>uses</tt>
-and <tt>provides</tt> clauses, as with a module. This is important to
-keep in mind: a configuration can use and provide interfaces. Said
-another way, not all configurations are top-level applications.
-
-<p>The actual configuration is implemented within the pair of curly
-brackets following the key word <tt>implementation </tt>. The
-<tt>components</tt> lines specify the set of components that this
-configuration references. In this case those components are
-<tt>Main</tt>, <tt>BlinkC</tt>,
-<tt>LedsC</tt>, and three instances of a timer component called
-<tt>TimerMilliC</tt> which will be referenced as Timer0, Timer1,
-and Timer2<a href="#timermillic_footnote">(1)</a>. This is accomplished
-via the <i>as</i> keyword which is simply an alias<a href="#hint10">(2)</a>. 
-
-<p>As we continue reviewing the BlinkAppC application, keep in mind that the
-BlinkAppC component is not the same as the BlinkC component. Rather,
-the BlinkAppC component is composed of the BlinkC component along with
-MainC, LedsC and the three timers.
-
-<p>The remainder of the BlinkAppC configuration consists of connecting
-interfaces used by components to interfaces provided by others. The
-<tt>MainC.Boot</tt> and <tt>MainC.SoftwareInit</tt> interfaces are
-part of TinyOS's boot sequence and will be covered in detail in Lesson
-3. Suffice it to say that these wirings enable the LEDs and Timers to
-be initialized.
-
-<p>The last four lines wire interfaces that the BlinkC component
-<i>uses</i> to interfaces that the TimerMilliC and LedsC
-components <i>provide</i>. To fully understand the semantics of these
-wirings, it is helpful to look at the BlinkC module's definition and
-implementation.
-
-<h1>The BlinkC.nc Module</h1>
-
-<pre></pre>
-<prehead>apps/Blink/BlinkC.nc:</prehead>
-<pre>
-module BlinkC {
-  uses interface Timer&lt;TMilli&gt; as Timer0;
-  uses interface Timer&lt;TMilli&gt; as Timer1;
-  uses interface Timer&lt;TMilli&gt; as Timer2;
-  uses interface Leds;
-  uses interface Boot;
-}
-implementation
-{
-  // implementation code omitted
-}
-</pre>
-
-<p>The first part of the module code states that this is a module
-called <tt>BlinkC</tt>and declares the interfaces it provides and
-uses.&nbsp; The <tt>BlinkC</tt>&nbsp; module <b>uses</b> three
-instances of the interface <tt>Timer&lt;TMilli&gt;</tt> using the
-names Timer0, Timer1 and Timer2 (the <tt>&lt;TMilli&gt;</tt> syntax
-simply supplies the generic Timer interface with the required timer
-precision). Lastly, the <tt>BlinkC</tt>
-module also uses the Leds and Boot interfaces. This means that BlinkC
-may call any command declared in the interfaces it uses and must also
-implement any events declared in those interfaces.
-
-<p>After reviewing the interfaces used by the <tt>BlinkC</tt>
-component, the semantics of the last four lines in
-<tt>BlinkAppC.nc</tt> should become clearer.  The line
-<tt>BlinkC.Timer0 -&gt; Timer0</tt> wires the three
-<tt>Timer&lt;TMilli&gt;</tt> interface used by <tt>BlinkC</tt> to the
-<tt>Timer&lt;TMilli&gt;</tt> interface provided the three
-<tt>TimerMilliC</tt> component. The <tt>BlinkC.Leds -&gt;
-LedsC</tt> line wires the <tt>Leds</tt> interface used by the
-<tt>BlinkC</tt> component to the <tt>Leds</tt> interface provided by
-the <tt>LedsC</tt> component.
-
-<p>nesC uses arrows to bind interfaces to one another.  The right arrow
-(<tt>A-&gt;B</tt>) as "A wires to B". The left side of the arrow (A)
-is a user of the interface, while the right side of the arrow (B) is
-the provider. A full wiring is <tt>A.a-&gt;B.b</tt>, which means
-"interface a of component A wires to interface b of component B."
-Naming the interface is important when a component uses or provides multiple
-instances of the same interface. For example, BlinkC uses three instances of
-Timer: Timer0, Timer1 and Timer2.
-
-When a component only has one instance
-of an interface, you can elide the interface name. For example, returning
-to BlinkAppC:
-
-<pre></pre>
-<prehead>apps/Blink/BlinkAppC.nc:</prehead>
-<pre>
-configuration BlinkAppC {
-}
-implementation {  
-  components MainC, BlinkC, LedsC;
-  components new TimerMilliC() as Timer0;
-  components new TimerMilliC() as Timer1;
-  components new TimerMilliC() as Timer2;
-
-  BlinkC -> MainC.Boot;
-  BlinkC.Timer0 -> Timer0;
-  BlinkC.Timer1 -> Timer1;
-  BlinkC.Timer2 -> Timer2;
-  BlinkC.Leds -> LedsC;
-}
-</pre>
-
-<p>The interface name Leds does not have to be included in LedsC:</p>
-
-<pre>
-  BlinkC.Leds -> LedsC; // Same as BlinkC.Leds -> LedsC.Leds
-</pre>
-
-<p>Because BlinkC only uses one instance of the Leds interface, this
-line would also work:</p>
-
-<pre>
-  BlinkC -> LedsC.Leds; // Same as BlinkC.Leds -> LedsC.Leds
-</pre>
-
-<p>As the TimerMilliC components each provide a single instance of Timer,
-it does not have to be included in the wirings:</p>
-
-<pre>
-  BlinkC.Timer0 -> Timer0;
-  BlinkC.Timer1 -> Timer1;
-  BlinkC.Timer2 -> Timer2;
-</pre>
-
-<p>However, as BlinkC has three instances of Timer, eliding the name
-on the user side would be a compile-time error, as the compiler would
-not know which instance of Timer was being wired:</p>
-
-<pre>
-  BlinkC -> Timer0.Timer;  // Compile error!
-</pre
-
-<p>The direction of a wiring arrow is always from a user to a
-provider. If the provider is on the left side, you can also
-use a left arrow:</p>
-
-<pre>
-  Timer0 <- BlinkC.Timer0; // Same as BlinkC.Timer0 -> Timer0;
-</pre>
-
-<p>For ease of reading, however, most wirings are left-to-right.</p>
-
-<h1>Visualizing a Component Graph</h1>
-
-<p>Carefully engineered TinyOS systems often have many layers of configurations,
-each of which refines the abstraction in simple way, building something robust
-with very little executable code. Getting to the modules underneath
--- or just navigating the layers -- with a text editor can be laborious.
-To aid in this process, TinyOS and nesC have a documentation feature called
-nesdoc, which generates documentation automatically from source code. In
-addition to comments, nesdoc displays the structure and composition of
-configurations.</p>
-
-<p>To generate documentation for an application, type</p>
-
-<pre>
-  make <i>platform</i> docs
-</pre>
-
-<p>You should see a long list of interfaces and components stream by. If you
-see the error message</p>
-
-<pre>sh: dot: command not found</pre>
-
-<p>then you need to <A HREF="http://www.graphviz.org/Download..php">install
-graphviz</A>, which is the program that draws the component graphs.</p>
-
-<p>Once you've generated the documentation, go to <tt>tinyos-2.x/doc/nesdoc</tt>. You
-should see a directory for your platform: open its <tt>index.html</tt>, and
-you'll see a list of the components and interfaces for which you've
-generated documentation. For example, if you generated documentation
-for Blink on the telosb platform, you'll see documentation for interfaces
-such as Boot, Leds, and Timer, as well as some from the underlying hardware
-implementations, such as Msp430TimerEvent and HplMsp430GeneralIO.</p>
-
-<p>In the navigation panel on the left, components are below interfaces.
-Click on BlinkAppC, and you should a figure like this: </p>
-
-<CENTER>
-  <IMG SRC="img/BlinkAppC.gif">
-</CENTER>
-
-<p>In nesdoc diagrams, a single box is a module and a double box is a
-configuration. Dashed border lines denote that a component is a generic:</p>
-<CENTER>
-<TABLE CELLPADDING=6 BORDER=1>
-  <TR>
-    <td></td>
-    <td><b>Singleton</b></td>
-    <td><b>Generic</b></td>
-  </TR>
-  <TR>
-    <td>Module</td>
-    <td><IMG SRC="img/singleton-module.gif"></td>
-    <td><IMG SRC="img/generic-module.gif"></td>
-  </TR>
-  <TR>
-    <td>Configuration</td>
-    <td><IMG SRC="img/singleton-configuration.gif"></td>
-    <td><IMG SRC="img/generic-configuration.gif"></td>
-  </TR>
-</TABLE>
-</CENTER>
-<p>Lines denote wirings, and shaded ovals denote interfaces
-that a component provides or uses. You can click on the components
-in the graph to examine their internals. Click on MainC, which shows
-the wirings for the boot sequence:</p>
-
-<CENTER>
-  <IMG SRC="img/tos.system.MainC.gif">
-</CENTER>
-
-<p>Shaded ovals denote wireable interfaces.
-Because MainC provides the Boot interface and uses the Init (as
-SoftwareInit) interface, it has two shaded ovals. Note the direction
-of the arrows: because it uses SoftwareInit, the wire goes out from
-RealMainP to SoftwareInit, while because it provides Boot, the wire
-goes from Boot into RealMainP. The details of MainC aren't too important
-here, and we'll be looking at it in greater depth in
-<A HREF="lesson3.html">lesson 3</A>
-(you can also read <A HREF="../tep107.html">TEP 107</A> for details),
-but looking at the components you can get a sense of what it does: it
-controls the scheduler, initializes the hardware platform, and
-initializes software components.</p>
-
-<h1>Conclusion</h1>
-
-<p>This lesson has introduced the concepts of the TinyOS component
-model: configurations, modules, interfaces and wiring.  It showed
-how applications are built by wiring components together. The next
-lesson continues with Blink, looking more closely at modules,
-including the TinyOS concurrency model and executable code.
-
-<p>
-<a name=#related_docs>
-<h1>Related Documentation</h1>
-</a>
-<ul>
-<li> mica mote Getting Started Guide at <a href="http://www.xbow.com">Crossbow</a>
-<li> telos mote Getting Started Guide for <a href="http://www.moteiv.com">Moteiv</a>
-<li> <a href="https://sourceforge.net/projects/nescc">nesc at sourceforge</a>
-<li> <a href="http://nescc.sourceforge.net/papers/nesc-ref.pdf">nesC reference manual</a>
-<li> <a href="http://csl.stanford.edu/~pal/pubs/tinyos-programming-1-0.pdf">TinyOS Programming Guide</a>
-<li> <a href="../tep3.html">TEP 3: TinyOS Coding Conventions</a>
-<li> <a href="../tep102.html">TEP 102: Timers</a>
-<li> <a href="../tep106.html">TEP 106: Schedulers and Tasks</a>
-<li> <a href="../tep107.html">TEP 106: TinyOS 2.x Boot Sequence</a>
-</ul>
-
-<p>
-<hr>
-
-<p><a name="timermillic_footnote">(1)</a> The TimerMilliC component is a
-<i>generic component</i> which means that, unlike non-generic components,
-it can be instantiated more than once.  Generic components can take types
-and constants as arguments, though in this case TimerMilliC takes
-none. There are also <i>generic interafces</i>, which take type arguments
-only. The Timer interface provided by TimerMilliC is a generic interface;
-its type argument defines the timer's required precision (this prevents
-programmer from wiring, e.g., microsecond timer users to millisecond timer
-providers).  A full explanation of generic components is outside this
-document's scope, but you can read about them in <!-- TODO: Need to update
-this link to a real file><a href="../../nesc/user/generics-1.2.txt"> -->the
-nesc generic component documentation</a>.
-
-<p><a name="hint10">(2)</a>
-<b>Programming Hint 10:</b> Use the <i>as</i> keyword liberally. From  
-<a href="http://csl.stanford.edu/~pal/pubs/tinyos-programming-1-0.pdf"><i>TinyOS Programming</i></a>
-
-
-<!-- Begin footer -->
-<br>
-<hr>
-<center>
-<p>&lt;&nbsp;<b><a href="index.html">Top</a></b> 
-&nbsp;|&nbsp; <b><a href="lesson2.html">Next Lesson </a>&nbsp;&gt;</b>
-</center>
-
+<p>Sorry, your browser does not support frames. Please <a href="http://docs.tinyos.net/index.php/Getting_Started_with_TinyOS" target="_top">go here</a>.</p>
 </body>
-</html>
+</noframes>
+</frameset>
+</html>
\ No newline at end of file
index a159b9b22addb152f4f835cf884bd6262391e0bd..dd2b1dc06340da475f921d65a269920bdfb6a43a 100644 (file)
-<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
-<html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" ^M   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
-  <title>TinyOS Tutorial Lesson 10: Platforms</title>
-  <link href="../../stylesheets/tutorial.css" rel="stylesheet" type="text/css">
+<title>klueska.com</title>
 </head>
-
+<frameset>
+<frame src="http://docs.tinyos.net/index.php/Platforms" name="redir_frame" />
+<noframes>
 <body>
-
-<div class="title">Lesson 10: Platforms</div>
-<div class="subtitle">Last updated October 23 2006</div>
-
-<h1>Introduction</h1>
-
-<p>Many different hardware platforms (e.g micaZ, telos, eyesIFX) can be
-  used with TinyOS. This lesson shows you what a platform port consists
-  of, and how TinyOS reuses as much code as possible between different
-  platforms.
-  The lesson will proceed by showing how to do the port for an imaginary
-  mote called "yamp", which has a MSP430 microcontroller and a CC2420 
-  radio transceiver. 
-
-<p>
-  The <b>target audience</b> of this lesson consists of those people that want
-  to better understand what the difference between e.g "make micaz" and "make
-  telosb" is, and how these differences concretely map into the underlying
-  files, definitions, etc. 
-
-<p> Note that the material covered in this tutorial is <b>not</b>
-  strictly necessary for regular tinyos developpers, and you can safely skip
-  it if you have no intention of working down to the lowest level or
-  developping new platforms.
-
-</p>
-
-<h1>Chips vs Platforms</h1>
-
-<p>
-  Two key building blocks for any mote are the microcontroller and
-  radio transceiver. 
-  Of course, both a microcontroller and a radio can be used on 
-  more than one platform. This is indeed the case for the MSP430 and CC2420
-  that our yamp mote uses (telos, eyes, and tinynode use the MSP430; telos
-  and micaz use the CC2420).
-</p>
-
-<p>
-  Given this multiplicity of platforms, it would be vasly redundant if each
-  platform developper had to rewrite the software support for each chip
-  from scratch. While a chip may be physically wired in a different way on
-  different platforms (e.g., a radio is connected to a different digital
-  pins on the microcontroller), by far the largest part of the logic to
-  deal with a chip is platform-independent.
-</p>
-
-<p>
-  Thus, platform-independent code to support a chip is placed in a
-  chip-specific directory. Writing a platform port for a platform is then 
-  (essentially) a matter of <b>pulling in the code for each of the 
-  platform's chips, and "gluing"  things together</b>.
-  For example, the modules and components that support the CC2420 are in
-  tos/chips/cc2420. This radio is used on both the telos and micaZ motes; the
-  "gluing" is done by the modules in the tos/platforms/telosa/chips/cc2420 and
-  tos/platforms/micaz/chips/cc2420/ directories.
-</p>
-
-<p>
-  Note that in general there may
-  be more to a platform port than pulling in existing code for different
-  chips, in particular when a new platform uses a chip that is not yet
-  supported. Developping drivers for a new chip can be a non-trivial
-  undertaking (especially for radios and microcontrollers); these aspects
-  are not covered here. 
-</p>
-
-<h1>Initial platform bring-up</h1>
-
-<p>
-  As a first step to bring up the platform, we will stick to the bare minimum in
-  order to compile and install the Null application on our yamp mote. 
-</p>
-
-<p>
-  All platform-specific code goes in tos/platforms/<platformname>. 
-    For example, we have tos/platforms/micaz or tos/platforms/tinynode.
-    Our first step is to create a directory for the yamp platform:
-    <pre>
-      $ cd tinyos-2.x/tos/platforms
-      $ mkdir yamp
-    </pre>
-</p>
-
-<h2>The .platform file</h2>
-
-Each platform directory (such as tos/platforms/yamp) should contain a
-file named ".platform", that contains basic compiler parameters
-information for each platform. So, create the file
-"tos/platforms/yamp/.platform" (note the <b>.</b> in  "<b>.</b>platform" !!!), that contains the following:
-
-<pre>
-  push( @includes, qw(
-
-  %T/chips/cc2420
-  %T/chips/msp430
-  %T/chips/msp430/adc12
-  %T/chips/msp430/dma
-  %T/chips/msp430/pins
-  %T/chips/msp430/timer
-  %T/chips/msp430/usart
-  %T/chips/msp430/sensors
-  %T/lib/timer
-  %T/lib/serial
-  %T/lib/power
-  ) );
-
-  @opts = qw(
-
-  -gcc=msp430-gcc
-  -mmcu=msp430x1611
-  -fnesc-target=msp430
-  -fnesc-no-debug
-  -fnesc-scheduler=TinySchedulerC,TinySchedulerC.TaskBasic,TaskBasic,TaskBasic,runTask,postTask
-
-  );
-
-</pre>
-    
-<p>
-  This file contains perl snippets that are intepreted by the ncc compiler. 
-  The first statement simply adds some directories to the include path that
-  is used when compiling an application for the yamp platform (the %T gets
-  expanded to the full location of tinyos-2.x/tos, using the TOS2DIR
-  environment variable). Note that we have included the CC2420 and MSP430
-  directories, as well as some libraries.
-</p>
-
-<p>
-  The second statement defines the @opts list, that contains various parameters
-  passed to nesc. Please consult the nesc documentation for information on the
-  meaning of these parameters.
-</p>
-
-<h2>The hardware.h file</h2>
-
-<p>
-  Each platform directory also has a file named "hardware.h" that is included by
-  default when compiling an application for that platform. This can define
-  platform-specific constants, pin names, or also include other "external"
-  header files (e.g. msp430hardware.h in our case, or atm128hardware.h for
-  platforms using the atm128 MCU).<br>
-
-  So, create the file "tos/platforms/yamp/hardware.h" with the following contents:
-</p>
-
-<pre>
-  #ifndef _H_hardware_h
-  #define _H_hardware_h
-
-  #include "msp430hardware.h"
-
-  // LEDs
-  TOSH_ASSIGN_PIN(RED_LED, 5, 4);
-  TOSH_ASSIGN_PIN(GREEN_LED, 5, 5);
-  TOSH_ASSIGN_PIN(YELLOW_LED, 5, 6);
-
-  // UART pins
-  TOSH_ASSIGN_PIN(SOMI0, 3, 2);
-  TOSH_ASSIGN_PIN(SIMO0, 3, 1);
-  TOSH_ASSIGN_PIN(UCLK0, 3, 3);
-  TOSH_ASSIGN_PIN(UTXD0, 3, 4);
-  TOSH_ASSIGN_PIN(URXD0, 3, 5);
-  TOSH_ASSIGN_PIN(UTXD1, 3, 6);
-  TOSH_ASSIGN_PIN(URXD1, 3, 7);
-  TOSH_ASSIGN_PIN(UCLK1, 5, 3);
-  TOSH_ASSIGN_PIN(SOMI1, 5, 2);
-  TOSH_ASSIGN_PIN(SIMO1, 5, 1);
-
-
-  #endif // _H_hardware_h
-</pre>
-
-<p>
-  This file simply pulls in msp430hardware.h from tos/chips/msp430 (the compiler
-  will find it because we have added this directory to our search path in the
-  .platform created previously) and defines some physical pins using macros from
-  msp430hardware.h. For example, on our yamp mote, the red led is physically
-  connected to the general purpose I/O (GPIO) pin 5.4.
-</p>
-
-<p>
-  Some other very important functions (that are defined in msp430hardware.h
-  and so pulled in indirectly via this hardware.h)
-  concern the disabling of interrupts for atomic sections (atomic blocks in nesc
-  code essentially get converted into __nesc_atomic_start() and
-  __nesc_atomic_end()). How interrupts are disabled is of course microcontroller
-  specific; the same applies to putting the microcontroller to sleep (as is done
-  by the scheduler when there are no more tasks to run, using the McuSleep
-  interface). These functions must be somehow defined for each platform, 
-  typically by means of an <tt>#include</tt>'d MCU-specific file.<br>
-<i>  As an exercise, try finding the definitions of</i> __nesc_atomic_start() <i>and
-</i>  __nesc_atomic_end()<i> for the micaZ and intelmote2 platforms.</i>
-
-</p>
-
-<h1>Setting up the build environment and building the "null" app</h1>
-Before pulling in existing chip drivers or writing any code, we must set up
-the build environment so that it is aware of and supports our platform.
-
-Once this is done, we will define the basic TinyOS module for our platform,
-and use the Null app (in tinyos-2.x/apps/null) in order to test that our
-platform is properly configured. As per it's description in its README file,
-Null is an empty skeleton application.  It is useful to test that the
-build environment is functional in its most minimal sense, i.e., you
-can correctly compile an application. So, let's go ahead and try to compile 
-Null for the yamp platform:
-
-<!-- <h2> Defining a make target</h3> -->
-
-<!-- At this point we have created all the necessary files in tos/platforms/yamp/ -->
-<!-- in order to run the Null application. But how do we compile it and install it -->
-<!-- on our yamp mote? -->
-
-<!-- We would like to enter "make yamp" in any application directory and have a -->
-<!-- yamp binary be built, just as e.g. "make micaz" builds us a micaz -->
-<!-- binary. But if we try it at this point we get an error message listing all the -->
-<!-- valid targets and telling us that yamp is not a valid target: -->
-
-<pre>
-  $ cd tinyos-2.x/apps/Null
-  $ make yamp
-/home/henridf/work/tinyos-2.x/support/make/Makerules:166: *** 
-
-Usage:  make <target> <extras>
-        make <target> help
-
-        Valid targets: all btnode3 clean eyesIFX eyesIFXv1 eyesIFXv2 intelmote2 mica2 mica2dot micaz null telos telosa telosb tinynode tmote
-        Valid extras: docs ident_flags nescDecls nowiring rpc sim sim-cygwin sim-fast tos_image verbose wiring
-
- Welcome to the TinyOS make system!
-
- You must specify one of the valid targets and possibly some combination of
- the extra options.  Many targets have custom extras and extended help, so be
- sure to try "make <target> help" to learn of all the available features.
-
- Global extras:
-
-   docs    : compile additional nescdoc documentation
-   tinysec : compile with TinySec secure communication
-
-ERROR, "yamp tos-ident-flags tos_image" does not specify a valid target.  Stop. 
-  
-</pre>
-
-<p>
-The problem is that we need to define the platform in the <i>TinyOS build
-  system</i>, so that the make invocation above recognizes the yamp platform.
-The TinyOS build system is a Makefile-based set of rules and definitions
-that has a very rich functionality. This includes invoking
-necessary  compilation commands as with any build system, but goes much
-  further and includes support for other important aspects such as 
-device reprogramming or supporting multiple platforms and targets.
-</p>
-
-<p>
-A full description of the inner workings of the TinyOS build system is beyond
-  the scope of this tutorial. For now, we will simply see how to define the
-  yamp platform so that the "make yamp" command does what it should. (For those
-  that want to delve deeper, start with "tinyos-2.x/support/make/Makerules".)
-</p>
-
-<h2> Defining a make target</h2>
-
-The TinyOS build system resides in "tinyos-2.x/support/make". The strict
-minimum for a platform to be recognized by the build system (i.e., for the
-build system to understand that "yamp" is a legal platform when we enter "make
-yamp") is the existence of a <i>platformname</i>.target file in the
-aforementioned make directory.<br>
-So, create the file "tinyos-2.x/support/make/yamp.target" with the following
-contents:
-
-<pre>
-
-PLATFORM = yamp
-
-$(call TOSMake_include_platform,msp)
-
-yamp: $(BUILD_DEPS)
-       @:
-</pre>
-
-This sets the PLATFORM variable to yamp, includes the msp platform
-("make/msp/msp.rules") file, and provides in the last two lines a make rule
-for building a yamp application using standard Makefile syntax.
-
-Now, let's go back and try to compile the Null app as before. This time we get:
-
-<pre>
-[18:23 henridf@tinyblue: ~/work/tinyos-2.x/apps/Null] make yamp
-mkdir -p build/yamp
-    compiling NullAppC to a yamp binary
-ncc -o build/yamp/main.exe -Os -Wall -Wshadow -DDEF_TOS_AM_GROUP=0x7d -Wnesc-all -target=yamp -fnesc-cfile=build/yamp/app.c -board=   NullAppC.nc -lm 
-In file included from NullAppC.nc:42:
-In component `MainC':
-/home/henridf/work/tinyos-2.x/tos/system/MainC.nc:50: component PlatformC not found
-/home/henridf/work/tinyos-2.x/tos/system/MainC.nc:53: no match
-make: *** [exe0] Error 1
-</pre>
-
-So there's progress of sorts, since now we're getting a "real" compilation
-error as opposed to not even making it past the build system. Let's take a
-closer look at the output. The ncc compiler is unhappy about not finding a
-"PlatformC" component.
-
-The "PlatformC" component must be defined for each platform. Its role and
-placement in the system is described in more detail in TEP107. For now,
-suffice to cite from that TEP that:
-<i>A port of TinyOS to a new plaform MUST include a component PlatformC which
-  provides one and only one instance of the Init interface.</i>.
-
-
-Create the file "tos/platforms/yamp/PlatformP.nc" with the following contents:
-
-<pre>
-#include "hardware.h"
-
-module PlatformP{
-  provides interface Init;
-  uses interface Init as Msp430ClockInit;
-  uses interface Init as LedsInit;
-}
-implementation {
-  command error_t Init.init() {
-    call Msp430ClockInit.init();
-    call LedsInit.init();
-    return SUCCESS;
-  }
-
-  default command error_t LedsInit.init() { return SUCCESS; }
-
-}
-</pre>
-
-, and create the file "tos/platforms/yamp/PlatformC.nc" as:
-
-<pre>
-#include "hardware.h"
-
-configuration PlatformC
-{
-  provides interface Init;
-}
-implementation
-{
-  components PlatformP
-    , Msp430ClockC
-    ;
-
-  Init = PlatformP;
-  PlatformP.Msp430ClockInit -> Msp430ClockC.Init;
-}
-</pre>
-
-Now, compilation of the Null application finally works for the yamp platform:
-
-<pre>
-[19:47 henridf@tinyblue: ~/work/tinyos-2.x/apps/Null] make yamp
-mkdir -p build/yamp
-    compiling NullAppC to a yamp binary
-ncc -o build/yamp/main.exe -Os -Wall -Wshadow -DDEF_TOS_AM_GROUP=0x7d -Wnesc-all -target=yamp -fnesc-cfile=build/yamp/app.c -board=   NullAppC.nc -lm 
-    compiled NullAppC to build/yamp/main.exe
-            1216 bytes in ROM
-               6 bytes in RAM
-msp430-objcopy --output-target=ihex build/yamp/main.exe build/yamp/main.ihex
-    writing TOS image
-</pre>
-
-
-<h1>Getting Blink to work</h1>
-
-With the previous steps, we now have the basic foundation to start working on
-our yamp platform: the basic platform definitions are in place, and the build
-system recognizes and correctly acts upon the "make yamp" target. We haven't
-yet actually <i>programmed</i> our mote yet. 
-<p>
-The next step in the bring-up of a platform, that we will cover in this part,
-is to program a node with an application and verify that it actually
-works. We'll do this with Blink, because it is simple, and easy to verify that
-it works. As a bonus, we'll also have validated basic timer functionality once
-we see those Leds turning on and off.
-<p>
-As a first step, let's go to the Blink application directory and try to
-compile the application:
-<pre> 
-[19:06 henridf@tinyblue: ~/work/tinyos-2.x/apps/Blink] make yamp
-mkdir -p build/yamp
-    compiling BlinkAppC to a yamp binary
-ncc -o build/yamp/main.exe -Os -Wall -Wshadow -DDEF_TOS_AM_GROUP=0x7d -Wnesc-all -target=yamp -fnesc-cfile=build/yamp/app.c -board=   BlinkAppC.nc -lm 
-In file included from BlinkAppC.nc:45:
-In component `LedsC':
-/home/henridf/work/tinyos-2.x/tos/system/LedsC.nc:38: component PlatformLedsC not found
-/home/henridf/work/tinyos-2.x/tos/system/LedsC.nc:42: cannot find `Init'
-/home/henridf/work/tinyos-2.x/tos/system/LedsC.nc:43: cannot find `Led0'
-/home/henridf/work/tinyos-2.x/tos/system/LedsC.nc:44: cannot find `Led1'
-/home/henridf/work/tinyos-2.x/tos/system/LedsC.nc:45: cannot find `Led2'
-make: *** [exe0] Error 1
-</pre>
-
-The compiler cannot find the component "PlatformLedsC" that is referred to in 
-the file tos/system/LedsC.nc. As the name indicates, "PlatformLedsC" is a
-platform-specific component, and thus we will need to define this component
-for the yamp platform. 
-<p>
-Why should there be such a platform-specific component for accessing Leds?  This is because at
-the lowest level, i.e in hardware, Leds are implemented differently on
-different platforms. Typically, a Led is connected to a microcontroller I/O pin,
-and the Led is turned on/off by setting the appropriate output 0/1 on that
-pin. This is in fact the model used on all current TinyOS platforms. 
-But even in this simple and uniform model, (and disregarding
-the fact that future platforms may use different hardware implementations
-and not connect each Led directly to an I/O pin), we have that the
-lowest-level to turn on/off a Led must be defined on a per-platform basis. 
-<p> 
-Now, consider Leds from another perspective, namely that of the Leds.nc
-interface (defined in tos/interfaces/Leds.nc). In this interface, we have
-commands such as <tt>get();</tt> in principle such a command does not need to be
-platform-dependent: the code that maintains the current state of a Led and
-returns it via the get() call does not need to be re-written each time a Led
-is connected to a different pin (of course re-writing get() for each
-platform would  not be much overhead given its simplicity; this argument
-clearly becomes far stronger in more complex situations involving entire chips
-rather than individual GPIOs).
-<p> The key notion that the above example is simply that there is a boundary
-  above which software components are platform-independent, and below which
-  components are specifically written with one hardware platform in mind. 
-  This is at heart a very simple concept; its complete instantiation in TinyOS is of
-  course richer than the above example, and is the topic of TEP2 (Hardware
-  Abstraction Architecture).
-<p> Let's now return to the task at hand, which is to make Blink work on our
-  platform. If we take a closer look at the file "tos/system/LedsC.nc", we see
-  that it contains a configuration that wires the module LedsP with modules
-  Init, Leds0,  Leds1, and Leds2, all of which are to be provided by the
-  (still missing) PlatformLedsC. Taking a closer look at
-  "tos/system/LedsP.nc", we see that the Leds0,1,2 modules used by LedsP are
-  GeneralIO interfaces. The GeneralIO interface (see
-  "tos/interfaces/GeneralIO.nc" and TEP 117) simply encapsulates a digital I/O pin and
-  provides functions to control its direction and get/set its input/output
-  values. 
-<p> So, we need to create a PlatformLedsC configuration that shall provide
-  three GeneralIO interfaces and an Init. This is done by creating the file
-  "tos/platforms/yamp/PlatformLedsC.nc" with the following contents:
-
-<pre>
-#include "hardware.h"
-
-configuration PlatformLedsC {
-  provides interface GeneralIO as Led0;
-  provides interface GeneralIO as Led1;
-  provides interface GeneralIO as Led2;
-  uses interface Init;
-}
-implementation
-{
-  components 
-      HplMsp430GeneralIOC as GeneralIOC
-    , new Msp430GpioC() as Led0Impl
-    , new Msp430GpioC() as Led1Impl
-    , new Msp430GpioC() as Led2Impl
-    ;
-  components PlatformP;
-
-  Init = PlatformP.LedsInit;
-
-  Led0 = Led0Impl;
-  Led0Impl -> GeneralIOC.Port54;
-
-  Led1 = Led1Impl;
-  Led1Impl -> GeneralIOC.Port55;
-
-  Led2 = Led2Impl;
-  Led2Impl -> GeneralIOC.Port56;
-
-}
-</pre>
-
-We refer the reader to the TinyOS Programming Guide cited below for more
-explanations on how the above confiuration uses generics (ie with the "new"
-keyword). For the purpose of this lesson, the key point is that we are wiring
-to ports 5.4, 5.5, and 5.6 -- we shall suppose that these  are the MSP430 
-microcontroller pins to which the three Leds are connected on the yamp
-platform.  <p>
-
-With the above file in place, we can now compile Blink for the yamp platform. 
-How do we test that the application actually works? We have thus far presented
-yamp as an imaginary platform, but it turns out that the above application
-should work on any platform with the MSP430x1611 microcontroller and where the
-Leds are connected to microcontroller ports 5.4-5.6. 
-Not entirely coincidentally, these are exactly the Led wirings used by the
-telos/tmote platforms. So those readers that have a telos/tmote at hand can
-test this application on it. (Testing on a tinynode or eyes mote is also easy and only
-requires changing the pin wirings in PlatformLedsC to follow those of that
-platform; running this application on mica-family motes will require more
-changes since they use a different microcontroller).
-
-<p>
-Now, enter the following command (where you have suitably replaced /dev/ttyXXX by the appropriate serial port),
-<pre>
-  make yamp install bsl,/dev/ttyXXX
-</pre>
-and you will see the Leds of your impersonated (by a telos) yamp node Blinking!
-
-<h1>Conclusion</h1>
-
-<p>This lesson has introduced the notion of per-platform support in TinyOS
-  using as a guiding example the development of a platform port to an
-  imaginary "yamp" platform. We have seen how introducing support for a new
-  platform requires touching not only nesc code but also adding some rules to
-  the build system. This tutorial also touched upon the notions of Hardware
-  Abstraction Architecture (HAA) that is central to the clean and modular
-  support of different platforms and chips in TinyOS.
-<p>
-  The steps outlined here did not cover what is the hardest part of
-  a platform port: developping the components to drive a radio transceiver or
-  MCU (which are necessary if the platform uses chips that are not currently
-  supported in TinyOS). Developping such drivers is an advanced topic that is
-  beyond the scope of the tutorials; for those curious to gain some insight we
-  recommend perusing the code for a chip (e.g the CC2420 radio in
-  tos/chips/cc2420 or the xe1205 radio in tos/chips/xe1205) armed with that
-  chips datasheet and the platform schematics.
-<p>
-<a name=#related_docs>
-<h1>Related Documentation</h1>
-</a>
-<ul>
-<li> <a href="https://sourceforge.net/projects/nescc">nesc at sourceforge</a>
-<li> <a href="http://nescc.sourceforge.net/papers/nesc-ref.pdf">nesC reference manual</a>
-<li> <a href="http://csl.stanford.edu/~pal/pubs/tinyos-programming-1-0.pdf">TinyOS Programming Guide</a>
-<li> <a href="../tep102.html">TEP 2: Hardware Abstraction Architecture</a>
-<li> <a href="../tep106.html">TEP 106: Schedulers and Tasks</a>
-<li> <a href="../tep107.html">TEP 107: TinyOS 2.x Boot Sequence</a>
-<li> <a href="../tep117.html">TEP 117: Low-level I/O</a>
-</ul>
-
-<p>
-<hr>
-
-
-<!-- Begin footer -->
-<br>
-<hr>
-<center>
-                                             <p>&lt;&nbsp;<b><a href="lesson8.html">Previous Lesson</a></b> |&nbsp; <b><a
- href="index.html">Top</a></b> &nbsp;|&nbsp; <b><a href="lesson11.html">Next
-Lesson </a>&nbsp;&gt;</b>
-</p>
-
-&nbsp;</b>
-</center>
-
+<p>Sorry, your browser does not support frames. Please <a href="http://docs.tinyos.net/index.php/Platforms" target="_top">go here</a>.</p>
 </body>
-</html>
+</noframes>
+</frameset>
+</html>
\ No newline at end of file
index 9f49f9340a9e2d6b1c7b5be5e3f87b5d8ffbe467..02d3212eda49fa7bacc533f51d6a31821531d54e 100644 (file)
-<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
-<html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" ^M   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
-  <title>Lesson 11: Simulation with TOSSIM</title>
-  <link href="../../stylesheets/tutorial.css" rel="stylesheet" type="text/css">
+<title>klueska.com</title>
 </head>
+<frameset>
+<frame src="http://docs.tinyos.net/index.php/TOSSIM" name="redir_frame" />
+<noframes>
 <body>
-
-<div class="title">Lesson 11: Simulation with TOSSIM</div>
-<div class="subtitle">Last Modified: 20 April 2007</div>
-
-      <p>This lesson introduces the TOSSIM simulator. You will become
-        familiar with how to compile TOSSIM and use some of its
-        functionality. You will learn how to:</p>
-
-      <p>
-        
-        <ul>
-          
-          <li>Compile TOSSIM.</li>
-          
-          <li>Configure a simulation in Python and C++.</li>
-            
-          <li>Inspect variables.</li>
-              
-          <li>Inject packets.</li>
-        </ul>
-      </p>
-      
-      <p><b>Note:</b> This tutorial is for TOSSIM in TinyOS 2.0.1. If
-      you are using TinyOS 2.0.0, it has a slightly different 
-       A HREF="lesson11-200.html">tutorial.</A> The principal difference
-      between the two is how you specify noise in RF simulation.
-      </p>
-<h1>Introduction</h1>
-
-        TOSSIM simulates entire TinyOS applications. It works by
-        replacing components with simulation implementations. The
-        level at which components are replaced is very flexible: for
-        example, there is a simulation implementation of millisecond
-        timers that replaces <code>HilTimerMilliC</code>, while there is also an
-        implementation for atmega128 platforms that replaces the HPL
-        components of the hardware clocks. The former is general and
-        can be used for any platform, but lacks the fidelity of
-        capturing an actual chips behavior, as the latter
-        does. Similarly, TOSSIM can replace a packet-level
-        communication component for packet-level simulation, or
-        replace a low-level radio chip component for a more precise
-        simulation of the code execution.
-
-        TOSSIM is a discrete event simulator. When it runs, it pulls
-        events of the event queue (sorted by time) and executes them.
-        Depending on the level of simulation, simulation events can
-        represent hardware interrupts or high-level system events
-        (such as packet reception). Additionally, tasks are simulation
-        events, so that posting a task causes it to run a short time
-        (e.g., a few microseconds) in the future.
-
-        TOSSIM is a library: you must write a program that configures
-        a simulation and runs it. TOSSIM supports two programming
-        interfaces, Python and C++. Python allows you to interact with
-        a running simulation dynamically, like a powerful
-        debugger. However, as the interpretation can be a performance
-        bottleneck when obtaining results, TOSSIM also has a C++
-        interface. Usually, transforming code from one to the other is
-        very simple.
-
-        TOSSIM currently does not support gathering power
-        measurements.
-
-        <h1>Compiling TOSSIM</h1>
-
-        <p>TOSSIM is a TinyOS library. Its core code lives in <code><a
-        href="../../../tos/lib/tossim">tos/lib/tossim</a></code>. Every TinyOS
-        source directory has an optional <code>sim</code> subdirectory,
-        which contains simulation implementations of that package. For
-        example, <code><a
-        href="../../../tos/chips/atm128/timersim">tos/chips/atm128/timer/sim</a></code>
-        contains TOSSIM implementations of some of the Atmega128 timer
-        abstractions.</p>
-
-        <p>To compile TOSSIM, you pass the <code>sim</code> option to make:</p>
-
-        <pre>
-          $ cd apps/Blink
-          $ make micaz sim
-        </pre>
-
-        
-      <p>Currently, the only platform TOSSIM supports is the
-        micaz. You should see output similar to this:</p>
-      <pre>
-          mkdir -p build/micaz
-            placing object files in build/micaz
-            writing XML schema to app.xml
-            compiling BlinkAppC to object file sim.o 
-          ncc -c -fPIC -o build/micaz/sim.o -g -O0 -tossim -fnesc-nido-tosnodes=1000 -fnesc-simulate -fnesc-nido-motenumber=sim_node\(\)   -finline-limit=100000 -Wall -Wshadow -DDEF_TOS_AM_GROUP=0x7d -Wnesc-all -target=micaz -fnesc-cfile=build/micaz/app.c -board=micasb  -Wno-nesc-data-race BlinkAppC.nc   -fnesc-dump=components -fnesc-dump=variables -fnesc-dump=constants -fnesc-dump=typedefs -fnesc-dump=interfacedefs -fnesc-dump=tags -fnesc-dumpfile=app.xml
-            compiling Python support into pytossim.o and tossim.o
-          g++ -c -shared -fPIC -o build/micaz/pytossim.o -g -O0  /home/pal/src/tinyos-2.x/tos/lib/tossim/tossim_wrap.cxx -I/usr/include/python2.3 -I/home/pal/src/tinyos-2.x/tos/lib/tossim -DHAVE_CONFIG_H
-          g++ -c -shared -fPIC -o build/micaz/tossim.o -g -O0  /home/pal/src/tinyos-2.x/tos/lib/tossim/tossim.c -I/usr/include/python2.3 -I/home/pal/src/tinyos-2.x/tos/lib/tossim
-            linking into shared object ./_TOSSIMmodule.so
-          g++ -shared build/micaz/pytossim.o build/micaz/sim.o build/micaz/tossim.o -lstdc++ -o _TOSSIMmodule.so
-          copying Python script interface TOSSIM.py from lib/tossim to local directory
-      </pre>
-
-      <p>Depending on what OS you are using and what packages are installed, TOSSIM may
-       not properly compile on the first try. <A HREF="#appendix">Appendix A</A>
-       addresses some of the common causes and gives possible solutions.</p>
-
-
-     <A name="#compiling"></A>
-
-       
-        <p>Compiling TOSSIM has five basic steps. Let's go through
-        them one by one.</p>
-
-        <h2>Writing an XML schema</h2>
-
-        <pre>
-          writing XML schema to app.xml
-        </pre>
-
-        <p>The first thing the TOSSIM build process does is use
-        nesc-dump to produce an XML document that describes the
-        application. Among other things, this document descibes the
-        name and type of every variable.</p>
-
-        <h2>Compiling the TinyOS Application</h2>
-
-        <p>Besides introducing all of these new compilation steps, the
-        <code>sim</code> option changes the include paths of the
-        application. If the application has a series of includes</p>
-
-        <pre>
-          -Ia -Ib -Ic
-        </pre>
-
-        <p>Then the sim option transforms the list to</p>
-
-        <pre>
-          -Ia/sim -Ib/sim -Ic/sim -I%T/lib/tossim -Ia -Ib -Ic
-        </pre>
-          
-        <p>This means that any system-specific simulation
-        implementations will be used first, followed by generic TOSSIM
-        implementations, followed by standard implementations. The
-        <code>sim</code> option also passes a bunch of arguments to the
-        compiler, so it knows to compile for simulation.</p>
-
-        <p>The product of this step is an object file, <code>sim.o</code>,
-        which lives in the platform's build directory. This object
-        file has a set of C functions which configure the simulation
-        and control execution.</p>
-
-        <h2>Compiling the Programming Interface</h2>
-
-        <pre>
-            compiling Python support into pytossim.o and tossim.o
-          g++ -c -shared -fPIC -o build/micaz/pytossim.o -g -O0 \
-          /home/pal/src/tinyos-2.x/tos/lib/tossim/tossim_wrap.cxx \
-          -I/usr/include/python2.3 -I/home/pal/src/tinyos-2.x/tos/lib/tossim \
-          -DHAVE_CONFIG_H
-          g++ -c -shared -fPIC -o build/micaz/tossim.o -g -O0 \
-          /home/pal/src/tinyos-2.x/tos/lib/tossim/tossim.c \
-          -I/usr/include/python2.3 -I/home/pal/src/tinyos-2.x/tos/lib/tossim
-        </pre>
-        
-        <p>The next step compiles the support for the C++ and Python
-        programming interfaces. The Python interface is actually built
-        on top of the C++ interface. Calling a Python object calls a
-        C++ object, which then calls TOSSIM through the C
-        interface. <code>tossim.o</code> contains the C++ code, while
-        <code>pytossim.o</code> contains the Python support. These files
-        have to be compiled separately because C++ doesn't understand
-        nesC, and nesC doesn't understand C++.</p>
-
-        <h2>Building the shared object</h2>
-        
-        <pre>
-            linking into shared object ./_TOSSIMmodule.so
-          g++ -shared build/micaz/pytossim.o build/micaz/sim.o build/micaz/tossim.o -lstdc++ -o _TOSSIMmodule.so
-        </pre>
-
-        <p>The next to last step is to build a shared library that
-        contains the TOSSIM code, the C++ support, and the Python
-        support.</p>
-
-        <h2>Copying Python Support</h2>
-        
-        <pre>
-            copying Python script interface TOSSIM.py from lib/tossim to local directory
-        </pre>
-
-        <p>Finally, there is the Python code that calls into the
-        shared object. This code exists in <code>lib/tossim</code>, and
-        the make process copies it into the local directory.</p>
-
-        
-        <h1>Running TOSSIM with Python</h1>
-        
-        <p>Go into the <code>RadioCountToLeds</code> application and build
-          TOSSIM:</p>
-
-        <pre>
-$ cd tinyos-2.x/apps/RadioCountToLeds
-$ make micaz sim
-        </pre>
-
-        <p>We'll start with running a simulation in Python. You can either
-          write a script and just tell Python to run it, or you can
-          use Python interactively. We'll start with the latter. Fire
-          up your Python interpreter:</p>
-
-        <pre>
-$ python
-        </pre>
-
-        <p>You should see a prompt like this:</p>
-
-        <pre>
-Python 2.3.4 (#1, Nov  4 2004, 14:13:38)
-[GCC 3.4.2 20041017 (Red Hat 3.4.2-6.fc3)] on linux2
-Type "help", "copyright", "credits" or "license" for more information.
->>>
-        </pre>
-
-        <p>The first thing we need to do is import TOSSIM and create a
-        TOSSIM object. Type</p>
-
-        <pre>
->>> from TOSSIM import *
->>> t = Tossim([])
-        </pre>
-        
-        <p>The square brackets are an optional argument that lets you
-        access variables in the simulation. We'll get to how to use
-        that later. In this case, we're telling TOSSIM that there are
-        no variables that we want to look at. The way you run a TOSSIM
-        simulation is with the <code>runNextEvent</code> function. For
-        example:</p>
-
-        <pre>
->>> t.runNextEvent()
-0
-        </pre>
-
-        <p>When you tell TOSSIM to run the next event, it returns
-        0. This means that there was no next event to run. The reason
-        is simple: we haven't told any nodes to boot. This snippet of
-        code will tell mote 32 to boot at time 45654 and run its first
-        event (booting):</p>
-
-        <pre>
->>> m = t.getNode(32);
->>> m.bootAtTime(45654);
->>> t.runNextEvent()
-1
-        </pre>
-
-      <p><b>Segmentation faults:</b>If trying to do this causes TOSSIM
-      to throw a segmentation violation (segfault), then chances are
-      you are using a version of gcc that does not work well with the
-      dynamic linking that TOSSIM is doing. In particular, it has been
-      verified to work properly with 4.0.2 and 3.6, but some people
-      have encountered problems with gcc 4.1.1.</p>
-      
-      <p>Instead of using raw simulation ticks, you can also use the
-      call <code>ticksPerSecond()</code>. However, you want to be careful
-      to add some random bits into this number: having every node
-      perfectly synchronized and only different in phase in terms of
-          seconds can lead to strange results.</p>
-
-      <pre>
->>> m = t.getNode(32);
->>> m.bootAtTime(4 * t.ticksPerSecond() + 242119);
->>> t.runNextEVent()
-1
-      </pre>
-
-        <p>Now, <code>runNextEvent</code> returns 1, because there was an
-        event to run. But we have no way of knowing whether the node
-        has booted or not. We can find this out in one of two ways.
-        The first is that we can just ask it:</p>
-
-        <pre>
->>> m.isOn()
-1
->>> m.turnOff()
->>> m.isOn()
-0
->>> m.bootAtTime(560000)
->>> t.runNextEvent()
-0
->>> t.runNextEvent()
-1
-        </pre>        
-
-        <p>Note that the first <code>runNextEvent</code> returned 0. This
-        is because when we turned the mote off, there was still an
-        event in the queue, for its next timer tick. However, since
-        the mote was off when the event was handled in that call,
-        <code>runNextEvent</code> returned 0. The second call to
-        <code>runNextEvent</code> returned 1 for the second boot event, at
-        time 560000.</p>
-
-
-        <p>A Tossim object has several useful functions. In Python,
-        you can generally see the signature of an object with the
-        <code>dir</code> function. E.g.:</p>
-
-        <pre>
->>> t = Tossim([])
->>> dir(t)
-['__class__', '__del__', '__delattr__', '__dict__', '__doc__', '__getattr__',
-'__getattribute__', '__hash__', '__init__', '__module__', '__new__',
-'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__',
-'__swig_getmethods__', '__swig_setmethods__', '__weakref__', 'addChannel',
-'currentNode', 'getNode', 'init', 'mac', 'newPacket', 'radio', 'removeChannel',
-'runNextEvent', 'setCurrentNode', 'setTime', 'this', 'thisown', 'ticksPerSecond', 'time', 'timeStr']
-        </pre>
-
-        <p>The most common utility functions are:</p>
-
-        <ul>
-          <li><b><code>currentNode()</code></b>: returns the ID of the current node.</li>
-          <li><b><code>getNode(id)</code></b>: returns an object representing a specific mote</li>
-          <li><b><code>runNextEvent()</code></b>: run a simulation event</li>
-          <li><b><code>time()</code></b>: return the current time in simulation ticks as a large integer </li>
-          <li><b><code>timeStr()</code></b>: return a string representation of the current time</li>
-          <li><b><code>init()</code></b>: initialize TOSSIM</li>
-          <li><b><code>mac()</code></b>: return the object representing the media access layer</li>
-          <li><b><code>radio()</code></b>: return the object representing the radio model</li>
-          <li><b><code>addChannel(ch, output)</code></b>: add <i>output</i> as an output to channel <i>ch</i> </li>
-          <li><b><code>removeChannel(ch, output)</code></b>: remove <i>output</i> as an output to channel <i>ch</i> </li>
-          <li><b><code>ticksPerSecond()</code></b>: return how many simulation ticks there are in a simulated second </li>
-        </ul>
-
-        <p>The next section discusses the last two.</p>
-
-          <h1>Debugging Statements</h1>
-        
-        <p>The second approach to know whether a node is on is to tell
-        it to print something out when it boots. TOSSIM has a
-        debugging output system, called <code>dbg</code>. There are four
-        <code>dbg</code> calls:</p>
-
-          <ul>
-            <li><code>dbg</code>: print a debugging statement preceded by the node ID.</li>
-            <li><code>dbg_clear</code>: print a debugging statement which is not preceded by the node ID. This allows you to easily print out complex data types, such as packets, without interspersing node IDs through the output.</li>
-            <li><code>dbgerror</code>: print an error statement preceded by the node ID</li>
-            <li><code>dbgerror_clear</code>: print an error statement which is not preceded by the node ID</li>
-          </ul>
-
-          
-        <p>Go into <code>RadioCountToLedsC</code> and modify the <code>Boot.booted</code> event
-          to print out a debug message when it boots, such as this:</p>
-
-        <pre>
-event void Boot.booted() {
-  call Leds.led0On();
-  dbg("Boot", "Application booted.\n");
-  call AMControl.start();
-}
-        </pre>
-
-        <p>Calls to the debugging calls take two or more
-        parameters. The first parameter ("Boot" in the above example)
-        defines the output <i>channel</i>. An output channel is simply
-        a string. The second and subsequent parameters are the message
-        to output. They are identical to a printf statement. For example
-          <code>RadioCountToLedsC</code> has this call:
-
-        <pre>
-event message_t* Receive.receive(message_t* bufPtr, void* payload, uint8_t len) {
-  dbg("RadioCountToLedsC", "Received packet of length %hhu.\n", len);
-  ...
-}
-        </pre>
-
-        which prints out the length of received packet as an 8-bit unsigned value (%hhu).</p>
-
-        <p>Once you have added the debugging statement to the event,
-        recompile the application with <code>make micaz sim</code> and
-        start up your Python interpreter. Load the TOSSIM module and
-        schedule a mote to boot as before:</p>
-        
-        <pre>
->>> from TOSSIM import *
->>> t = Tossim([])
->>> m = t.getNode(32);
->>> m.bootAtTime(45654);
-        </pre>
-
-        <p>This time, however, we want to see the debugging message
-        that the mote has booted. TOSSIM's debugging output can be
-        configured on a per-channel basis. So, for example, you can
-        tell TOSSIM to send the "Boot" channel to standard output, but
-        another channel, say "AM", to a file. 
-        By default, a channel has no destination, and so
-        messages to it are discarded.</p>
-
-        <p>In this case, we want to send the Boot channel to standard
-        output. To do this, we need to import the <code>sys</code> Python
-        package, which lets us refer to standard out. We can then tell
-        TOSSIM to send Boot messages to this destination:
-          
-        <pre>
->>> import sys
->>> t.addChannel("Boot", sys.stdout);
-1
-        </pre>
-
-          The return value shows that the channel was added successfully. Run the first
-          simulation event, and the mote boots:
-
-        <pre>
->>> t.runNextEvent()
-DEBUG (32): Application booted.
-1
-        </pre>          </p>
-
-        <p>The only difference between debug and error functions is
-        the string output at the beginning of a message. Debug
-        statements print <code>DEBUG (n)</code>, while error statements
-        print <code>ERROR (n)</code>.</p>
-
-        <p>A debugging statement can have multiple output
-          channels. Each channel name is delimited by commas:
-
-          <pre>
-event void Boot.booted() {
-  call Leds.led0On();
-  dbg("Boot,RadioCountToLedsC", "Application booted.\n");
-  call AMControl.start();
-}
-          </pre>
-
-          If a statement has multiple channels and those channels
-          share outputs, then TOSSIM only prints the message once. For
-          example, if both the Boot channel and RadioCountToLedsC
-          channel were connected to standard out, TOSSIM will only
-          print one message. For example, this series of debug statements
-
-          
-          <pre>
-event void Boot.booted() {
-  call Leds.led0On();
-  dbg("Boot,RadioCountToLedsC", "Application booted.\n");
-  dbg("RadioCountToLedsC", "Application booted again.\n");
-  dbg("Boot", "Application booted a third time.\n");
-  call AMControl.start();
-}
-          </pre>
-
-          when configured so
-
-          <pre>
->>> import sys
->>> t.addChannel("Boot", sys.stdout)
->>> t.addChannel("RadioCountToLedsC", sys.stdout)
-          </pre>
-
-          will print out this:
-
-          <pre>
-DEBUG (32): Application booted.
-DEBUG (32): Application booted again.
-DEBUG (32): Application booted a third time.
-          </pre></p>
-
-
-        <p>A channel can have multiple outputs. For example, this
-        script will tell TOSSIM to write <code>RadioCountToLedsC</code> messages to
-        standard output, but to write <code>Boot</code> messages to both standard
-        output and a file named <code>log.txt</code>:
-
-          <pre>
->>> import sys
->>> f = open("log.txt", "w")
->>> t.addChannel("Boot", f)
->>> t.addChannel("Boot", sys.stdout)
->>> t.addChannel("RadioCountToLedsC", sys.stdout)
-          </pre>
-        </p>
-
-        <h1>Configuring a Network</h1>
-
-        <p>When you start TOSSIM, no node can communicate with any
-        other.  In order to be able to simulate network behavior, you
-        have to specify a <i>network topology</i>. Internally, TOSSIM
-        is structured so that you can easily change the underlying
-        radio simulation, but that's beyond the scope of this
-        tutorial. The default TOSSIM radio model is signal-strength
-        based. You provide a graph to the simulator that describes the
-        propagation strengths. You also specify noise floor, and
-        receiver sensitivity. There are some very early results that
-        describe current sensor platforms (e.g., the mica2) in these
-        terms. Because all of this is through a scripting interface,
-        rather than provide a specific radio model, TOSSIM tries to
-        provide a few low-level primitives that can express a wide
-        range of radios and behavior.</p>
-
-        <p>You control the radio simulation through a Python Radio
-        object:</p>
-
-        
-        <pre>
->>> from TOSSIM import *
->>> t = Tossim([])
->>> r = t.radio()
->>> dir(r)
-['__class__', '__del__', '__delattr__', '__dict__', '__doc__',
-'__getattr__', '__getattribute__', '__hash__', '__init__',
-'__module__', '__new__', '__reduce__', '__reduce_ex__',
-'__repr__', '__setattr__', '__str__', '__swig_getmethods__',
-'__swig_setmethods__', '__weakref__', 'add', 'connected',
-'gain', 'remove', 'setNoise', 'this', 'thisown',
-<class 'TOSSIM.RadioPtr'>]
-        </pre>          
-
-        <p>The first set of methods (with the double underscores) are
-        ones that you usually don't call. The important ones are at
-        the end. They are:</p>
-
-        <ul>
-          <li><b><code>add(src, dest, gain)</code></b>: Add a link from <i>src</i>
-          to <i>dest</i> with <i>gain</i>. When <i>src</i> transmits, <i>dest</i>
-          will receive a packet attenuated by the <i>gain</i> value.</li>
-
-          <li><b><code>connected(src, dest)</code></b>: Return whether there is a
-          link from <i>src</i> to <i>dest</i>.</li>
-
-
-          <li><b><code>gain(src, dest)</code></b>: Return the gain value of the
-          link from <i>src</i> to <i>dest</i>.</li>
-          
-          <li><b><code>threshold()</code></b>: Return the CCA threshold.</li>
-
-          <li><b><code>setThreshold(val)</code></b>: Set the CCA threshold value in
-            dBm. The default is -72dbM.</li>
-          
-        </ul>
-
-      <p>The default values for TOSSIM's radio model are based on the CC2420 radio,
-       used in the micaZ, telos family, and imote2. It uses an SNR curve derived
-       from experimental data collected using two micaZ nodes, RF shielding, and
-       a variable attenuator.</p>
-
-      <p>In addition to the radio propagation above, TOSSIM
-      also simulates the RF noise and interference a node hears, both from other
-      nodes as well as outside sources. It uses the Closest Pattern Matching (CPM)
-      algorithm. CPM takes a noise trace as input and generates a statistical model
-      from it. This model can capture bursts of interference and other correlated
-      phenomena, such that it greatly improves the quality of the RF simulation.
-       It is not perfect (there are several things it does not handle, such as
-       correlated interference at nodes that are close to one another), but
-       it is much better than traditional, independent packet loss models. For
-       more details, please refer to the paper "Improving Wireless Simulation through
-       Noise Modeling," by Lee et al.</p>
-      
-
-      <p>To configure CPM, you need to feed it a noise trace. You accomplish this
-       by calling <tt>addNoiseTraceReading</tt> on a Mote object. Once you
-       have fed the entire noise trace, you must call <tt>createNoiseModel</tt>
-       on the node. The directory <tt>tos/lib/tossim/noise</tt> contains
-       sample noise traces, which are a series of noise readings, one per line.
-       For example, these are the first 10 lines of meyer-heavy.txt,
-       which is a noise trace taken from Meyer Library at Stanford University:</p>
-
-      <pre>
--39
--98
--98
--98
--99
--98
--94
--98
--98
--98
-</pre>
-
-      <p>As you can see, the hardware noise floor is around -98 dBm,
-       but there are spikes of interference around -86dBm and -87dBm.</p>
-
-      <p>This piece of code will give a node a noise model from a noise trace
-       file. It works for nodes 0-7: you can change the range appropriately:</p>
-
-      <pre>
-noise = open("meyer-heavy.txt", "r")
-lines = noise.readlines()
-for line in lines:
-    str = line.strip()
-    if (str != ""):
-        val = int(str)
-        for i in range(0, 7):
-            t.getNode(i).addNoiseTraceReading(val)
-
-for i in range(0, 7):
-    t.getNode(i).createNoiseModel()</pre>
-
-
-      <p>CPM can use a good deal of RAM: using the entire meyer-heavy
-      trace as input has a cost of approximately 10MB per node. You
-      can reduce this overhead by using a shorter trace; this will of
-      course reduce simulation fidelity. <u>The trace
-      must be at least 100 entries long, or CPM will not work as it does
-      not have enough data to generate a statistical model.</u> </p>
-
-      <p>You can also use 
-      <p>The Radio object only deals with physical layer
-        propagation. The MAC object deals with the data link layer,
-        packet lengths, and radio bandwidth. The default TOSSIM MAC
-        object is for a CSMA protocol. You get a reference to the MAC
-        object by calling <code>mac()</code> on a Tossim object:
-          <pre>
->>> mac = t.mac()
-          </pre>
-
-          The default MAC object has a large number of functions, for
-          controlling backoff behavior, packet preamble length, radio
-          bandwidth, etc. All time values are specified in terms of
-          radio symbols, and you can configure the number of symbols
-          per second and bits per symbol. By default, the MAC object
-          is configured to act like the standard TinyOS 2.0 CC2420
-          stack: it has 4 bits per symbol and 64k symbols per second,
-          for 256kbps. This is a subset of the MAC functions that
-          could be useful for changing backoff behavior. Every
-          accessor function has a corresponding set function that
-          takes an integer as a parameter. E.g., there's <code>int
-          initHigh()</code> and <code>void setInitHigh(int val)</code>. The
-          default value for each parameter is shown italicized in
-          parentheses.  </p>
-
-        <ul>
-          <li><b>initHigh</b>: The upper bound of the initial backoff range. <i>(400)</i></li>
-          <li><b>initLow</b>: The lower bound of the initial backoff range. <i>(20)</i></li>
-          <li><b>high</b>: The upper bound of the backoff range. This is multiplied by the
-          exponent base to the nth power, where n is the number of previous backoffs. So if the
-          node had its initial backoff, then the upper bound is high * base, while if it
-          is after the second backoff then the upper bound is high * base * base. <i>(160)</i></li>
-          <li><b>low</b>: The lower bound of the backoff range. This is multiplied by the
-          exponent base to the nth power, where n is the number of previous backoffs. So if the
-          node had its initial backoff, then the upper bound is low * base, while if it
-          is after the second backoff then the upper bound is low * base * base. <i>(20)</i></li>
-          <li><b>symbolsPerSec</b>: The number of symbols per second that the radio can
-          transmit. <i>(65536)</i></li>
-          <li><b>bitsPerSymbol</b>: The number of bits per radio symbol. Multiplying this by
-          the symbols per second gives the radio bandwidth. <i>(4)</i></li>
-          <li><b>preambleLength</b>: How long a packet preamble is. This is added to the duration
-          of transmission for every packet. <i>(12)</i></li>
-          <li><b>exponentBase</b>: The base of the exponent used to calculate backoff. Setting it to
-          2 provides binary exponential backoff. <i>(0)</i>.</li>
-          <li><b>maxIterations</b>: The maximum number of times the radio will back off before
-          signaling failure, zero signifies forever. <i>(0)</i>.</li>
-          <li><b>minFreeSamples</b>: The number of times the radio must detect a clear channel
-          before it will transmit. This is important for protocols like 802.15.4, whose synchonrous
-          acknowledgments requires that this be greater than 1 (you could have sampled in the dead time
-          when the radios are changing between RX and TX mode). <i>(2)</i></li>
-          <li><b>rxtxDelay</b>: The time it takes to change the radio from RX to TX mode (or vice versa).<i>(32)</i></li>
-          <li><b>ackTime</b>: The time it takes to transmit a synchonrous acknowledgment, not including the
-          requisite RX/TX transition.<i>(34)</i></li>
-        </ul>
-
-        <p>Any and all of these configuration constants can be changed
-        at compile time with #define directives. Look at
-        <code>tos/lib/tossim/sim_csma.h</code>.</p>
-
-        <p>Because the radio connectivity graph can be scripted, you
-        can easily store topologies in files and then load the
-        file. Alternatively, you can store a topology as a script.
-        For example, this script will load a file which specifies each
-          link in the graph as a line with three values, the source, the
-          destination, and the gain, e.g.:
-
-          <pre>
-1  2 -54.0
-          </pre>
-
-          means that when 1 transmits 2 hears it at -54 dBm. Create a file <code>topo.txt</code>
-          that looks like this:</p>
-
-        <pre>
-1  2 -54.0
-2  1 -55.0
-1  3 -60.0
-3  1 -60.0
-2  3 -64.0
-3  2 -64.0
-        </pre>
-
-        <p>This script will read such a file:
-
-          <pre>
->>> f = open("topo.txt", "r")
->>> lines = f.readlines()
->>> for line in lines:
-...   s = line.split()
-...   if (len(s) > 0):
-...     print " ", s[0], " ", s[1], " ", s[2];
-...     r.add(int(s[0]), int(s[1]), float(s[2]))
-          </pre></p>
-        
-        
-        <p>Now, when a node transmits a packet, other nodes will hear it.
-        This is a complete script for simulating packet transmission with
-          RadioCountToLedsC. Save it as a file <code>test.py</code>:</p>
-        <pre>
-from TOSSIM import *
-import sys
-
-t = Tossim([])
-r = t.radio()
-f = open("topo.txt", "r")
-
-lines = f.readlines()
-for line in lines:
-  s = line.split()
-  if (len(s) > 0):
-    print " ", s[0], " ", s[1], " ", s[2];
-    r.add(int(s[0]), int(s[1]), float(s[2]))
-
-t.addChannel("RadioCountToLedsC", sys.stdout)
-t.addChannel("Boot", sys.stdout)
-
-noise = open("meyer-heavy.txt", "r")
-lines = noise.readlines()
-for line in lines:
-  str = line.strip()
-  if (str != ""):
-    val = int(str)
-    for i in range(1, 4):
-      t.getNode(i).addNoiseTraceReading(val)
-
-for i in range(1, 4):
-  print "Creating noise model for ",i;
-  t.getNode(i).createNoiseModel()
-
-t.getNode(1).bootAtTime(100001);
-t.getNode(2).bootAtTime(800008);
-t.getNode(3).bootAtTime(1800009);
-
-for i in range(0, 100):
-  t.runNextEvent()
-        </pre>          
-
-        <p>Run it by typing <code>python test.py</code>. You should see
-          output that looks like this:</p>
-
-        <pre>
-1  2 -54.0
-2  1 -55.0
-1  3 -60.0
-3  1 -60.0
-2  3 -64.0
-3  2 -64.0
-DEBUG (1): Application booted.
-DEBUG (1): Application booted again.
-DEBUG (1): Application booted a third time.
-DEBUG (2): Application booted.
-DEBUG (2): Application booted again.
-DEBUG (2): Application booted a third time.
-DEBUG (3): Application booted.
-DEBUG (3): Application booted again.
-DEBUG (3): Application booted a third time.
-DEBUG (1): RadioCountToLedsC: timer fired, counter is 1.
-DEBUG (1): RadioCountToLedsC: packet sent.
-DEBUG (2): RadioCountToLedsC: timer fired, counter is 1.
-DEBUG (2): RadioCountToLedsC: packet sent.
-DEBUG (3): RadioCountToLedsC: timer fired, counter is 1.
-DEBUG (3): RadioCountToLedsC: packet sent.
-DEBUG (1): Received packet of length 2.
-DEBUG (3): Received packet of length 2.
-DEBUG (2): Received packet of length 2.
-DEBUG (1): RadioCountToLedsC: timer fired, counter is 2.
-DEBUG (1): RadioCountToLedsC: packet sent.
-DEBUG (2): RadioCountToLedsC: timer fired, counter is 2.
-DEBUG (2): RadioCountToLedsC: packet sent.
-DEBUG (3): RadioCountToLedsC: timer fired, counter is 2.
-DEBUG (3): RadioCountToLedsC: packet sent.
-DEBUG (1): Received packet of length 2.
-        </pre>
-
-        <p>If you set node's clear channel assessment to be at -110dBm,
-       then nodes will never transmit, as noise and interference never
-       drop this low. You'll see something like this:</p>
-             <pre>
-1  2 -54.0
-2  1 -55.0
-1  3 -60.0
-3  1 -60.0
-2  3 -64.0
-3  2 -64.0
-DEBUG (1): Application booted.
-DEBUG (1): Application booted again.
-DEBUG (1): Application booted a third time.
-DEBUG (2): Application booted.
-DEBUG (2): Application booted again.
-DEBUG (2): Application booted a third time.
-DEBUG (3): Application booted.
-DEBUG (3): Application booted again.
-DEBUG (3): Application booted a third time.
-DEBUG (1): RadioCountToLedsC: timer fired, counter is 1.
-DEBUG (1): RadioCountToLedsC: packet sent.
-DEBUG (2): RadioCountToLedsC: timer fired, counter is 1.
-DEBUG (2): RadioCountToLedsC: packet sent.
-DEBUG (3): RadioCountToLedsC: timer fired, counter is 1.
-DEBUG (3): RadioCountToLedsC: packet sent.
-DEBUG (1): RadioCountToLedsC: timer fired, counter is 2.
-DEBUG (2): RadioCountToLedsC: timer fired, counter is 2.
-DEBUG (3): RadioCountToLedsC: timer fired, counter is 2.
-        </pre>
-
-        <p>Because the nodes backoff perpetually, they never transmit
-        the packet and so subsequent attempts to send fail. Although
-        it only takes a few simulation events to reach the first timer
-        firings, it takes many simulation events (approximately 4000)
-        to reach the second timer firings. This is because the nodes
-        have MAC backoff events. If you want to simulate in terms of
-        time, rather than events, you can always do something like
-        this, which simulates 5 seconds from the first node boot:</p>
-
-        <pre>
-t.runNextEvent();
-time = t.time()
-while (time + 50000000000 > t.time()):
-  t.runNextEvent()
-</pre>
-
-        <p>TOSSIM allows you to specify a network topology in terms of
-        gain. However, this raises the problem of coming up with a
-        topology. There are two approaches you can take. The first is
-        to take data from a real world network and input this into
-        TOSSIM. The second is to generate it from applying a
-        theoretical propagation model to a physical layout.  The standard
-        file format is
-
-          <pre>
-gain src dest g
-          </pre>
-
-          where each statement is on a separate line.
-       The <i>gain</i> statement defines a propagation
-          gain <i>g</i> when <i>src</i> transmits to <i>dest</i>. This
-          is a snippet of python code that will parse this file
-          format:
-
-          <pre>
-f = open("15-15-tight-mica2-grid.txt", "r")
-
-lines = f.readlines()
-for line in lines:
-  s = line.split()
-  if (len(s) > 0):
-    if (s[0] == "gain"):
-      r.add(int(s[1]), int(s[2]), float(s[3]))
-          </pre></p>
-
-        <p>TOSSIM has a tool for the second option of generating a
-        network topology using a theoretical propagation model. The
-        tool is written in Java and is
-        <code>net.tinyos.sim.PropagationModel</code>. The tool takes a
-        single command line parameter, the name of a configuration
-        file, e.g.:</p>
-
-        <pre>
-java net.tinyos.sim.PropagationModel config.txt
-        </pre>
-
-        <p>The format of a configuration file is beyond the scope of
-        this document: the tool has its own <A
-        HREF="usc-topologies.html">documentation</A>. TOSSIM has a few sample configuration
-        files generated from the tool in
-        <code>tos/lib/tossim/topologies</code>. 
-        Note that the tool uses random numbers,
-        these configuration files can generate multiple different
-        network topologies. Network topology files generated from the
-        tool follow the same format as <code>15-15-tight-mica2-grid.txt</code>.
-        If you have topologies measured from real networks, we would love
-        to include them in the TOSSIM distribution.</p>
-
-        <h1>Variables</h1>
-
-        <p>TOSSIM allows you to inspect variables in a running TinyOS
-        program. Currently, you can only inspect basic types. For
-        example, you can't look at fields of structs, but you can look
-        at state variables.</p>
-
-        <p>When you compile TOSSIM, the make system generates a large
-        XML file that contains a lot of information about the TinyOS
-        program, including every component variable and its type. If
-        you want to examine the state of your program, then you need
-        to give TOSSIM this information so it can parse all of the
-        variables properly. You do this by instantiating a Python
-        object that parses the XML file to extract all of the relevant
-        information. You have to import the Python support package for
-        TOSSIM to do this. First, set your PYTHONPATH environment variable
-       to point to <tt>tinyos-2.x/support/sdk/python</tt>. This tells
-       Python where to find the TOSSIM packages. Then, in an interpreter
-       type this:</p>
-
-        <pre>
-from tinyos.tossim.TossimApp import *
-
-n = NescApp()
-        </pre>
-
-        <p>Instantiating a <code>NescApp</code> can take quite a while:
-        Python has to parse through megabytes of XML. So be patient
-        (you only have to do it once). NescApp has two optional
-        arguments. The first is the name of the application being
-        loaded. The second is the XML file to load. The default for
-        the latter is <code>app.xml</code>, which is the name of the file
-        that the make system generates. The default for the former is
-        "Unknown App."  So this code behaves identically to that
-        above:</p>
-
-        <pre>
-from tinyos.tossim.TossimApp import *
-
-n = NescApp("Unknown App", "app.xml")
-        </pre>
-
-        <p>You fetch a list of variables from a NescApp object by
-        calling the function <code>variables</code> on the field
-        <code>variables</code>:</p>
-
-        <pre>
-vars = n.variables.variables()
-        </pre>
-
-        <p>To enable variable inspection, you pass this list to a
-        Tossim object when you instantiate it:</p>
-
-        <pre>
-t = Tossim(vars)
-        </pre>
-
-        <p>The TOSSIM object now knows the names, sizes, and types of
-        all of the variables in the TinyOS application. This
-        information allows the TOSSIM support code to take C variables
-        and properly tranform them into Python variables. This
-        currently only works for simple types: if a component declares
-        a structure, you can't access its fields. But let's say we
-        want to read the counter in <code>RadioCountToLedsC</code>. Since each mote
-        in the network has its own instance of the variable, we need
-        to fetch it from a specific mote:</p>
-
-        <pre>
-m = t.getNode(0)
-v = m.getVariable("RadioCountToLedsC.counter")
-        </pre>
-
-        <p>The name of a variable is usually <i>C.V</i>, where
-        <i>C</i> is the component name and <i>V</i> is the variable.
-        In the case of generic components, the name is <i>C.N.V</i>,
-        where <i>N</i> is an integer that describes which instance.
-        Unfortunately, there is currently no easy way to know what
-        <i>N</i> is from nesC source, so you have to root through
-        <code>app.c</code> in order to know.</p>
-
-        <p>Once you have a variable object (<code>v</code> in the above
-        code), you can fetch its value with the <code>getData()</code>
-        function:</p>
-
-        <pre>
-counter = v.getData()
-        </pre>
-
-        <p>Because <code>getData()</code> transforms the underlying C type
-        into a Python type, you can then use its return value in
-        Python expressions. For example, this script will start a
-        simulation of five nodes and run it until node 0's counter
-        reaches 10:</p>
-
-        <pre>
-from sys import *
-from random import *
-from TOSSIM import *
-from tinyos.tossim.TossimApp import *
-
-n = NescApp()
-t = Tossim(n.variables.variables())
-r = t.radio()
-
-f = open("topo.txt", "r")
-lines = f.readlines()
-for line in lines:
-  s = line.split()
-  if (len(s) > 0):
-    if (s[0] == "gain"):
-      r.add(int(s[1]), int(s[2]), float(s[3]))
-
-noise = open("meyer-heavy.txt", "r")
-lines = noise.readlines()
-for line in lines:
-  str = line.strip()
-  if (str != ""):
-    val = int(str)
-    for i in range(0, 4):
-      t.getNode(i).addNoiseTraceReading(val)
-
-for i in range (0, 4):
-  t.getNode(i).createNoiseModel()
-  t.getNode(i).bootAtTime(i * 2351217 + 23542399)
-
-m = t.getNode(0)
-v = m.getVariable("RadioCountToLedsC.counter")
-
-
-
-while (v.getData() < 10):
-  t.runNextEvent()
-
-print "Counter variable at node 0 reached 10."
-        </pre>
-
-      <p>The TOSSIM <A
-      HREF="../../../tos/lib/tossim/examples">examples</A>
-      subdirectory also has an example script, named
-      <code>variables.py</code>.</p>
-
-      <h1>Injecting Packets</h1>
-
-      <p>TOSSIM allows you to dynamically inject packets into a
-      network.  Packets can be scheduled to arrive at any time. If a
-      packet is scheduled to arrive in the past, then it arrives
-      immediately. Injected packets circumvent the radio stack: it is
-      possible for a node to receive an injected packet while it is in
-      the midst of receiving a packet from another node over its
-      radio.</p>
-
-      <p>TinyOS 2.0 has support for building Python packet objects.
-      Just like the standard Java toolchain, you can build a packet
-      class based on a C structure. The packet class gives you a full
-      set of packet field mutators and accessors. If an application
-      has a packet format, you can generate a packet class for it,
-      instantiate packet objects, set their fields, and have nodes
-      receive them.</p>
-
-      <p>The <code>RadioCountToLeds</code> application Makefile has an
-      example of how to do this. First, it adds the Python class as a
-      dependency for building the application. Whenever you compile
-      the app, if the Python class doesn't exist, make will build it
-      for you:</p>
-
-      <pre>
-BUILD_EXTRA_DEPS = RadioCountMsg.py RadioCountMsg.class
-      </pre>
-
-      <p>The Makefile also tells make how to generate RadioCountMsg.py:</p>
-
-      <pre>
-RadioCountMsg.py: RadioCountToLeds.h
-        mig python -target=$(PLATFORM) $(CFLAGS) -python-classname=RadioCountMsg RadioCountToLeds.h RadioCountMsg -o $@
-      </pre>
-
-      <p>The rule says to generate RadioCountMsg.py by calling mig
-      with the python parameter.  The Makefile also has rules on how
-      to build Java class, but that's not important for TOSSIM. Since
-      we've been using RadioCountToLeds so far, the Python class
-      should be there already.</p>
-
-      <p>RadioCountMsg.py defines a packet format, but this packet is
-      contained in the data payload of another format. If a node is
-      sending a <code>RadioCountMsg</code> over AM, then the <code>RadioCountMsg</code>
-      structure is put into the AM payload, and might look something
-      like this:</p>
-
-      <center>
-        <table BORDER=1>
-          <TR>
-            <TD WIDTH=100 BGCOLOR="#ffa0a0">AM Header</TD>
-            <TD WIDTH=100 BGCOLOR="white">RadioCountMsg</TD>
-            <TD WIDTH=100 BGCOLOR="#ffa0a0">AM Footer</TD>
-          </TR>
-        </table>
-      </center>
-      
-      <p>If it is sending it over a routing protocol. the packet is
-      put in the routing payload, and might look something like this:</p>
-
-      <center>
-        <table BORDER=1>
-          <TR>
-            <TD WIDTH=100 BGCOLOR="#ffa0a0">AM Header</TD>
-            <TD WIDTH=100 BGCOLOR="#00a0ff">Routing Header</TD>
-            <TD WIDTH=100 BGCOLOR="white">RadioCountMsg</TD>
-            <TD WIDTH=100 BGCOLOR="#ffa0a0">AM Footer</TD>
-          </TR>
-        </table>
-      </center>
-
-      <p>If you want to send a <code>RadioCountMsg</code> to a node, then you need
-      to decide how to deliver it. In the simple AM case, you place
-      the <code>RadioCountMsg</code> structure in a basic AM packet. In the routing
-      case, you put it in a routing packet, which you then put inside
-      an AM packet. We'll only deal with the simple AM case here.</p>
-
-      <p>To get an AM packet which you can inject into TOSSIM, you
-      call the <code>newPacket</code> function on a Tossim object. The
-      returned object has the standard expected AM fields:
-      <i>destination</i>, <i>length</i>, <i>type</i>, and <i>data</i>,
-      as well as <i>strength</i>.</p>
-
-      <p>To include support for a packet format, you must import
-      it. For example, to include <code>RadioCountMsg</code>, you have to import
-      it:</p>
-
-      <pre>
-from RadioCountMsg import *
-      </pre>
-      
-      <p>This snippet of code, for example, creates a <code>RadioCountMsg</code>,
-      sets its counter to 7, creates an AM packet, stores the
-      <code>RadioCountMsg</code> in the AM packet, and configures the AM packet so
-      it will be received properly (destination and type):</p>
-
-      <pre>
-from RadioCountMsg import *
-
-msg = RadioCountMsg()
-msg.set_counter(7);
-pkt = t.newPacket();
-pkt.setData(msg.data)
-pkt.setType(msg.get_amType())
-pkt.setDestination(0)
-      </pre>
-
-
-      <p>The variable <code>pkt</code> is now an Active Message of the AM
-      type of <code>RadioCountMsg</code> with a destination of 0 that contains a
-      <code>RadioCountMsg</code> with a counter of 7. You can deliver this packet
-      to a node with the <code>deliver</code> function. The
-      <code>deliver</code> function takes two parameters, the destination
-      node and the time to deliver:</p>
-
-      <pre>
-pkt.deliver(0, t.time() + 3)
-      </pre>
-
-      <p>This call delivers pkt to node 0 at the current simulation
-      time plus 3 ticks (e.g., 3ns). There is also a
-      <code>deliverNow</code>, which has no time parameter. Note that if
-      the destination of <code>pkt</code> had been set to 1, then the
-      TinyOS application would not receive the packet, as it was
-      delivered to node 0.</p>
-
-      <p>Taken all together, the following script starts a simulation,
-      configures the topology based on topo.txt, and delivers a packet
-      to node 0. It can also be found as <code>packets.py</code> in the TOSSIM <A
-      HREF="../../../tos/lib/tossim/examples/">examples</A>
-      subdirectory.
-
-      <pre>
-import sys
-from TOSSIM import *
-from RadioCountMsg import *
-
-t = Tossim([])
-m = t.mac();
-r = t.radio();
-
-t.addChannel("RadioCountToLedsC", sys.stdout);
-t.addChannel("LedsC", sys.stdout);
-
-for i in range(0, 2):
-  m = t.getNode(i);
-  m.bootAtTime((31 + t.ticksPerSecond() / 10) * i + 1);
-  
-f = open("topo.txt", "r")
-lines = f.readlines()
-for line in lines:
-  s = line.split()
-  if (len(s) > 0):
-    if (s[0] == "gain"):
-      r.add(int(s[1]), int(s[2]), float(s[3]))
-
-noise = open("meyer-heavy.txt", "r")
-lines = noise.readlines()
-for line in lines:
-  str = line.strip()
-  if (str != ""):
-    val = int(str)
-    for i in range(0, 4):
-      t.getNode(i).addNoiseTraceReading(val)
-
-for i in range (0, 4):
-  t.getNode(i).createNoiseModel()
-
-for i in range(0, 60):
-  t.runNextEvent();
-
-msg = RadioCountMsg()
-msg.set_counter(7);
-pkt = t.newPacket();
-pkt.setData(msg.data)
-pkt.setType(msg.get_amType())
-pkt.setDestination(0)
-
-print "Delivering " + str(msg) + " to 0 at " + str(t.time() + 3);
-pkt.deliver(0, t.time() + 3)
-
-
-for i in range(0, 20):
-  t.runNextEvent();
-      </pre>
-
-      
-      <h1>C++</h1>
-
-      <p>Python is very useful because it is succinct, easy to write,
-      and can be used interactively. Interpretation, however, has a
-      significant cost: a Python/C transition on every event is a
-      significant cost (around 100%, so it runs at half the
-      speed). Additionally, it's often useful to step through code
-      with a standard debugger. TOSSIM also has support for C++, so
-      that it can be useful in these circumstances.  Because many of
-      the Python interfaces are merely wrappers around C++ objects,
-      much of the scripting stays the same. The two major exceptions
-      are inspecting variables and injecting packets.</p>
-
-      <p>In a C++ TOSSIM, there is no variable inspection. While it is
-      possible to request memory regions and cast them to the expected
-      structures, currently there is no good and simple way to do
-      so. The Python support goes through several steps in order to
-      convert variables into Python types, and this gets in the way of
-      C++. However, as the purpose of C++ is usually to run high
-      performance simulations (in which inspecting variables is a big
-      cost) or debugging (when you have a debugger), this generally
-      isn't a big problem.</p>
-
-      <p>There is a C++ <code>Packet</code> class, which the Python
-      version is a simple wrapper around. In order to inject packets
-      in C++, however, you must build C support for a packet type and
-      manually build the packet. There currently is no support in mig
-      with which to generate C/C++ packet structures, and since most
-      packets are nx_struct types, they cannot be parsed by
-      C/C++. Furthermore, as many of the fields are nx types, they are
-      big endian, while x86 processors are little endian. Still, if you
-      want to deliver a packet through C++, you can do so.</p>
-
-      <p>Usually, the C++ and Python versions of a program look pretty
-      similar. For example (note that this program will use a lot of RAM
-         and take a long time to start due to its noise models):</p>
-
-      <table WIDTH=800>
-
-        <TR><TD WIDTH=400><TD WIDTH=400></TR>
-        <TR><TD ALIGN=CENTER><b>Python</b></TD><TD ALIGN=CENTER><b>C++</b></TD></TR>
-        <TR>
-          <TD VALIGN=TOP>
-            <PRE>
-import TOSSIM
-import sys
-import random
-
-from RadioCountMsg import *
-
-t = TOSSIM.Tossim([])
-r = t.radio();
-
-for i in range(0, 999):
-  m = t.getNode(i);
-  m.bootAtTime(5000003 * i + 1);
-  
-  for j in range (0, 2):
-    if (j != i):
-      r.add(i, j, -50.0);
-
-  # Create random noise stream
-  for j in range (0, 500):
-    m.addNoiseTraceReading(int(random.random() * 20) - 70);
-  m.createNoiseModel()
-
-for i in range(0, 1000000):
-  t.runNextEvent();
-           </PRE>
-          </TD>
-          <TD VALIGN=TOP>
-            <PRE>
-#include &lt;tossim.h&gt;
-#include &lt;stdlib.h&gt;
-
-
-int main() {
-  Tossim* t = new Tossim(NULL);
-  Radio* r = t->radio();
-
-  for (int i = 0; i &lt; 999; i++) {
-    Mote* m = t->getNode(i);
-    m->bootAtTime(5000003 * i + 1);
-    for (int j = 0; j &lt; 2; j++) {
-      if (i != j) {
-        r->add(i, j, -50.0);
-      }
-    }
-    for (int j = 0; j &lt; 500; j++) {
-       m->addNoiseTraceReading((char)(drand48() * 20) - 70);
-    }
-    m->createNoiseModel();
-  }
-
-
-  for (int i = 0; i &lt; 1000000; i++) {
-    t->runNextEvent();
-  }
-}
-            </PRE>
-          </TD>
-        </TR>
-      </TABLE>
-
-      <p>To compile a C++ TOSSIM, you have to compile the top-level
-      driver program (e.g, the one shown above) and link it against
-      TOSSIM. Usually the easiest way to do this is to link it against
-      the TOSSIM objects rather than the shared library. Often, it's
-      useful to have a separate Makefile to do this with. E.g.,
-      <code>Makefile.Driver</code>:</p>
-
-      <pre>
-all:
-        make micaz sim
-        g++ -g -c -o Driver.o Driver.c -I../../tos/lib/tossim/
-        g++ -o Driver Driver.o build/micaz/tossim.o build/micaz/sim.o build/micaz/c-support.o
-      </pre>
-        
-
-     <h2>Using gdb</h2>
-
-     <p>Since Driver is a C++ program, you can use gdb on it to
-     step through your TinyOS code, inspect variables, set 
-     breakpoints, and do everything else you can normally do.
-     Unfortunately, as gdb is designed for C and not nesC, the
-     component model of nesC means that a single command can have multiple
-providers; referring to a specific command requires specifying the component,
-interface, and command. For example, to break on entry to the <tt>redOff</tt>
-command of the <tt>Leds</tt> interface of <tt>LedsC</tt>, one must type:
-
-<pre>
-$ gdb Driver
-GNU gdb Red Hat Linux (6.0post-0.20040223.19rh)
-Copyright 2004 Free Software Foundation, Inc.
-GDB is free software, covered by the GNU General Public License, and you are
-welcome to change it and/or distribute copies of it under certain conditions.
-Type "show copying" to see the conditions.
-There is absolutely no warranty for GDB.  Type "show warranty" for details.
-This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".
-
-(gdb) break *LedsP$Leds$led0Toggle
-Breakpoint 1 at 0x804f184: file LedsP.nc, line 73.
-</pre>
-
-<p>nesC translates component names to C names using
-$. $ is a legal but almost-never-used character in some versions
-of C, so nesC prohibits it and uses it internally. The leading
-* is necessary so dbg can parse the $s. With the above
-breakpoint set, gdb will break whenever a mote toggles led0.</p>
-
-<p>Variables have similar names. For example, to inspect the packet
-of RadioCountToLedsC in the RadioCountToLeds application,</p>
-
-<pre>
-(gdb) print RadioCountToLedsC$packet
-$1 = {{header = {{data = ""}, {data = ""}, {data = ""}, {data = ""}, {
-        data = ""}}, data = {{data = ""} <repeats 28 times>}, footer = {{
-        data = ""}, {data = ""}}, metadata = {{data = ""}, {data = ""}, {
-        data = ""}, {data = ""}, {data = ""}}} <repeats 1000 times>}
-</pre>
-
-<p>For those who know gdb very well, you'll recognize this as a print
-of an array, rather than a single variable: there are more than 1000
-instances of the message_t struct. This is because TOSSIM simulates
-many motes; rather than there being a single RadioCountToLedsC$packet,
-there is one for every node. To print the packet of a specific node, you
-have to index into the array. This, for example, will print the variable
-for node 6:</p>
-
-<pre>
-(gdb) print RadioCountToLedsC$packet[6]
-$2 = {header = {{data = ""}, {data = ""}, {data = ""}, {data = ""}, {
-      data = ""}}, data = {{data = ""} <repeats 28 times>}, footer = {{
-      data = ""}, {data = ""}}, metadata = {{data = ""}, {data = ""}, {
-      data = ""}, {data = ""}, {data = ""}}}
-</pre>
-
-<p>If you want to print out the variable for the node TOSSIM is currently
-simulating, you can do this:</p>
-
-<pre>
-(gdb) print RadioCountToLedsC$counter[sim_node()]
-$4 = 0
-</pre>
-
-<p>You can also set watchpoints (although, as to be expected, they are
-<i>slow</i>:</p>
-
-<pre>
-(gdb) watch CpmModelC$receiving[23]
-Hardware watchpoint 2: CpmModelC$receiving[23]
-</pre>
-
-<p>This variable happens to be an internal variable in the 
-packet-level network simulation, which keeps track of whether
-the radio thinks it is receiving a packet. So setting the
-above watchpoint will cause gdb to break whenever 
-node 23 starts receiving a packet or returns to searching
-for packet preambles.</p>
-
-<p>Generic components add another wrinkle. Since they use
-a code-copying approach, each instance of a generic has its
-own separate functions and variables (this is mostly due to the
-fact that you can pass types to them). Take, for example,
-<code>AMQueueImplP</code>, which is used in both the radio
-AM stack and the serial AM stack. If you use gdb on an
-application that uses both serial and radio communication and
-try to break on its Send.send, you'll see an error:</p>
-
-<pre>
-(gdb) break *AMQueueImplP$Send$send
-No symbol "AMQueueImplP$Send$send" in current context.
-</pre>
-
-<p>nesC gives each generic a unique number. So if you
-have an application in which there is a single copy
-of AMQueueImplP, its name will actually be AMQueueImplP$0.
-For example, in RadioCountToLeds, this will work:</p>
-
-<pre>
-(gdb) break *AMQueueImplP$0$Send$send
-Breakpoint 5 at 0x8051b29: file AMQueueImplP.nc, line 79.
-</pre>
-
-<p>If you have multiple instances of a generic in a 
-program, there is unfortunately no easy way to figure out each one's
-name besides looking at the source code or stepping into them.
-E.g., if you application uses serial and radio communication,
-knowing which stack has AMQueueImpl$0 and which has AMQueueImplP$1
-requires either stepping through their send operation or looking
-at their <code>app.c</code> files.
-</p>
-
-<h1>Conclusions</h1>
-
-This lesson introduced the basics of the TOSSIM simulator. It showed
-you how to configure a network, how to run a simulation, how to
-inspect variables, how to inject packets, and how to compile with C++.
-
-<center>
-<p>&lt;&nbsp;<b><a href="lesson10.html">Previous Lesson</a></b> |&nbsp; <b><a
- href="index.html">Top</a></b> &nbsp;|&nbsp; <b><a href="lesson12.html">Next
-Lesson </a>&nbsp;&gt;</b>
-             </center>
-</p>
-
-
-           <A name="appendix"><H1>Appendix A: Troubleshooting TOSSIM compilation</H1></A>
-
-           <p>TOSSIM is a C/C++ shared library with an optional
-           Python translation layer. Almost all of the problems
-           encountered in compiling TOSSIM are due to C linking
-           issues. If you don't know what a linker is (or have never
-           linked a C program), then chances are the rest of this
-           appendix is going to be cryptic and
-           incomprehensible. You're best off starting with learning
-           about <A
-           HREF="http://en.wikipedia.org/wiki/Linker">linkers</A>, <A
-           HREF="http://www.iecc.com/linker/linker01.html">why they
-           are needed</A>, and how you <A
-           HREF="http://www.linuxjournal.com/article/6463">use the
-           gcc/g++ compilers</A> to link code.</p>
-               
-
-           <p>Generally, when compiling TOSSIM using <tt>make micaz sim</tt>,
-             one of four things can go wrong:</p>
-
-           <ol>
-             <li>You are using Cygwin but the <tt>sim</tt> compilation option
-               can't figure this out.</li>
-
-             <li>You do not have the needed Python support installed.</li>
-
-             <li>You have Python support installed, but the make
-             system can't find it.</li>
-
-             <li>You have Python support installed, but it turns out to
-               be incompatible with TOSSIM.</li>
-              
-              <li>You have a variant of gcc/g++ installed that 
-               expects slightly different compilation options than the
-               normal installation.</li>
-           </ol>
-
-           <p>We'll visit each in turn.</p>
-
-           <h2>You are using Cygwin but the <tt>sim</tt> compilation option
-             can't figure this out</h2>
-
-           <p>It turns out that the Cygwin and Linux versions of gcc/g++
-             have different command-line flags and require different options
-             to compile TOSSIM properly. For example, telling the Linux
-             compiler to build a library requires <tt>-fPIC</tt> while
-             the Cygwin is <tt>-fpic</tt>. If you're using Cygwin and
-             you see the output look like this:
-
-             <pre>
-  ncc -c -shared -fPIC -o build/micaz/sim.o ...
-             </pre>
-
-             rather than
-
-             <pre>
-  ncc -c -DUSE_DL_IMPORT -fpic -o build/micaz/sim.o ...
-             </pre>
-
-             then you have encountered this problem. The problem
-             occurs because Cygwin installations do not have a
-             consistent naming scheme, and so it's difficult for the
-             compilation toolchain to always figure out whether it's
-             under Linux or Cygwin.</p>
-
-           <p><b>Symptom:</b> You're running cygwin but you see the
-             <tt>-fPIC</tt> rather than <tt>-fpic</tt> option being
-             passed to the compiler.</b></p>
-           
-           <p><b>Solution:</b> Explicitly set the OSTYPE environment
-             variable to be <tt>cygwin</tt> either in your <tt>.bashrc</tt>
-             or when you compile. For example, in bash:</p>
-
-           <pre>
-$ OSTYPE=cygwin make micaz sim
-           </pre>
-
-           or in tcsh
-
-           <pre>
-$ setenv OSTYPE cygwin
-$ make micaz sim
-           </pre>
-
-           <p>Note that often this problem occurs in addition to
-           other ones, due to using a nonstandard Cygwin
-           installation. So you might have more problems to track
-           down.</p>
-           
-           <h2>You do not have the needed Python support installed</h2>
-
-           <p>If when you compile you see lots of errors such as
-           "undefined reference to" or "Python.h: No such file or
-           directory" then this might be your problem. It is a
-           subcase of the more general problem of TOSSIM not being
-           able to find needed libraries and files.</p>
-           
-           <p>Compiling Python scripting support requires that you
-             have certain Python development libraries installed. First, check
-             that you have Python installed:</p>
-
-           <pre>
-$ python -V
-Python 2.4.2
-           </pre>
-
-           <p>In the above example, the system has Python 2.4.2. If
-           you see "command not found" then you do not have Python
-           installed. You'll need to track down an RPM and install
-           it.  TOSSIM has been tested with Python versions 2.3 and
-           2.4. You can install other versions, but there's no
-           assurance things will work.</p>
-
-           <p>In addition to the Python interpreter itself, you need
-           the libraries and files for Python development. This is
-           essentially a set of header files and shared libraries. If
-           you have the <tt>locate</tt> command, you can type
-           <tt>locate libpython</tt>, or if you don't, you can look
-           in <tt>/lib</tt>, <tt>/usr/lib</tt> and
-           <tt>/usr/local/lib</tt>. You're looking for a file with a
-           name such as <tt>libpython2.4.so</tt> and a file named
-           <tt>Python.h</tt>. If you can't find these files, then you
-           need to install a <tt>python-devel</tt> package.</p>
-
-
-           <p><b>Symptom:</b> Compilation can't find critical files
-           such as the Python interpreter, <tt>Python.h</tt> or a
-           Python shared library, and searching your filesystem shows
-           that you don't have them.</p>
-
-           <p><b>Solution:</b> Installed the needed files from Python
-           and/or Python development RPMS.</p>
-
-           <p>If you have all of the needed files, but are still
-           getting errors such as "undefined reference" or "Python.h:
-           No such file or directory", then you have the next
-           problem: they're on your filesystem, but TOSSIM can't find
-           them.</p>
-             
-           <h2>You have Python support installed, but the make
-             system can't find it</h2>
-
-           <p>You've found libpython and Python.h, but when TOSSIM compiles
-           it says that it can't find one or both of them. If it can't
-           find Python.h then compilation will fail pretty early, as g++ won't
-           be able to compile the Python glue code. If it can't find the python
-           library, then compilation will fail at linking, and you'll see
-           errors along the lines of "undefined reference to __Py...". You
-           need to point the make system at the right place.</p>
-
-           <p>Open up <tt>support/make/sim.extra</tt>. If the make
-             system can't find Python.h, then chances are it isn't in
-             one of the standard places (e.g., /usr/include). You need to tell
-             the make system to look in the directory where Python.h is with
-             a <tt>-I</tt> option. At the top of sim.extra, under the PFLAGS entry,
-             add
-
-           <pre>
-CFLAGS += -I/path
-           </pre>
-
-             where <tt>/path</tt> is the path of the directory where Python.h
-             lives. For example, if it is in <tt>/opt/python/include</tt>,
-             then add <tt>CFLAGS += -I/opt/python/include</tt>.</p>
-           
-           <p>If the make system can't find the python library for
-           linking (causing "undefined reference") error messages,
-           then you need to make sure the make system can find
-           it. The sim.extra file uses two variables to find the
-           library: <tt>PYDIR</tt> and <tt>PYTHON_VERSION</tt>.  It
-           looks for a file named libpython$(PYTHON_VERSION).so. So
-           if you have Python 2.4 installed, make sure that
-           PYTHON_VERSION is 2.4 (be sure to use no spaces!) and if
-           2.3, make sure it is 2.3.</p>
-
-           <p>Usually the Python library is found in
-           <tt>/usr/lib</tt>. If it isn't there, then you will need
-           to modify the <tt>PLATFORM_LIB_FLAGS</tt> variable.  The
-           -L flag tells gcc in what directories to look for
-           libraries. So if libpython2.4.so is in
-           <tt>/opt/python/lib</tt>, then add
-           <tt>-L/opt/python/lib</tt> to the
-           <tt>PLATFORM_LIB_FLAGS</tt>. Note that there are three
-           different versions of this variable, depending on what OS
-           you're using. Be sure to modify the correct one (or be
-           paranoid and modify all three).
-
-             
-           <p><b>Symptom:</b> You've verified that you have the
-           needed Python files and libraries, but compilation is
-           still saying that it can't link to them ("undefined
-           reference") or can't find them ("cannot find -lpython2.4").</p>
-
-           <p><b>Solution:</b> Change the sim.extra file to point to
-           the correct directories using -L and -I flags.</p>
-
-           <h2>You have Python support installed, but it turns out to
-             be incompatible with TOSSIM.</h2>
-
-           <p><b>Symptom:</b> You get a "This python version requires
-             to use swig with the -classic option" error message.</p>
-
-           <p><b>Solution:</b> Install SWIG and regenerate Python
-           support with the sing-generate script in
-           <tt>tos/lib/tossim</tt>, or install a different version of
-           Python.</p>
-           
-              <h2>You have a variant of gcc/g++ installed that 
-               expects slightly different compilation options than the
-               normal installation.</h2>
-
-               <p><b>Symptom:</b> g++ complains that it cannot find
-                main() when you are compiling the shared library
-                ("undefined reference to `_WinMain@16'").</p>
-
-                <p><b>Solution:</b> There are two possible solutions.
-                The first is to include a dummy main(), as described
-                 in this <A HREF="http://mail.millennium.berkeley.edu/pipermail/tinyos-help/2006-December/021719.html">tinyos-help posting.</A> The
-                 second is to add the -shared option, as described in
-                 this <A HREF="http://curl.haxx.se/mail/archive-2003-01/0056.html">web page</A>.
-                 
-                 <p>Hopefully, these solutions worked and you can get back
-           to <A HREF="#compiling">compiling</A>, If not, then you
-               should email tinyos-help.</p>
-</center>
-
+<p>Sorry, your browser does not support frames. Please <a href="http://docs.tinyos.net/index.php/TOSSIM" target="_top">go here</a>.</p>
 </body>
-</html>
+</noframes>
+</frameset>
+</html>
\ No newline at end of file
index e94af8573c99b3af68cb9d0c2ea3a6482f86437f..c7c36ab711d906274e69d8207e05d76484e04d81 100644 (file)
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" ^M   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
-  <title>TinyOS Tutorial Lesson 12: Network Protocols</title>
-  <link href="../../stylesheets/tutorial.css" rel="stylesheet"
- type="text/css">
+<title>klueska.com</title>
 </head>
+<frameset>
+<frame src="http://docs.tinyos.net/index.php/Network_Protocols" name="redir_frame" />
+<noframes>
 <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/4bitle \<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="lesson11.html">Previous Lesson</a></b> |&nbsp; <b><a
- href="index.html">Top</a></b> &nbsp;|&nbsp; <b><a href="lesson13.html">Next
-Lesson </a>&nbsp;&gt;</b>
-</p>
-</center>
+<p>Sorry, your browser does not support frames. Please <a href="http://docs.tinyos.net/index.php/Network_Protocols" target="_top">go here</a>.</p>
 </body>
-</html>
+</noframes>
+</frameset>
+</html>
\ No newline at end of file
index c9559da9f1ee4cfa8441988cd2c9e68e4bd1e883..a56977c83d3bcdefcacb2bd53eb24a5cf8b8f7a8 100644 (file)
-<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
-<html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" ^M   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
-  <title>TinyOS Tutorial Lesson 13: TinyOS Toolchain</title>
-  <link href="../../stylesheets/tutorial.css" rel="stylesheet" type="text/css">
+<title>klueska.com</title>
 </head>
-
+<frameset>
+<frame src="http://docs.tinyos.net/index.php/TinyOS_Toolchain" name="redir_frame" />
+<noframes>
 <body>
-
-<div class="title">Lesson 13: TinyOS Toolchain</div>
-<div class="subtitle">Last updated October 29 2006</div>
-    
-<p> This lesson describes the details of the TinyOS toolchain, including
-the build system, how to create your own Makefile, and how to find out
-more information on the various tools included with TinyOS.
-
-<h1>TinyOS Build System</h1>
-
-As you saw in <a href="lesson1.html">Lesson 1</a>, TinyOS applications
-are built using a somewhat unconventional application of the 
-<i>make</i> tool. For instance, in the <code>apps/Blink</code> directory,
-
-<pre>$ make mica2
-</pre>
-
-compiles Blink for the mica2 platform,
-
-<pre>$ make mica2 install
-</pre>
-
-compiles and installs (using the default parallel port programmer) Blink
-for the mica2, and
-
-<pre>$ make mica2 reinstall mib510,/dev/ttyS0
-</pre>
-
-installs the previously compiled mica2 version of Blink using the MIB510
-serial port programmer connected to serial port /dev/ttyS0.
-
-<p>
-As these examples show, the TinyOS build system is controlled by passing
-arguments to make that specify the target platform, the desired action, 
-and various options. These arguments can be categorised as follows:
-
-<ul>
-<li>Target platform: one of the supported TinyOS platforms, e.g., <b>mica2</b>,
-<b>telosb</b>, <b>tinynode</b>. A target platform is always required,
-except when using the <b>clean</b> action.<p>
-
-<li>Action: the action to perform. By default, the action is to compile
-the application in the current directory, but you can also specify:
-
-  <ul>
-  <li> <b>help</b>: display a help message for the target platform.
-  <li> <b>install,<i>N</i></b>: compile and install. The <i>N</i> argument
-       is optional and specifies the mote id (default 1).
-  <li> <b>reinstall,<i>N</i></b>: install only (fails if the application wasn't previously compiled). <i>N</i> is as for <b>install</b>.
-  <li> <b>clean</b>: remove compiled application for all platforms.
-  <li> <b>sim</b>: compile for the simulation environment for the specified platform (see <a href="lesson11.html">Lesson 11</a> for details).
-  </ul>
-
-  Example: to compile for simulation for the micaz:
-  <pre>$ make micaz sim</pre>
-
-<li>Compilation option: you can change the way compilation proceeds by
-specifying:
-  <ul>
-  <li> <b>debug</b>: compile for debugging. This enables debugging, and
-       turns off optimisations (e.g., inlining) that make debugging
-       difficult.
-  <li> <b>debugopt</b>: compile for debugging, but leave optimisations
-       enabled. This can be necessary if compiling with <b>debug</b>
-       gives code that is too slow, or if the bug only shows up when
-       optimisation is enabled.
-  <li> <b>verbose</b>: enable a lot of extra output, showing all commands
-       executed by <i>make</i> and the details of the nesC compilation
-       including the full path of all files loaded. This can be helpful
-       in tracking down problems (e.g., when the wrong version of a
-       component is loaded).
-  <li> <b>wiring</b>, <b>nowiring</b>: enable or disable the use of
-       the nescc-wiring to check the wiring annotations in a nesC
-       program. See the nescc-wiring man page for more details.
-  </ul>
-
-  Example: to do a verbose compilation with debugging on the telosb:
-  <pre>$ make debug verbose telosb</pre>
-
-  <p>Additionally, you can pass additional compilation options by
-  setting the CFLAGS environment variable when you invoke make. For instance, 
-  to compile <code>apps/RadioCountoToLeds</code> for a mica2 with
-  a 900MHz radio set to ~916.5MHz, you would do:
-
-  <pre>$ env CFLAGS="-DCC1K_DEF_FREQ=916534800" make mica2 </pre>
-
-  Note that this will not work with applications whose Makefile 
-  defines CFLAGS (but this practice is discouraged, see the section
-  on <a href="#makefile">writing Makefiles</a> below).<p>
-
-<li>Installation option: some platforms have multiple programmers, and
-some programmers require options (e.g., to specify which serial port
-to use). The programmer is specified by including its name amongst the
-<i>make</i> arguments. Known programmers include <b>bsl</b> for
-msp430-based platforms and <b>avrisp</b> (STK500), <b>dapa</b> (MIB500
-and earlier), <b>mib510</b> (MIB510) and <b>eprb</b> (MIB600) for mica
-family motes.
-
-<p>Arguments to the programmer are specified with a comma after the
-programmer name, e.g.,
-
-<pre>$ make mica2dot reinstall mib510,/dev/ttyUSB1 </pre>
-<pre>$ make telosb reinstall bsl,/dev/ttyUSB1 </pre>
-
-to specify that the programmer is connected to serial port /dev/ttyUSB1.
-
-<p>More details on the programmers and their options can be found in
-your mote documentation.
-
-</ul>
-
-<h1>Customising the Build System</h1>
-
-You may find that you are often specifying the same options, e.g., that
-your mib510 programmer is always connected to /dev/ttyS1 or that you
-want to use channel 12 of the CC2420 radio rather than the default
-TinyOS 2 channel (26). To do this, put the following lines
-
-<pre>
-MIB510 ?= /dev/ttyS1
-PFLAGS = -DCC2420_DEF_CHANNEL=12
-</pre>
-in a file called <code>Makelocal</code> in the <code>support/make</code>
-directory. If you now compile in <code>apps/RadioCountToLeds</code>, you
-will see:
-<pre>
-$ make micaz install mib510
-    compiling RadioCountToLedsAppC to a micaz binary
-ncc -o build/micaz/main.exe -Os <b>-DCC2420_DEF_CHANNEL=12</b> ... RadioCountToLedsAppC.nc -lm
-    compiled RadioCountToLedsAppC to build/micaz/main.exe
-    ...
-    installing micaz binary using mib510
-uisp -dprog=mib510 <b>-dserial=/dev/ttyS1</b> ...
-</pre>
-
-The definition of <code>PFLAGS</code> passes an option to the nesC
-compiler telling it to define the C preprocessor symbol
-<code>CC2420_DEF_CHANNEL</code> to 12. The CC2420 radio stack checks
-the value of this symbol when setting its default channel.
-
-<p>The definition of <code>MIB510</code> sets the value of the
-argument to the <b>mib510</b> installation option, i.e.,
-<pre>$ make micaz install mib510 </pre>
-is now equivalent to
-<pre>$ make micaz install mib510,/dev/ttyS1 </pre>
-
-Note that the assignment to MIB510 was written using the <code>?=</code>
-operator. If you just use regular assignment (<code>=</code>), then the
-value in <code>Makelocal</code> will override any value you specify
-on the command line (which is probably not what you want...).
-
-<p><code>Makelocal</code> can contain definitions for any <i>make</i>
-variables used by the build system. Unless you understand the details of
-how this works, we recommend you restrict yourselves to defining:
-
-  <ul>
-  <li> <code>PFLAGS</code>: extra options to pass to the nesC compiler. Most
-       often used to define preprocessor symbols as seen above.
-  <li> <code><i>X</i></code>: set the argument for <i>make</i> argument <i>
-       x</i>, e.g., <code>MIB510</code> as seen above. You can, e.g., set the 
-       default mote id to 12 by adding <code>INSTALL ?= 12</code> and 
-       <code>REINSTALL ?= 12</code> to <code>Makelocal</code>.
-  </ul>
-
-<p>Some useful preprocessor symbols that you can define with 
-<code>PFLAGS</code> include:
-  <ul>
-  <li> DEFINED_TOS_AM_ADDRESS: the motes group id (default is 0x22).
-  <li> CC2420_DEF_CHANNEL: CC2420 channel (default is 26).
-  <li> CC1K_DEF_FREQ: CC1000 frequency (default is 434.845MHz).
-  <li> TOSH_DATA_LENGTH: radio packet payload length (default 28).
-  </ul>
-<p>
-
-<a name="makefile">
-<h1>Application Makefiles</h1>
-</a>
-
-To use the build system with your application, you must create a makefile
-(a file called <code>Makefile</code>) which contains at the minimum:
-
-<pre>
-COMPONENT=<i>TopLevelComponent</i>
-include $(MAKERULES)
-</pre>
-where <i>TopLevelComponent</i> is the name of the top-level component
-of your application.
-
-<p>TinyOS applications commonly also need to specify some options to the
-nesC compiler, and build some extra files alongside the TinyOS
-application. We will see examples of both, by looking at, and making a
-small change to, the <code>apps/RadioCountToLeds</code> application.
-
-<p>The RadioCountToLeds Makefile uses <code>mig</code> (see <a
-href="lesson4.html">Lesson 4</a>) to build files describing the layout
-of its messages, for use with python and Java tools:
-
-<pre>
-COMPONENT=RadioCountToLedsAppC
-<b>BUILD_EXTRA_DEPS = RadioCountMsg.py RadioCountMsg.class</b>
-
-RadioCountMsg.py: RadioCountToLeds.h
-       mig python -target=$(PLATFORM) $(CFLAGS) -python-classname=RadioCountMsg RadioCountToLeds.h RadioCountMsg -o $@
-
-RadioCountMsg.class: RadioCountMsg.java
-       javac RadioCountMsg.java
-
-RadioCountMsg.java: RadioCountToLeds.h
-       mig java -target=$(PLATFORM) $(CFLAGS) -java-classname=RadioCountMsg RadioCountToLeds.h RadioCountMsg -o $@
-
-include $(MAKERULES)
-</pre>
-
-The first and last line of this Makefile are the basic lines present in
-all TinyOS Makefiles; the line in bold defining BUILD_EXTRA_DEPS
-specifies some additional <i>make</i> targets to build alongside the
-main TinyOS application (if you are not familiar with make, this may be a
-good time to read a make tutorial, e.g., <a
-href="http://oucsace.cs.ohiou.edu/~bhumphre/makefile.html">this
-one</a>).
-
-<p>When you compile RadioCountToLeds for the first time, you will see that
-the two extra targets, <code>RadioCountMsg.py</code> and 
-<code>RadioCountMsg.class</code>, are automatically created:
-<pre>
-$ make mica2
-mkdir -p build/mica2
-mig python -target=mica2  -python-classname=RadioCountMsg RadioCountToLeds.h RadioCountMsg -o RadioCountMsg.py
-mig java -target=mica2  -java-classname=RadioCountMsg RadioCountToLeds.h RadioCountMsg -o RadioCountMsg.java
-javac RadioCountMsg.java
-    compiling RadioCountToLedsAppC to a mica2 binary
-    ...
-</pre>
-
-As this Makefile is written, these generated files are not deleted when
-you execute <code>make clean</code>. Fix this by adding the following line:
-<pre>
-CLEAN_EXTRA = $(BUILD_EXTRA_DEPS) RadioCountMsg.java
-</pre>
-to <code>apps/RadioCountToLeds/Makefile</code>. This defines the CLEAN_EXTRA
-make variable to be the same as BUILD_EXTRA_DEPS, with RadioCountMsg.java
-added to the end. The build system's <b>clean</b> target deletes all files
-in CLEAN_EXTRA:
-<pre>
-$ make clean
-rm -rf build RadioCountMsg.py RadioCountMsg.class RadioCountMsg.java
-rm -rf _TOSSIMmodule.so TOSSIM.pyc TOSSIM.py
-</pre>
-
-Finally, to see how to pass options to the nesC compiler, we will change
-RadioCountToLeds's source code to set the message sending period based
-on the preprocessor symbol <code>SEND_PERIOD</code>. Change the line in
-<code>RadioCountToLedsC.nc</code> that reads
-<pre> call MilliTimer.startPeriodic(1000);</pre>
-to
-<pre> call MilliTimer.startPeriodic(SEND_PERIOD);</pre>
-and add the following line to RadioCountToLeds's Makefile:
-<pre>
-CFLAGS += -DSEND_PERIOD=2000
-</pre>
-Note the use of <code>+=</code> when defining CFLAGS: this allows the user
-to also pass options to nesC when invoking make as we saw above (<code>env CFLAGS=x make ...</code>). 
-
-<p>Now compiling RadioCountToLeds gives:
-<pre>
-$ make mica2
-    ...
-    compiling RadioCountToLedsAppC to a mica2 binary
-ncc -o build/mica2/main.exe ... <b>-DSEND_PERIOD=2000</b> ... RadioCountToLedsAppC.nc -lm
-    compiled RadioCountToLedsAppC to build/mica2/main.exe
-    ...
-</pre>
-
-<h1>TinyOS Tools</h1>
-
-The TinyOS build system is designed to make it easier to write Makefiles
-for applications that support multiple platforms, programmers, etc in
-a uniform way. However, it's use is not compulsory, and all the tools it
-is built on can be used in your own build system (e.g., your own Makefile
-or simple build script). Below we show how to build and install the
-RadioCountToLeds application for a micaz with the mib510 programmer
-using just a few commands.
-
-<p>First, we compile RadioCountToLedsAppC.nc (the main component of
-the application) using the nesC compiler, ncc:
-<pre>
-$ ncc -target=micaz -o rcl.exe -Os -finline-limit=100000 -Wnesc-all -Wall RadioCountToLedsAppC.nc
-</pre>
-
-This generates an executable file, <code>rcl.exe</code>. Next, we want
-to install this program on a mote with mote id 15. First, we create a
-new executable, <code>rcl.exe-15</code>, where the variables storing the
-mote's identity are changed to 15, using the
-<code>tos-set-symbols</code> command:
-<pre>
-$ tos-set-symbols rcl.exe rcl.exe-15 TOS_NODE_ID=15 ActiveMessageAddressC\$addr=15
-</pre>
-
-Finally, we install this executable on the micaz using <code>uisp</code>, 
-to a mib510 programmer connected to port /dev/ttyUSB1:
-<pre>$ uisp -dpart=ATmega128 -dprog=mib510 -dserial=/dev/ttyUSB1 --erase --upload if=rcl.exe-15
-Firmware Version: 2.1
-Atmel AVR ATmega128 is found.
-Uploading: flash
-</pre>
-
-If you wish to follow this route, note two things: first, you can find out
-what commands the build system is executing by passing the <code>-n</code>
-option to make, which tells it to print rather than execute commands:
-<pre>
-$ make -n micaz install.15 mib510
-mkdir -p build/micaz
-echo "    compiling RadioCountToLedsAppC to a micaz binary"
-ncc -o build/micaz/main.exe -Os -finline-limit=100000 -Wall -Wshadow -Wnesc-all -target=micaz -fnesc-cfile=build/micaz/app.c -board=micasb  -fnesc-dump=wiring -fnesc-dump='interfaces(!abstract())' -fnesc-dump='referenced(interfacedefs, components)' -fnesc-dumpfile=build/micaz/wiring-check.xml RadioCountToLedsAppC.nc -lm
-nescc-wiring build/micaz/wiring-check.xml
-...
-</pre>
-
-Second, all the commands invoked by the build system should have man pages
-describing their behaviour and options. For instance, try the following
-commands:
-<pre>
-$ man tos-set-symbols
-$ man ncc
-$ man nescc
-</pre>
-    
-<h1>Related Documentation</h1>
-</a>
-<ul>
-<li> mica mote Getting Started Guide at <a href="http://www.xbow.com">Crossbow</a>
-<li> telos mote Getting Started Guide for <a href="http://www.moteiv.com">Moteiv</a>
-<li> <a href="lesson1.html">Lesson 1</a> introduced the build system.
-<li> <a href="lesson10.html">Lesson 10</a> describes how to add a new platform
-to the build system.
-<li> GNU make man page.
-<li> man pages for the nesC compiler (man ncc, man nescc) and the various
-TinyOS tools.
-</ul>
-
-<!-- Begin footer -->
-<br>
-<hr>
-<center>
-<p>&lt;&nbsp;<b><a href="lesson12.html">Previous Lesson</a></b> |&nbsp; <b><a
- href="index.html">Top</a></b> &nbsp;|&nbsp; <b><a href="lesson15.html">Next Lesson </a>&nbsp;&gt;</b>
-</center>
-
+<p>Sorry, your browser does not support frames. Please <a href="http://docs.tinyos.net/index.php/TinyOS_Toolchain" target="_top">go here</a>.</p>
 </body>
-</html>
-
-<!--  LocalWords:  toolchain mib telosb tinynode sim micaz inlining debugopt nc
- -->
-<!--  LocalWords:  nowiring nescc CFLAGS env DCC practice bsl msp avrisp STK lm
- -->
-<!--  LocalWords:  dapa eprb PFLAGS RadioCountToLedsAppC ncc uisp dprog dserial
- -->
-<!--  LocalWords:  TOS TOSH TopLevelComponent MAKERULES RadioCountToLeds DEPS
- -->
-<!--  LocalWords:  RadioCountMsg py mig classname java javac mkdir rf TOSSIM
- -->
-<!--  LocalWords:  TOSSIMmodule pyc RadioCountToLeds's MilliTimer startPeriodic
- -->
-<!--  LocalWords:  DSEND rcl exe finline Wnesc tos ActiveMessageAddressC addr
- -->
-<!--  LocalWords:  dpart ATmega Atmel AVR Wshadow fnesc cfile micasb dumpfile
- -->
-<!--  LocalWords:  interfacedefs telos Moteiv
- -->
+</noframes>
+</frameset>
+</html>
\ No newline at end of file
index 5e17b9dbd50afa3d79ef749f991dbb0a3e05126b..22b039f46546f5222a9ab117904026a67e1b88dd 100644 (file)
-<html>
-    <head>
-      <title>TinyOS Tutorial Lesson 15: The TinyOS printf Library</title>
-      <link href="../../stylesheets/tutorial.css" rel="stylesheet" Type="text/css">
-  </head>
-  <body>
-    
-    <div class="title">Lesson 15: The TinyOS <code><font size=6>printf</font></code> Library</div>
-    <div class="subtitle">Last updated August 19th, 2007</div>
-    
-    <p>This lesson demonstrates how to use the <code>printf</code> library located in 
-    <code>tos/lib/printf</code> to debug TinyOS applications by printing messages over
-    the serial port.</p>
-    
-    <h1>Overview</h1>
-    <p> 
-    Anyone familiar with TinyOS knows that debugging applications has 
-    traditionally been a very arduous, if not stressful process.  While simulators
-    like TOSSIM can be used to help verify the logical correctness of a program, 
-    unforseen problems inevitably arise once that program is deployed on 
-    real hardware.  Debugging such a program typically involves flashing the 
-    three available LEDs in some intricate sequence or resorting to line by line 
-    analysis of a running program through the use of a JTAG.
-    </p>
-    <p>
-    It is common practice when developing desktop applications to print output 
-    to the terminal screen for debugging purposes. While tools such as 
-    <code>gdb</code> provide means of stepping though a program line by line,
-    often times developers simply want to quickly print something to the screen 
-    to verify that the value of a variable has been set correctly, or determine 
-    that some sequence of events is being run in the proper order.  It would be 
-    absurd to suggest that they only be allowed three bits of information in order
-    to do so.
-    </p>
-    <p>
-    The TinyOS <code>printf</code> library provides this terminal printing functionality 
-    to TinyOS applications through motes connected to a pc via their serial interface.
-    Messages are printed by calling 
-    <code>printf</code> commands using a familiar syntax borrowed from the C programming 
-    language.  In order to use this functionality, developers simply need to include 
-    a single component in their top level configuration file (<code>PrintfC</code>),
-    and include a <code>"printf.h"</code> header file in any components that actually call 
-    <code>printf()</code>.
-    </p>
-    <p>
-    Currently, the <code>printf</code> library is only supported on msp430 and atmega128x 
-    based platforms (e.g. mica2, micaZ, telos, eyesIFX).  In the future we hope to add 
-    support for other platforms as well.  
-    </p>
-    <h1>The TinyOS <code>printf</code> Library</h1>
-    This section provides a basic overview of the TinyOS <code>printf</code> library,
-    including the components that make it up and the interfaces they provide.
-    In the following section we walk you through the process of actually using these components
-    to print messages from a mote to your pc.  If you dont care how <code>printf</code>
-    works and only want to know how to use it, feel free to skip ahead to the next section.
-    <hr></hr>
-    The entire <code>printf</code> library consists of only 4 files located
-    in the <code>tos/lib/printf</code> directory: one module,
-    one configuration, one interface file, and one header file.
-    <br><br>
-    <ul>
-      <li><b>PrintfC.nc</b>      -- Configuration file providing printf functionality to TinyOS applications
-      <li><b>PrintfP.nc</b>      -- Module implementing the printf functionality
-      <li><b>PrintfFlush.nc</b>  -- Interface for flushing printf messages over the serial port to a pc
-      <li><b>printf.h</b>        -- Header file specifying the printf message format and size of the flush buffer</pre>
-    </ul>
-    <p>
-    The <code>PrintfC</code> configuration is the only component an application needs to wire
-    in order to use the functionality provided by the TinyOS <code>printf</code>
-    library.  Below is the component graph of the <code>PrintfC</code> configuration:
-    </p>
-    <center><img src=img/printf_components.png></img><p><b>Figure 1: The component
-    graph of the PrintfC configuration.</b></p></center>
-    <p>
-    Conceptually, the operation of the TinyOS <code>printf</code> library is very
-    simple.  Developers supply strings to <code>printf()</code> commands in a
-    distributed fashion throughout any of the components that make up a complete
-    TinyOS application.  These strings are buffered in a central location inside
-    the <code>PrintfP</code> component and flushed out to a PC in the form of
-    TinyOS SerialMessages upon calling the <code>flush()</code> command of the
-    <code>PrintfFlush</code> interface.
-    </p>
-    <p>
-    By encapsulating the strings produced by calls to <code>printf()</code> inside
-    standard TinyOS SerialMessages, applications that use the serial stack for
-    other purposes can share the use of the serial port.  Alternate
-    implementations were considered in which <code>printf</code> would have
-    had exclusive access to the serial port, and explicit flushing would not have
-    been necessary.  In the end, we felt it was better to give developers the
-    freedom to decide exactly when messages should be printed, as well as allow them
-    to send multiple types of SerialMessages in a single application.
-    </p>
-    <p>
-    Currently, only a single buffer is used to store the strings supplied to
-    calls to <code>printf</code> before flushing them.  This means that while
-    the buffer is being flushed, any calls to <code>printf</code> will fail.
-    In the future, we plan to implement a double buffered approach so that
-    strings can continue to be buffered at the same time they are being printed.
-    </p>
-    <p>
-    There are also plans to provide a means of flushing messages out to a PC
-    without requiring developers to make an explicit <code>flush()</code> call.
-    This would allow developers to simply wire in the <code>PrintfC</code> component
-    without having to make any calls to any interfaces it provides.  In fact,
-    the <code>PrintfC</code> component would not need to provide any interfaces
-    at all.  It would start itself up and then run in a loop, periodically
-    flushing the contents of the <code>printf</code> buffer.
-    Such functionality is useful in applications that do not really care when
-    messages are printed or how long a delay the process of printing introduces
-    to other sections of code.  Explicit flushing would still be recommended in
-    applications where the sections of code under examinatation are very timing
-    sensitive (e.g. inside the CC2420 radio stack).
-    </p>
-    <h1>Using the TinyOS <code>printf</code> Library</h1>
-
-    <p>
-    To help guide the process of using the <code>printf</code> library, a
-    <code>TestPrintf</code> application has been created.
-    At present, this application is not included in
-    the official TinyOS distribution (<= 2.0.2).  If you are using TinyOS
-    from a cvs checkout, you will find it located under
-    <code>apps/tutorials/Printf</code>.  Otherwise, you can obtain it from
-    cvs by running the following set of commands from a terminal window:
-    </p>
-
-    <pre>
-cd $TOSROOT/apps/tutorials
-cvs -d:pserver:anonymous@tinyos.cvs.sourceforge.net:/cvsroot/tinyos login
-cvs -z3 -d:pserver:anonymous@tinyos.cvs.sourceforge.net:/cvsroot/tinyos co -P -d Printf tinyos-2.x/apps/tutorials/Printf</pre>
-    <p>
-    Just hit enter when prompted for a CVS password.  You do not need to enter one.
-    </p>
-
-    <p>
-    If you are not using cvs, you will also have to apply the patch
-    found <a href=http://sing.stanford.edu/klueska/tinyos-2.0-printf.patch>here</a>
-    in order to allow the <code>printf</code> library to compile correctly for
-    atmega128x based platforms (i.e. mica2, micaz):
-    </p>
-    <pre>
-    cp tinyos-2.0-printf.patch $TOSROOT/..
-    cd $TOSROOT/..
-    patch -p0 < tinyos-2.0-printf.patch</pre>
-    <p>
-    Note that you may have to use 'sudo' when applying the patch if you run into
-    permission problems.
-    </p>
-
-    <hr></hr>
-
-    <p>
-    The <code>TestPrintf</code> application demonstrates everything necessary
-    to use the <code>printf</code> library.  Go ahead and open the
-    <code>TestPrintfAppC</code> configuration to see how the various interfaces
-    provided by the <code>PrintfC</code> component have been wired in. You will
-    want to do something similar in your own applications.
-
-    <pre>
-configuration TestPrintfAppC{
-}
-implementation {
-  components MainC, TestPrintfC, LedsC;
-  components PrintfC;
-
-  TestPrintfC.Boot -> MainC;
-  TestPrintfC.Leds -> LedsC;
-  TestPrintfC.PrintfControl -> PrintfC;
-  TestPrintfC.PrintfFlush -> PrintfC;
-}</pre>
-
-    <p>
-    First, the <code>PrintfControl</code> interface has been wired in to enable turning on and
-    off the service providing <code>printf</code> functionality.  Turning on
-    the <code>Printf</code> service implicity
-    turns on the serial port for sending messages.  Second, the <code>PrintfFlush</code>
-    interface has been wired in to allow the application to control when
-    <code>printf</code> messages should be flushed out over the serial line.  In this
-    application, all <code>printf()</code> commands are called directly within the
-    <code>TestPrintfC</code> component.  In general, <code>printf()</code> commands can be
-    called from any component as long as they have included the <code>"printf.h"</code>
-    header file.
-    </p>
-    <hr></hr>
-    <p>
-    Before examining the <code>TestPrintfC</code> component, first install the
-    application on a mote and see what kind of output it produces.
-    Note that the instructions here are only valid for installation on a telosb mote
-    on a linux based TinyOS distribution.
-    For installation on other systems or for other mote platforms, please refer to
-    <a href="lesson1.html"> lesson 1</a> for detailed instructions.
-    </p>
-    <p>
-    To install the application on the mote, run the following set of commands.
-    </p>
-    <pre>
-cd $TOSROOT\apps\tests\TestPrintf
-make telosb install bsl,/dev/ttyUSBXXX</pre>
-    <p>
-    You will notice during the installation process that a pair of java files are
-    compiled along with the TinyOS application.  The first java file,
-    <code>PrintfMsg.java</code>, is generated by <code>mig</code>
-    to encapsulate a TinyOS <code>printf</code> message received over the serial
-    line (for more information on mig and how it generates these files, please refer
-    to the section entitled "MIG: generating packet objects" in
-    <a href=lesson4.html>lesson 4</a>).  The second file, <code>PrintfClient.java</code>
-    is used to read <code>printf</code> messages received from a mote and print
-    them to your screen.
-    </p>
-    <p>
-    To see the output generated by <code>TestPrintf</code> you need to start the
-    <code>PrintfClient</code> by running the following command:
-    </p>
-    <pre>
-cd $TOSROOT\apps\tests\TestPrintf
-java PrintfClient -comm serial@/dev/ttyUSBXXX:telosb</pre>
-
-    <p>
-    After resetting the mote, the following output should be printed to your screen:
-    </p>
-    <pre>
-Hi I am writing to you from my TinyOS application!!
-Here is a uint8: 123
-Here is a uint16: 12345
-Here is a uint32: 1234567890
-I am now iterating: 0
-I am now iterating: 1
-I am now iterating: 2
-I am now iterating: 3
-I am now iterating: 4
-This is a really short string...
-I am generating this string to have just less than 250
-characters since that is the limit of the size I put on my
-maximum buffer when I instantiated the PrintfC component.
-Only part of this line should get printed bec</pre>
-
-    <p>
-    Note that the 'tty' device (i.e. COM port) specified when starting the PrintfClient
-    MUST be the one used for communicating with a mote over the serial line.  On telos
-    and mica motes this is the same port that the mote is programmed from.  Other motes,
-    such as eyesIFX, have one port dedicated to programming and another for
-    communication. Just make sure you use the correct one.
-    </p>
-    <p>
-    If for some reason you do not receive the output shown above, please refer
-    to <a href=lesson4.html>lesson 4</a> to verify you have done everything
-    necessary to allow serial communication between your pc and the mote.  Remember
-    that when using the MIB510 programming board that the switch on the very front
-    of the board must be set to the <font style=bold>OFF</font> position in order to send
-    messages from the mote to the pc.
-    </p>
-    <hr></hr>
-    <p>
-    Go ahead and open up <code>TestPrintfC</code> to see how this output is being generated.
-    </p>
-    <p>
-    Upon receiving the booted event, the <code>Printf</code> service is started via a call to
-    <code>PrintfControl.start()</code>
-    </p>
-    <pre>
-event void Boot.booted() {
-  call PrintfControl.start();
-}</pre>
-    <p>
-    Once the <code>Printf</code> service has been started, a
-    <code>PrintfControl.startDone()</code> event is generated.  In the body of this event
-    the first four
-    lines of output are generated by making successive calls to <code>printf</code>
-    and then flushing the buffer they are stored in.
-    </p>
-    <pre>
-event void PrintfControl.startDone(error_t error) {
-  printf("Hi I am writing to you from my TinyOS application!!\n");
-  printf("Here is a uint8: %u\n", dummyVar1);
-  printf("Here is a uint16: %u\n", dummyVar2);
-  printf("Here is a uint32: %ld\n", dummyVar3);
-  call PrintfFlush.flush();
-}</pre>
-    <p>
-    Once these first four lines have been flushed out, the <code>PrintfFlush.flushDone()</code>
-    event is signaled.  The body of this event first prints the next 5 lines in a loop,
-    followed by the last five lines.  Finally, once all lines have been printed, the
-    <code>Printf</code> service is stopped via a call to <code>PrintfControl.stop()</code>.
-    </p>
-    <pre>
-event void PrintfFlush.flushDone(error_t error) {
-  if(counter < NUM_TIMES_TO_PRINT) {
-    printf("I am now iterating: %d\n", counter);
-    call PrintfFlush.flush();
-  }
-  else if(counter == NUM_TIMES_TO_PRINT) {
-    printf("This is a really short string...\n");
-    printf("I am generating this string to have just less <font color=red>...</font>
-    printf("Only part of this line should get printed bec <font color=red>...</font>
-    call PrintfFlush.flush();
-  }
-  else call PrintfControl.stop();
-  counter++;
-}</pre>
-    <p>
-    Notice that the last line of output is cut short before being fully printed.
-    If you actually read the line printed above it you can see why.  The buffer
-    used to store TinyOS <code>printf</code> messages before they are flushed
-    is by default limited to 250 bytes.  If you try and print more characters than
-    this before flushing, then only the first 250 characters will actually be printed.
-    This buffer size is configurable, however, by specifying the proper CFLAGS option
-    in your Makefile.
-    </p>
-    <pre>
-CFLAGS += -DPRINTF_BUFFER_SIZE=XXX</pre>
-    <p>
-    Once the the <code>Printf</code> service has been stopped, the
-    <code>PrintfControl.stopDone()</code> event is signaled and Led 2 is turned
-    on to signify that the application has terminated.
-    </p>
-    <pre>
-  event void PrintfControl.stopDone(error_t error) {
-    counter = 0;
-    call Leds.led2Toggle();
-    printf("This should not be printed...");
-    call PrintfFlush.flush();
-  }
-    </pre>
-    <p>
-    Notice that the call to <code>printf()</code> inside the body of the
-    <code>PrintfControl.stopDone()</code> event never produces any output.
-    This is because the <code>Printf</code> service has been stopped before
-    this command is called.
-    </p>
-    <h1>Conclusion</h1>
-    <p>
-    A few points are worthy of note before jumping in and writing your own applications that
-    use the functionality provided by the <code>printf</code> library.
-    </p>
-    <ol>
-      <li>In order to use the <code>printf</code> library, the <code>tos/lib/printf</code>
-          directory must be in your include path.  The easiest way to include it is
-          by adding the following line directly within the Makefile of your top
-          level application:
-          <pre>
-CFLAGS += -I$(TOSDIR)/lib/printf</pre>
-          Remember that changing the <code>printf</code> buffer size is done similarly:
-          <pre>
-CFLAGS += -DPRINTF_BUFFER_SIZE=XXX</pre>
-      </li>
-      <li>You MUST be sure to #include <code>"printf.h"</code> header file in
-          every component in which you would like to call the <code>printf()</code>
-          command.  Failure
-          to do so will result in obscure error messages making it difficult to identify
-          the problem.</li>
-    </ol>
-
-<p>
-Hopefully you now have everything you need to get going with the TinyOS <code>printf</code>
-library.  All questions (or comments) about the use of this library should be directed to
-<a href=mailto:tinyos-help@millennium.berkeley.edu>tinyos-help</a> mailing list.
-</p>
-
-<p>
-Enjoy!!
-</p>
-
-<!--
-<a name=#related_docs>
-<h1>Related Documentation</h1>
-</a>
-<ul>
-<li> <a href="../tep102.html">TEP 102: Timers</a>
-<li> <a href="../tep106.html">TEP 106: Schedulers and Tasks</a>
-</ul>
--->
-
-<!-- Begin footer -->
-<br>
-<hr>
-<center>
-<p>&lt;&nbsp;<b><a href="lesson13.html">Previous Lesson</a></b> |&nbsp; <b><a
- href="index.html">Top</a></b> &nbsp;|&nbsp; <b><a href="lesson16.html">Next Lesson </a>&nbsp;&gt;</b>
-</center>
-
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" ^M   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<title>klueska.com</title>
+</head>
+<frameset>
+<frame src="http://docs.tinyos.net/index.php/The_TinyOS_printf_Library" name="redir_frame" />
+<noframes>
+<body>
+<p>Sorry, your browser does not support frames. Please <a href="http://docs.tinyos.net/index.php/The_TinyOS_printf_Library" target="_top">go here</a>.</p>
 </body>
-</html>
+</noframes>
+</frameset>
+</html>
\ No newline at end of file
index 59711c3e80e552850083999c216e18df27d10576..a500965122ed6503536158863ed99c4bcc3faf77 100644 (file)
-<html>
-    <head>
-      <title>TinyOS Tutorial Lesson 16: Writing Low Power Sensing Applications</title>
-      <link href="../../stylesheets/tutorial.css" rel="stylesheet" Type="text/css">
-  </head>
-  <body>
-    
-    <div class="title">Lesson 16: Writing Low Power Sensing Applications</div>
-    <div class="subtitle">Last updated August 31st, 2007</div>
-    
-    <p>
-    This lesson demonstrates how to write low power sensing applications in TinyOS.  At 
-       any given moment, the power consumption of a wireless sensor node is a function of its
-       microcontroller power state, whether the radio, flash, and sensor peripherals are on, 
-       and what operations active peripherals are performing.  This tutorial shows you 
-       how to best utilize the features provided by TinyOS to keep the power consumption
-       of applications that use these devices to a minumum.
-       </p>
-    
-    <h1>Overview</h1>
-    <p>
-    Energy management is a critical concern in wireless sensor networks.  Without it, 
-    the lifetime of a wireless sensor node is limited to just a few short weeks or even 
-    days, depending on the type of application it is running and the size of batteries 
-    it is using.  With proper energy management, the same node, running the 
-    same application, can be made to last for months or years on the same set of batteries.
-    </p>
-    <p>
-    Ideally, one would want all energy management to be handled transparently by the
-    operating system, relieving application developers from having to deal with this 
-    burden themselves.  While attempts have been made in the past to provide such
-    capabilities, most operating systems today still just provide the necessary primitives for 
-    performing energy management -- the logic of when and how to do so is left completely up 
-    to the application.
-    </p>
-    <p>
-       TinyOS provides a novel method of performing energy management directly 
-       within the OS. The method it uses is as efficient as it is elegant.  Developers 
-       no longer have to struggle with code that explicitly manages the power state for any of the
-       peripheral devices that it uses.  To get a better idea of the complexity involved in 
-       doing something as simple as periodically taking a set of sensor readings 
-       and logging them to flash in the most energy efficient manner possible, take a look 
-       at the pseudo code found below.
-       </p>
-       <pre>   
-Every Sample Period:
-  Turn on SPI bus              
-  Turn on flash chip           
-  Turn on voltage reference    
-  Turn on I2C bus              
-  Log prior readings           
-  Start humidity sample        
-  Wait 5ms for log             
-  Turn off flash chip          
-  Turn off SPI bus             
-  Wait 12ms for vref          
-  Turn on ADC
-  Start total solar sample
-  Wait 2ms for total solar
-  Start photo active sample
-  Wait 2ms for photo active
-  Turn off ADC
-  Turn off vref
-  Wait 34ms for humidity
-  Start temperature sample
-  Wait 220ms for temperature
-  Turn off I2C bus
-       </pre>
-       <p>
-       With the methods provided by TinyOS, hand-tuned application code that looks like that 
-       can be transformed into this:
-       </p>
-       <pre>    
-Every Sample Period:
-  Log prior readings
-  Sample photo active
-  Sample total solar
-  Sample temperature
-  Sample humidity 
-       </pre>
-       <p>
-       The pseudo code shown above is for concurrently sampling all of the 
-       the onboard sensors found on the latest revision of the tmote sky sensor nodes.
-    Experiments have shown that using the methods provided by TinyOS, this application 
-    comes within 1.6% of the energy efficiency of the hand-tuned implementation -- 
-    even at sampling rates as fast as 1 sample per second.  For more information
-    on these experiments and the method TinyOS uses to actually manage energy
-    so efficiently, please refer to the paper found 
-    <a href="http://sing.stanford.edu/klueska/Black_Site/Publications_files/klues07icem.pdf">
-    here.</a> 
-       </p>
-       <!---
-       <center>
-       <img src="img/tmote_current.png" width=66% ></img>
-       </center>
-       -->
-       <p>
-       The rest of this tutorial is dedicated to teaching you how to write applications
-       that allow TinyOS to manage energy for you in the most efficient manner possible.  
-       As a rule, TinyOS can manage energy more efficiently when I/O requests are submitted
-       by an application in parallel.  Submitting them serially may result in energy
-       wasted by unnecessarily turning devices on and off more frequently than required. 
-       </p>
-       <h1>
-       Peripheral Energy Management
-       </h1>
-       <p>
-       Compare the following two code snippets:
-       </p>
-<table>
- <tr><td><b>Parallel</b></td><td width=10></td><td><b>Serial</b></td></tr>
- <tr><td valign=top>
-<pre>
-event void Boot.booted() {
-  call Timer.startPeriodic(SAMPLE_PERIOD);
-}
-
-event void Timer.fired() {
-  call LogWrite.append(current_entry, sizeof(log_entry_t));
-
-  current_entry_num = !current_entry_num;
-  current_entry = &(entry[current_entry_num]);
-  current_entry->entry_num = ++log_entry_num;
-  
-  call Humidity.read();
-  call Temperature.read();
-  call Photo.read();
-  call Radiation.read();
-}
-  
-event void Humidity.readDone(error_t result, uint16_t val) {
-  if(result == SUCCESS) {
-   current_entry->hum = val;
-  }
-  else current_entry->hum  = 0xFFFF;
-}
-  
-event void Temperature.readDone(error_t result, uint16_t val) {     
-  if(result == SUCCESS) {
-    current_entry->temp = val; 
-  }
-  else current_entry->temp = 0xFFFF;
-}
-  
-event void Photo.readDone(error_t result, uint16_t val) {
-  if(result == SUCCESS) {
-    current_entry->photo = val;
-  }
-  else current_entry->photo = 0xFFFF;
- }
-  
-event void Radiation.readDone(error_t result, uint16_t val) {
-  if(result == SUCCESS) {
-    current_entry->rad = val;
-  }
-  else current_entry->rad = 0xFFFF;
-}
-
-event void LogWrite.appendDone(void* buf, 
-                               storage_len_t len, 
-                               bool recordsLost, 
-                               error_t error) {
-  if (error == SUCCESS) 
-    call Leds.led2Toggle();
-}
-</pre>
-</td>
-<td></td>
-<td valign=top>
-<pre>
-event void Boot.booted() {
-  call Timer.startPeriodic(SAMPLE_PERIOD);
-}
-
-event void Timer.fired() {
-  call Humidity.read();
-}
-  
-event void Humidity.readDone(error_t result, uint16_t val) {
-  if(result == SUCCESS) {
-    entry->rad = val;
-  }
-  else current_entry->rad = 0xFFFF;
-  call Temperature.read();
-}
-  
-event void Temperature.readDone(error_t result, uint16_t val) {     
-  if(result == SUCCESS) {
-    entry->rad = val;
-  }
-  else current_entry->rad = 0xFFFF;
-  call Photo.read();
-}
-  
-event void Photo.readDone(error_t result, uint16_t val) {
-  if(result == SUCCESS) {
-    entry->rad = val;
-  }
-  else current_entry->rad = 0xFFFF;
-  call Radiation.read();
-}
-  
-event void Radiation.readDone(error_t result, uint16_t val) {
-  if(result == SUCCESS) {
-    entry->rad = val;
-  }
-  else current_entry->rad = 0xFFFF;
-  call LogWrite.append(entry, sizeof(log_entry_t));
-}
-
-event void LogWrite.appendDone(void* buf, 
-                               storage_len_t len, 
-                               bool recordsLost, 
-                               error_t error) {
-  if (error == SUCCESS) 
-    call Leds.led2Toggle();
-}
-
-
-
-
-
-  </pre>
-  </td>
-  </tr>
-  </table>
-  <p>
-  In the parallel case, logging to flash and requesting samples from each sensor is 
-  all done within the body of the <code>Timer.fired()</code> event.  In the serial case, 
-  a chain of events is triggered by first calling <code>Humidity.read()</code> in
-  <code>Timer.fired()</code>, sampling each subsequent sensor in the body of the previous 
-  <code>readDone()</code> event, and ending with all sensor readings 
-  being logged to flash.
-  </p>
-  <p>
-  By logging to flash and sampling all sensors within the body of a single event, the OS
-  has the opportunity to schedule each operation as it sees fit.  Performing each operation
-  after the completion of the previous one gives the OS no such opportunity.  The only 
-  downside of the parallel approach is that the application must manually manage a double 
-  buffer so that the values written to flash are not overwritten before they are logged. To save
-  the most energy, however, the parallel version should always be used. 
-  Keep in mind that in both cases, the developer must also make sure that the sampling 
-  interval is longer than the time it takes to gather all sensor readings.  If it is not, 
-  data corruption will inevitably occur.
-  </p>
-  <h1>
-  Radio Power Management
-  </h1>
-  <p>
-  By default, TinyOS provides low power radio operation through a technique known as
-  <i>Low-Power Listening</i>.  In low-power listening, a node turns on
-  its radio just long enough to detect a carrier on the channel. 
-  If it detects a carrier, then it keeps the radio on long enough to detect a packet.  
-  Because the LPL check period is much longer than a packet, a transmitter must send 
-  its first packet enough times for a receiver to have  a chance to hear it. The
-  transmitter stops sending once it receives a link-layer acknowledgment or a timeout 
-  of twice the check period. When a node receives a packet, it stays awake long
-  enough to receive a second packet. Therefore, a packet burst amortizes the wakeup 
-  cost of the first packet over the follow-up packets. It is therefore more energy
-  efficient to send packets in bursts when using low-power listening than sending individual 
-  packets at some fixed constant rate.  Keep this in mind when developing applications
-  that require low power operation.
-  </p>
-  <p>
-  Controlling the operation of low-power listening in TinyOS is provided through the 
-  use of the <code>LowPowerListening</code> interface.  Currently, this interface
-  is only supported for the cc1000 and cc2420 radios.  In the future we hope to 
-  support other radio platforms as well.
-  </p>
-  <pre>
-interface LowPowerListening {
-  /**
-   * Set this this node's radio sleep interval, in milliseconds.
-   * Once every interval, the node will sleep and perform an Rx check 
-   * on the radio.  Setting the sleep interval to 0 will keep the radio
-   * always on.
-   *
-   * This is the equivalent of setting the local duty cycle rate.
-   *
-   * @param sleepIntervalMs the length of this node's Rx check interval, in [ms]
-   */
-  command void setLocalSleepInterval(uint16_t sleepIntervalMs);
-  
-  /**
-   * @return the local node's sleep interval, in [ms]
-   */
-  command uint16_t getLocalSleepInterval();
-  
-  /**
-   * Set this node's radio duty cycle rate, in units of [percentage*100].
-   * For example, to get a 0.05% duty cycle,
-   *   call LowPowerListening.setDutyCycle(5);
-   *
-   * For a 100% duty cycle (always on),
-   *   call LowPowerListening.setDutyCycle(10000);
-   *
-   * This is the equivalent of setting the local sleep interval explicitly.
-   * 
-   * @param dutyCycle The duty cycle percentage, in units of [percentage*100]
-   */
-  command void setLocalDutyCycle(uint16_t dutyCycle);
-  
-  /**
-   * @return this node's radio duty cycle rate, in units of [percentage*100]
-   */
-  command uint16_t getLocalDutyCycle();
-  
-  /**
-   * Configure this outgoing message so it can be transmitted to a neighbor mote
-   * with the specified Rx sleep interval.
-   * @param msg Pointer to the message that will be sent
-   * @param sleepInterval The receiving node's sleep interval, in [ms]
-   */
-  command void setRxSleepInterval(message_t *msg, uint16_t sleepIntervalMs);
-  
-  /**
-   * @return the destination node's sleep interval configured in this message
-   */
-  command uint16_t getRxSleepInterval(message_t *msg);
-  
-  /**
-   * Configure this outgoing message so it can be transmitted to a neighbor mote
-   * with the specified Rx duty cycle rate.
-   * Duty cycle is in units of [percentage*100], i.e. 0.25% duty cycle = 25.
-   * 
-   * @param msg Pointer to the message that will be sent
-   * @param dutyCycle The duty cycle of the receiving mote, in units of 
-   *     [percentage*100]
-   */
-  command void setRxDutyCycle(message_t *msg, uint16_t dutyCycle);
-  
-  /**
-   * @return the destination node's duty cycle configured in this message
-   *     in units of [percentage*100]
-   */
-  command uint16_t getRxDutyCycle(message_t *msg);
-  
-  /**
-   * Convert a duty cycle, in units of [percentage*100], to
-   * the sleep interval of the mote in milliseconds
-   * @param dutyCycle The duty cycle in units of [percentage*100]
-   * @return The equivalent sleep interval, in units of [ms]
-   */
-  command uint16_t dutyCycleToSleepInterval(uint16_t dutyCycle);
-  
-  /**
-   * Convert a sleep interval, in units of [ms], to a duty cycle
-   * in units of [percentage*100]
-   * @param sleepInterval The sleep interval in units of [ms]
-   * @return The duty cycle in units of [percentage*100]
-   */
-  command uint16_t sleepIntervalToDutyCycle(uint16_t sleepInterval);
-  
-}</pre>
-<p>
-This interface is located in <code>tos/interfaces</code> in the standard TinyOS tree.  Take a
-look at the comments for each command to familiarize yourself with how this interface can be used.
-</p>
-<p>
-Using this interface typically involves first setting a nodes local duty cycle within the 
-<code>Boot.booted()</code> event of the top level application.  For each packet the application 
-wishes to send, the duty cycle of its destination is then specified as metadata so that the 
-correct number of preambles can be prepended to it.  The code snippet found below demonstrates 
-this usage pattern:
-</p>
-<pre>
-event void Boot.booted() {
-  call LPL.setLocalSleepInterval(LPL_INTERVAL);
-  call AMControl.start();
-}
-
-event void AMControl.startDone(error_t e) {
-  if(e != SUCCESS)
-    call AMControl.start();
-}
-  
-...
-
-void sendMsg() {
-  call LPL.setRxSleepInterval(&msg, LPL_INTERVAL);
-  if(call Send.send(dest_addr, &msg, sizeof(my_msg_t)) != SUCCESS)
-    post retrySendTask();
-}</pre>
-
-The <code>AMControl</code> interface is provided by <code>ActiveMessageC</code>, and is 
-used, among other things, to enable the operation of low-power listening for the radio.  
-Once <code>AMControl.start()</code> has completed successfully, the radio begins to duty cycle
-itself as specified by the parameter to the <code>setLocalSleepInterval()</code> command.  Calling 
-<code>setRxSleepInterval()</code> with a specific sleep interval then allows the correct number of preambles to be sent
-for the message specified in its parameter list.
-
-<h1>
-Microcontroller Power Management
-</h1>
-<p>
-Microcontrollers often have several power states, with varying power draws, 
-wakeup latencies, and peripheral support. The microcontroller should always be 
-in the lowest possible power state that can satisfy application requirements. 
-Determining this state accurately requires knowing a great deal about the power 
-state of many subsystems and their peripherals. Additionally, state transitions 
-are common. Every time a microcontroller handles an interrupt, it moves from a low 
-power state to an active state, and whenever the TinyOS scheduler finds the task 
-queue empty it returns the microcontroller to a low power state. TinyOS uses 
-three mechanisms to decide what low power state it puts a microcontroller into: 
-status and control registers, a dirty bit, and a power state override.  
-Please refer to <a href=../tep112.html>TEP 112</a> for more information.
-</p>
-</p>
-As a developer, you will not have to worry about MCU power managment at all in 
-most situations.  TinyOS handles everything for you automatically.  At times,
-however, you may want to use the provided power state override functionality.
-Take a look at <code>tos/chips/atm128/timer/HplAtm128Timer0AsyncP.nc</code> if
-you are interested in seeing an example of where this override functionality is used.  
-</p>
-
-<h1>
-Low Power Sensing Application
-</h1>
-<p>
-A fully functional low-power sensing application has been created that combines each 
-of the techniques found in this tutorial.  At present, this application is not included 
-in the official TinyOS distribution (<= 2.0.2).  If you are using TinyOS from a cvs 
-checkout, you will find it located under <code>apps/tutorials/LowPowerSensing</code>.  
-Otherwise, you can obtain it from
-cvs by running the following set of commands from a terminal window:
-</p>
-
-    <pre>
-cd $TOSROOT/apps/tutorials
-cvs -d:pserver:anonymous@tinyos.cvs.sourceforge.net:/cvsroot/tinyos login
-cvs -z3 -d:pserver:anonymous@tinyos.cvs.sourceforge.net:/cvsroot/tinyos co -P -d LowPowerSensing tinyos-2.x/apps/tutorials/LowPowerSensing</pre>
-    <p>
-    Just hit enter when prompted for a CVS password.  You do not need to enter one.
-    </p>
-
-This
-application has been tested on telosb and mica2 platforms, but should be usable
-on others without modification.  Take a look at the README file found in the top level directory
-for more information.
-</p>
-<a name=#related_docs>
-<h1>Related Documentation</h1>
-</a>
-<ul>
-<li> <a href="../tep103.html">TEP 103: Permanent Data Storage (Flash)</a>
-<li> <a href="../tep105.html">TEP 105: Low Power Listening</a>
-<li> <a href="../tep108.html">TEP 108: Resource Arbitration</a>
-<li> <a href="../tep109.html">TEP 109: Sensors and Sensor Boards</a>
-<li> <a href="../tep112.html">TEP 112: Microcontroller Power Management</a>
-<li> <a href="../tep114.html">TEP 114: SIDs: Source and Sink Independent Drivers</a>
-<li> <a href="../tep115.html">TEP 115: Power Management of Non-Virtualised Devices</a>
-<li> <a href="http://sing.stanford.edu/klueska/Black_Site/Publications_files/klues07icem.pdf">
-Integrating Concurrency Control and Energy Management in Device Drivers</a>
-</ul>
-
-<!-- Begin footer -->
-<br>
-<hr>
-<center>
-<p>&lt;&nbsp;<b><a href="lesson15.html">Previous Lesson</a></b> |&nbsp; <b><a
- href="index.html">Top</a></b> &nbsp;|&nbsp;
-</center>
-
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" ^M   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<title>klueska.com</title>
+</head>
+<frameset>
+<frame src="http://docs.tinyos.net/index.php/Writing_Low-Power_Applications" name="redir_frame" />
+<noframes>
+<body>
+<p>Sorry, your browser does not support frames. Please <a href="http://docs.tinyos.net/index.php/Writing_Low-Power_Applications" target="_top">go here</a>.</p>
 </body>
-</html>
+</noframes>
+</frameset>
+</html>
\ No newline at end of file
index d47351cc984c25193a943211ef4f99368d200dea..30f18ac3c53fb6f85b9f35078e9b578daf11f31e 100644 (file)
-<html>
-    <head>
-      <title>TinyOS Tutorial Lesson 2: Modules and the TinyOS Execution Model</title>
-      <link href="../../stylesheets/tutorial.css" rel="stylesheet" type="text/css">
-  </head>
-  <body>
-    
-    <div class="title">Lesson 2: Modules and the TinyOS Execution Model</div>
-    <div class="subtitle">Last updated June 27 2006</div>
-    
-    <p>This lesson introduces nesC modules, commands, events, and
-      tasks. It explains the TinyOS execution model.</p>
-    
-    <h1>Modules and State</h1>
-    
-    <p>Compiling TinyOS applications produces a single binary image that assumes
-      it has complete control of the hardware. Therefore, a mote only
-      runs one TinyOS image at a time. An image consists of the
-      components needed for a single application. As most more platforms
-      do not have hardware-based memory protection, there is
-      no seperation between a "user" address space and a "system"
-      address space; there is only one address space that all
-      components share. This is why many TinyOS components try to keep
-      their state private and avoid passing pointers: since there is
-      no hardware protection, the best way to keep memory uncorrupted
-      is to share it as little as possible.</p>
-    
-    <p>Recall from lesson 1 that the set of interfaces a component uses
-      and provides
-      define its signature. Both kinds of components -- configurations and
-      modules -- provide and use interfaces. The difference between the
-      two lies in their implementation: configurations are implemented
-      in terms of other components, which they wire, while modules
-      are executable code. After unwrapping all of the layers of abstraction
-      that configurations introduce, modules always lie within. Module
-      implementations are for the most part written in C, with
-      some extra constructions for nesC abstractions.</p>
-
-    <p>Modules can declare state variables. Any state a component declares
-      is private: no
-      other component can name it or directly access it. The only
-      way two components can directly interact is through interfaces.
-      Let's revisit the Blink application.
-      Here is the Blink module BlinkC's implementation in
-      its entirety:</p>
-
-<pre></pre>
-<prehead>apps/Blink/BlinkC.nc:</prehead>
-<pre>
-module BlinkC {
-  uses interface Timer&lt;TMilli&gt; as Timer0;
-  uses interface Timer&lt;TMilli&gt; as Timer1;
-  uses interface Timer&lt;TMilli&gt; as Timer2;
-  uses interface Leds;
-  uses interface Boot;
-}
-implementation
-{
-  event void Boot.booted()
-  {
-    call Timer0.startPeriodic( 250 );
-    call Timer1.startPeriodic( 500 );
-    call Timer2.startPeriodic( 1000 );
-  }
-
-  event void Timer0.fired()
-  {
-    call Leds.led0Toggle();
-  }
-  
-  event void Timer1.fired()
-  {
-    call Leds.led1Toggle();
-  }
-  
-  event void Timer2.fired()
-  {
-    call Leds.led2Toggle();
-  }
-}
-</pre>
-
-    <p>BlinkC does not allocate any state. Let's change it so that its
-      logic is a little different: rather than blink the LEDs from three
-      different timers, we'll blink them with a single timer and keep
-      some state to know which ones to toggle. Make a copy of the Blink
-      application, <tt>BlinkSingle</tt>, and go into its directory.</p>
-
-    <pre>
-$ cd tinyos-2.x/apps
-$ cp -R Blink BlinkSingle
-$ cd BlinkSingle
-    </pre>
-
-    <p>Open the BlinkC module in an editor.
-      The first step is to comment out the LED toggles in Timer1 and
-      Timer2:</p>
-
-    <pre>
-  event void Timer1.fired()
-  {
-    // call Leds.led1Toggle();
-  }
-  
-  event void Timer2.fired()
-  {
-    // call Leds.led2Toggle();
-  }
-    </pre>
-
-    <p>The next step is to add some state to BlinkC, a single byte. Just
-      like in C, variables and functions must be declared before they are
-      used, so put it at the beginning of the implementation:</p>
-
-    <pre>
-implementation
-{
-
-  uint8_t counter = 0;
-
-  event void Boot.booted()
-  {
-    call Timer0.startPeriodic( 250 );
-    call Timer1.startPeriodic( 500 );
-    call Timer2.startPeriodic( 1000 );
-  }
-    </pre>
-
-    <p>Rather than the standard C names of <tt>int</tt>, <tt>long</tt>,
-      or <tt>char</tt>, TinyOS code uses more explicit types, which
-      declare their size. In reality, these map to the basic C types, but
-      do so differently for different platforms. TinyOS code avoids using
-      <tt>int</tt>, for example, because it is platform-specific. For example,
-      on mica and Telos motes, <tt>int</tt> is 16 bits, while on the
-      IntelMote2, it is 32 bits. Additionally, TinyOS code often
-      uses unsigned values heavily, as wrap-arounds to negative numbers
-      can often lead to very unintended consequences. The commonly used
-      types are:</p>
-
-    <CENTER>
-      <table border=1 cellpadding=6>
-       <tr>
-         <td></td><td>8 bits</td><td>16 bits</td><td>32 bits</td><td>64 bits</td>
-       </tr>
-       <tr>
-         <td>signed</td><td><tt>int8_t</tt></td><td><tt>int16_t</tt></td><td><tt>int32_t</tt></td><td><tt>int64_t</tt></td>
-       </tr>
-       <tr>
-         <td>unsigned</td><td><tt>uint8_t</td><td><tt>uint16_t</td><td><tt>uint32_t</td><td><tt>uint64_t</tt></td>
-       </tr>
-      </table>
-    </CENTER>
-      <p>There is also a <tt>bool</tt> type. You can use the standard C
-       types, but doing so might raise cross-platform issues. Also,
-       <tt>uint32_t</tt> is often easier to write than <tt>unsigned
-         long</tt>. Most platforms support floating point numbers
-      (<tt>float</tt> almost always, <tt>double</tt> sometimes),
-       although their arithmetic is in software rather than hardware.</p>
-
-      <p>Returning to our modified BlinkC, we've allocated a single unsigned
-       byte, <tt>counter</tt>. When the mote boots, the <tt>counter</tt>
-       will be initialized to zero. The next step is to make it that
-       when Timer0 fires, it increments <tt>counter</tt> and displays the
-       result:</p>
-
-      <pre>
-  event void Timer0.fired()
-  {
-    counter++;
-    if (counter & 0x1) {
-      call Leds.led0On();
-    }
-    else {
-      call Leds.led0Off();
-    }
-    if (counter & 0x2) {
-      call Leds.led2On();
-    }
-    else {
-      call Leds.led2Off();
-    }
-    if (counter & 0x4) {
-      call Leds.led2On();
-    }
-    else {
-      call Leds.led2Off();
-    }
-  }
-      </pre>
-
-      <p>Another, more succinct way to do it is to use the <tt>set</tt>
-       command:</p>
-
-      <pre>
-  event void Timer0.fired()
-  {
-    counter++;
-    call Leds.set(counter);
-  }
-      </pre>
-
-      <p>Compile your program and install it on a mote. You'll see
-       that it behaves just as before, except that now the LEDs
-       are being driven by a single, rather than three, timers.</p>
-
-      <p>As only one timer is being used, this means that you don't need
-       Timer1 and Timer2: they waste CPU resources and memory. Open
-       BlinkC again and remove them from its signature and implementation.
-       You should have something that looks like this:</p>
-
-      <pre>
-module BlinkC {
-  uses interface Timer&lt;TMilli&gt; as Timer0;
-  uses interface Leds;
-  users interface Boot;
-}
-implementation
-{
-  uint8_t counter = 0;
-
-  event void Boot.booted()
-  {
-    call Timer0.startPeriodic( 250 );
-  }
-
-  event void Timer0.fired()
-  {
-    counter++;
-    call Leds.set(counter);
-  }
-  
-}
-      </pre>
-       
-      <p>Try to compile the application: nesC will throw an error, because
-       the configuration BlinkAppC is wiring to interfaces on BlinkC
-       that no longer exist (Timer1 and Timer2):</p>
-
-      <pre>
-dark /root/src/tinyos-2.x/apps/BlinkSingle -5-> make micaz
-mkdir -p build/micaz
-    compiling BlinkAppC to a micaz binary
-ncc -o build/micaz/main.exe -Os -finline-limit=100000 -Wall -Wshadow -DDEF_TOS_AM_GROUP=0x7d -Wnesc-all -target=micaz -fnesc-cfile=build/micaz/app.c -board=micasb  -fnesc-dump=wiring -fnesc-dump='interfaces(!abstract())' -fnesc-dump='referenced(interfacedefs, components)' -fnesc-dumpfile=build/micaz/wiring-check.xml BlinkAppC.nc -lm 
-In component `BlinkAppC':
-BlinkAppC.nc:54: cannot find `Timer1'
-BlinkAppC.nc:55: cannot find `Timer2'
-make: *** [exe0] Error 1
-      </pre>
-
-      <p>Open BlinkAppC and remove the two Timers and their wirings. Compile
-       the application:</p>
-
-      <pre>
-mkdir -p build/micaz
-    compiling BlinkAppC to a micaz binary
-ncc -o build/micaz/main.exe -Os -finline-limit=100000 -Wall -Wshadow -DDEF_TOS_AM_GROUP=0x7d -Wnesc-all -target=micaz -fnesc-cfile=build/micaz/app.c -board=micasb  -fnesc-dump=wiring -fnesc-dump='interfaces(!abstract())' -fnesc-dump='referenced(interfacedefs, components)' -fnesc-dumpfile=build/micaz/wiring-check.xml BlinkAppC.nc -lm 
-    compiled BlinkAppC to build/micaz/main.exe
-            2428 bytes in ROM
-              39 bytes in RAM
-avr-objcopy --output-target=srec build/micaz/main.exe build/micaz/main.srec
-avr-objcopy --output-target=ihex build/micaz/main.exe build/micaz/main.ihex
-    writing TOS image
-      </pre>
-
-      <p>If you compare the ROM and RAM sizes with the unmodified Blink
-       application, you should see that they are a bit smaller: TinyOS
-       is only allocating state for a single timer, and there is
-       event code for only one timer.</p>
-
-      <h1>Interfaces, Commands, and Events</h1>
-      
-      <p>Go back to <tt>tinyos-2.x/apps/Blink</tt>.
-      In lesson 1 we learned that if a component uses an interface, it can
-       call the interface's commands and must implement handlers for its
-       events.  We also saw that the BlinkC component uses the Timer, Leds,
-       and Boot interfaces. 
-       Let's take a look at those interfaces:</p>
-
-<pre></pre>
-<prehead>tos/interfaces/Boot.nc:</prehead>
-<pre>
-interface Boot {
-  event void booted();
-}
-</pre>
-
-<prehead>tos/interfaces/Leds.nc:</prehead>
-<pre>
-interface Leds {
-
-  /**
-   * Turn LED n on, off, or toggle its present state.
-   */
-  async command void led0On();
-  async command void led0Off();
-  async command void led0Toggle();
-
-  async command void led1On();
-  async command void led1Off();
-  async command void led1Toggle();
-
-  async command void led2On();
-  async command void led2Off();
-  async command void led2Toggle();
-
-  /**
-   * Get/Set the current LED settings as a bitmask. Each bit corresponds to
-   * whether an LED is on; bit 0 is LED 0, bit 1 is LED 1, etc. 
-   */
-  async command uint8_t get();
-  async command void set(uint8_t val);
-  
-}
-</pre>
-
-<prehead>tos/interfaces/Timer.nc:</prehead>
-<pre>
-interface Timer<precision_tag>
-{
-  // basic interface
-  command void startPeriodic( uint32_t dt );
-  command void startOneShot( uint32_t dt );
-  command void stop();
-  event void fired();
-
-  // extended interface omitted (all commands)
-}
-</pre>
-
-    <p>Looking over the interfaces for <code>Boot</code>,
-      <code>Leds</code>, and
-      <code>Timer</code>, we can see that since <code>BlinkC</code> uses
-      those interfaces it must implement handlers for the
-      <code>Boot.booted()</code> event, and the <code>Timer.fired()</code>
-      event. The <code>Leds</code> interface signature does not include any
-      events, so <code>BlinkC</code> need not implement any in order
-      to call the Leds commands. Here, again, is <code>BlinkC</code>'s
-      implementation of <code>Boot.booted()</code>:</p>
-    
-<pre></pre>
-<prehead>apps/Blink/BlinkC.nc:</prehead>
-<pre>
-  event void Boot.booted()
-  {
-    call Timer0.startPeriodic( 250 );
-    call Timer1.startPeriodic( 500 );
-    call Timer2.startPeriodic( 1000 );
-  }
-</pre>
-
-    <p><code>BlinkC</code> uses 3 instances of the TimerMilliC component,
-      wired to the interfaces <code>Timer0</code>, <code>Timer1</code>, and
-      <code>Timer2</code>. The <code>Boot.booted()</code> event handler
-      starts each instance. The parameter to
-      <code>startPeriodic()</code> specifies the period in milliseconds after 
-      which the timer will fire (it's millseconds because of the
-      <tt>&lt;TMilli&gt;</tt> in the interface).
-      Because the timer is started using
-      the <code>startPeriodic()</code> 
-      command, the timer will be reset after firing such that the
-      <code>fired()</code> event is 
-      triggered every n milliseconds.</p>
-
-    <p>Invoking an interface command requires the <tt>call</tt> keyword,
-      and invoking an interface event requires the <tt>signal</tt> keyword.
-      BlinkC does not provide any interfaces, so its code
-      does not have any signal statements: in a later lesson,
-      we'll look at the boot sequence, which signals the Boot.booted()
-      event.</p>
-    
-    <p>Next, look at the implementation of the <code>Timer.fired()</code>:</p>
-
-<pre></pre>
-<prehead>apps/Blink/BlinkC.nc:</prehead>
-<pre>
-  event void Timer0.fired()
-  {
-    call Leds.led0Toggle();
-  }
-  
-  event void Timer1.fired()
-  {
-    call Leds.led1Toggle();
-  }
-  
-  event void Timer2.fired()
-  {
-    call Leds.led2Toggle();
-  }
-}
-</pre>
-       
-    <p>Because it uses three instances of the Timer interface,
-      <code>BlinkC</code> 
-      must implement three instances of <code>Timer.fired()</code>
-      event. When implementing or invoking an interface function, the
-      function name is always <i>interface</i>.<i>function</i>. As
-      BlinkC's three Timer instances are named <tt>Timer0</tt>,
-      <tt>Timer1</tt>, and <tt>Timer2</tt>, it implements the three
-      functions <tt>Timer0.fired</tt>, <tt>Timer1.fired</tt>, and
-      <tt>Timer2.fired</tt>.</p>
-    
-    
-    
-    <h1>TinyOS Execution Model: Tasks</h1>
-    
-    <p>All of the code we've looked at so far is <i>synchronous</i>.
-      It runs in a single execution context and does not have
-      any kind of pre-emption. That is, when synchronous (sync) code
-      starts running, it does not relinquish the CPU to other
-      sync code until it completes. This simple mechanism allows
-      the TinyOS scheduler to minimize its RAM consumption and
-      keeps sync code very simple. However, it means that if one
-      piece of sync code runs for a long time, it prevents other
-      sync code from running, which can adversely affect system
-      responsiveness. For example, a long-running piece of code
-      can increase the time it takes for a mote to respond to a
-      packet.</p>
-    
-    <p>So far, all of the examples we've looked at have been
-      direct function calls. System components, such as the
-         boot sequence or timers, signal events to a component,
-         which takes some action (perhaps calling a command) and
-         returns. In most cases, this programming approach works
-         well. Because sync code is non-preemptive, however,
-         this approach does not work well for large computations.
-         A component needs to be able to split a large computation
-         into smaller parts, which can be executed one at a time.
-         Also, there are times when a component needs to do something,
-         but it's fine to do it a little later. Giving TinyOS the
-         ability to defer the computation until later can let it
-         deal with everything else that's waiting first.</p>
-
-       <p><b>Tasks</b> enable components to perform general-purpose
-         "background" processing in an application. A task is a function
-         which a component tells TinyOS to run later, rather than now.
-         The closest analogies in traditonal operating systems are
-         <A HREF="http://www.tldp.org/LDP/tlk/kernel/kernel.html">interrupt
-           bottom halves</A> and <A HREF="http://opensource.adobe.com/twiki/bin/view/AdobeSource/DeferredProcSystem">deferred
-           procedure calls</A>.</p>
-
-       <p>Make a copy of the Blink application, and call it BlinkTask:</p>
-
-       <pre>
-$ cd tinyos-2.x/apps
-$ cp -R Blink BlinkTask
-$ cd BlinkTask
-       </pre>
-
-       <p>Open <code>BlinkC.nc</code>. Currently, the event handler
-         for <code>Timer0.fired()</code> is:</p>
-
-       <pre>
-event void Timer0.fired() {
-  dbg("BlinkC", "Timer 0 fired @ %s\n", sim_time_string());
-  call Leds.led0Toggle();
-}
-       </pre>
-
-       <p>Let's change it so that it does a bit of work, enough that
-         we'll be able to see how long it runs. In terms of a mote,
-         the rate at which we can see things (about 24 Hz, or 40 ms)
-         is <u>slow</u>: the micaZ and Telos can send about 20 packets
-         in that time. So this example is really exaggerated, but it's
-         also simple enough that you can observe it with the naked eye.
-         Change the handler to be this:</p>
-
-       <pre>
-event void Timer0.fired() {
-  uint32_t i;
-  dbg("BlinkC", "Timer 0 fired @ %s\n", sim_time_string());
-  for (i = 0; i < 400001; i++) {
-    call Leds.led0Toggle();
-  }
-}
-       </pre>
-        
-    <p>This will cause the timer to toggle 400,001 times, rather
-      than once. Because the number is odd, it will have the end
-      result of a single toggle, with a bit of flickering in-between.
-      Compile and install the program. You'll see that
-      Led 0 introduces so much latency in the Led 1 and Led 2
-      toggles that you never see a situation where only one is on.
-      On TelosB motes, this long running task can cause the Timer stack
-      to completely skip events (try setting the count to 200,001 or 100,001).
-    </p>
-
-    <p>The problem is that this computation is interfering with the timer's
-      operation. What we'd like to do is tell TinyOS to execute the computation
-      later. We can accomplish this with a <b>task</b>.</p>
-
-    <p>A task is declared in your implementation module using the syntax
-    <pre>&nbsp; task void taskname() { ... }</pre> where
-    <tt>taskname()</tt> is whatever symbolic name you want to assign to the
-    task. Tasks must return <tt>void</tt> and may not take any
-    arguments. To dispatch a task for (later) execution, use the syntax
-    <pre>&nbsp; post taskname();</pre> A component can post a task in a
-    command, an event, or a task.  Because they are the root of a call
-    graph, a tasks can safely both call commands and signal events. We will
-    see later that, by convention, commands do not signal events to avoid
-    creating recursive loops across component boundaries (e.g., if command
-    X in component 1 signals event Y in component 2, which itself calls
-    command X in component 1). These loops would be hard for the programmer to
-    detect (as they depend on how the application is wired) and would lead to
-    large stack usage.</p>
-
-
-    <p>Modify BlinkC to perform the loop in a task:</p>
-
-    <pre>
-task void computeTask() {
-  uint32_t i;
-  for (i = 0; i < 400001; i++) {}
-}
-
-event void Timer0.fired() {
-  call Leds.led0Toggle();
-  post computeTask();
-}
-    </pre>
-
-    <p>Telos platforms will still struggle, but mica platforms will
-      operate OK.</p>
-
-    
-    <p>The <tt>post</tt> operation places the task on an internal
-      <b>task queue</b> which is processed in FIFO order. When a
-      task is executed, it runs to completion
-      before the next task is run. Therefore, and as the above examples
-      showed, a task should not run for long periods of time.
-      Tasks do not preempt each
-      other, but a task can  be preempted by a hardware interrupts (which
-      we haven't seen yet).
-      If you need to run a series of long operations,
-      you should dispatch a separate task for each operation, rather
-      than using one big task. The <tt>post</tt> operation returns
-      an <tt>error_t</tt>, whose value is either <tt>SUCCESS</tt>
-      or <tt>FAIL</tt>. A post fails if and only if the task is
-      already pending to run (it has been posted successfully and has not been invoked yet).(<A HREF="#task_footnote">1</A>)</p>
-
-    <p>For example, try this:</p>
-
-    <pre>
-uint32_t i;
-
-task void computeTask() {
-  uint32_t start = i;
-  for (;i < start + 10000 && i < 400001; i++) {}
-  if (i >= 400000) {
-    i = 0;
-  }
-  else {
-    post computeTask();
-  }
-}
-    </pre>
-
-    <p>This code breaks the compute task up into many smaller tasks.
-      Each invocation of computeTask runs through 10,000 iterations of
-      the  loop. If it hasn't completed all 400,001 iterations, it reposts
-      itself. Compile this code and run it; it will run fine on both
-      Telos and mica-family motes.</p>
-
-    <p>Note that using a task in this way required including another
-      variable (<tt>i</tt>) in the component. Because computeTask()
-      returns after 10,000 iterations, it needs somewhere to store
-      its state for the next invocation. In this situation, <tt>i</tt>
-      is acting as a static function variable often does in C. However,
-      as nesC component state is completely private, using the
-      <tt>static</tt> keyword to limit naming scope is not as useful.
-      This code, for example, is equivalent:</p>
-    <pre>
-task void computeTask() {
-  static uint32_t i;
-  uint32_t start = i;
-  for (;i < start + 10000 && i < 400001; i++) {}
-  if (i >= 400000) {
-    i = 0;
-  }
-  else {
-    post computeTask();
-  }
-}
-    </pre>
-
-    <h1>Internal Functions</h1>
-
-    <p>Commands and events are the only way that a function in a component
-      can be made callable by another component. There are situations
-      when a component wants private functions for its own internal
-      use. A component can define standard C functions, which other
-      components cannot name and therefore cannot invoke directly. 
-      While these functions do not have the <tt>command</tt> or <tt>event</tt>
-      modifier, they can freely call commands or signal events. For example,
-      this is perfectly reasonable nesC code:</p>
-
-    <pre>
-module BlinkC {
-  uses interface Timer&lt;TMilli&gt; as Timer0;
-  uses interface Timer&lt;TMilli&gt; as Timer1;
-  uses interface Timer&lt;TMilli&gt; as Timer2;
-  uses interface Leds;
-  uses interface Boot;
-}
-implementation
-{
-
-  void startTimers() {
-    call Timer0.startPeriodic( 250 );
-    call Timer1.startPeriodic( 500 );
-    call Timer2.startPeriodic( 1000 );
-  }
-
-  event void Boot.booted()
-  {
-    startTimers();
-  }
-
-  event void Timer0.fired()
-  {
-    call Leds.led0Toggle();
-  }
-  
-  event void Timer1.fired()
-  {
-    call Leds.led1Toggle();
-  }
-  
-  event void Timer2.fired()
-  {
-    call Leds.led2Toggle();
-  }
-}
-    </pre>
-    
-    <p>Internal functions act just like C functions: they don't need the <tt>
-       call</tt> or <tt>signal</tt> keywords.</p>
-
-    <h1>Split-Phase Operations</h1>
-
-    <p>Because nesC interfaces are wired at compile time,
-      callbacks (events) in TinyOS are very efficient. In most
-      C-like languages, callbacks have to be registered at run-time
-      with a function pointer. This can prevent the compiler from
-      being able to optimize code across callback call paths. Since
-      they are wired statically in nesC, the compiler knows exactly
-      what functions are called where and can optimize heavily.</p>
-
-    <p>The ability to optimize across component boundaries is
-      very important in TinyOS, because it has no blocking operations.
-      Instead, every long-running operation is <b>split-phase</b>.
-      In a blocking system, when a program calls a long-running operation,
-      the call does not return until the operation is complete: the program
-      blocks. In a split-phase system, when a program calls a long-running
-      operation, the call returns immediately, and the called abstraction
-      issues a callback when it completes. This approach is called
-      split-phase because it splits invocation and completion into two
-      separate phases of execution. Here is a simple example of the
-      difference between the two:</p>
-
-<center>
-    <table>
-      <tr><td align=center>Blocking</td> <td align=center>Split-Phase</td></tr>
-      <tr>
-        <td valign=top>
-<pre>
-if (send() == SUCCESS) {
-  sendCount++;
-}
-</pre>
-</td>
-        <td valign=top>
-<pre>
-// start phase
-send(); 
-
-//completion phase
-void sendDone(error_t err) {
-  if (err == SUCCESS) {
-    sendCount++;
-  }
-}
-</pre>
-</td>
-      </tr>
-    </table>
-</center>
-
-    <p>Split-phase code is often a bit more verbose and complex than
-     sequential code. But it has several advantages. First, split-phase
-     calls do not tie up stack memory while they are executing. Second,
-     they keep the system reponsive: there is never a situation when
-     an application needs to take an action but all of its threads are
-     tied up in blocking calls. Third, it tends to reduce stack
-     utilization, as creating large variables on the stack is rarely
-     necessary.</p>
-
-    <p>Split-phase interfaces enable a TinyOS component to easily start
-      several operations at once and have them execute in parallel.
-      Also, split-phase operations can save memory. This is because
-      when a program calls a blocking operation, all of the state it
-      has stored on the call stack (e.g., variables declared in functions)
-      have to be saved. As determining the exact size of the stack is
-      difficult, operating systems often choose a very conservative
-      and therefore large size.  Of course, if there is data that 
-      has to be kept across the 
-      call, split-phase operations still need to save it.</p>
-
-    <p>The command <tt>Timer.startOneShot</tt> is an example of
-     a split-phase call. The user of the Timer inteface calls the command,
-     which returns immediately. Some time later (specified by the
-     argument), the component providing Timer signals <tt>Timer.fired</tt>.
-     In a system with blocking calls, a program might use <tt>sleep()</tt>:
-
-     <center>
-       <table>
-         <tr>
-           <td align=center>Blocking</td><td align=center>Split-phase</td>
-         </tr>
-         <tr>
-           <td valign=top>
-             <pre>
-state = WAITING;
-op1();
-sleep(500);
-op2();
-state = RUNNING
-             </pre>
-           </td>
-           <td valign=top>
-             <pre>
-state = WAITING;
-op1();
-call Timer.startOneShot(500);
-
-event void Timer.fired() {
-  op2();
-  state = RUNNING;
-}
-             </pre>
-           </td>
-         </tr>
-       </table>
-     </center> 
-
-<p>In the next lesson, we'll look at one of the most basic
-split-phase operations: sending packets.</p>
-
-<a name=#related_docs>
-<h1>Related Documentation</h1>
-</a>
-<ul>
-<li> <a href="../tep102.html">TEP 102: Timers</a>
-<li> <a href="../tep106.html">TEP 106: Schedulers and Tasks</a>
-</ul>
-
-<p>
-<hr>
-
-<p><a name="task_footnote">(1)</a> The task semantics have changed
-significantly from tinyos-2.x. In 1.x, a task could be posted more
-than once and a post could fail if the task queue were full. In 2.x, a
-basic post will only fail if that task has already been posted and has
-not started execution. So a task can always run, but can only have one
-outstanding post at any time. If a component needs to post task
-several times, then the end of the task logic can repost itself as
-need be.
-
-
-<!-- Begin footer -->
-<br>
-<hr>
-<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>
-</center>
-
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" ^M   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<title>klueska.com</title>
+</head>
+<frameset>
+<frame src="http://docs.tinyos.net/index.php/Modules_and_the_TinyOS_Execution_Model" name="redir_frame" />
+<noframes>
+<body>
+<p>Sorry, your browser does not support frames. Please <a href="http://docs.tinyos.net/index.php/Modules_and_the_TinyOS_Execution_Model" target="_top">go here</a>.</p>
 </body>
-</html>
+</noframes>
+</frameset>
+</html>
\ No newline at end of file
index c0d5a35da9d392e3da6b21415178dd79e2ce82e6..d82c974c914bb6ad16453a667287688fc6b15e1f 100644 (file)
-<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
-<html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" ^M   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
-  <title>Lesson 3: Mote-mote radio communication</title>
-  <link href="../../stylesheets/tutorial.css" rel="stylesheet" type="text/css">
+<title>klueska.com</title>
 </head>
+<frameset>
+<frame src="http://docs.tinyos.net/index.php/Mote-mote_radio_communication" name="redir_frame" />
+<noframes>
 <body>
-
-<div class="title">Lesson 3: Mote-mote radio communication</div>
-<div class="subtitle">Last Modified: June 27 2006</div>
-
-<p>This lesson introduces radio communications in TinyOS.  You will
-become familar with TinyOS interfaces and components that support
-communications and you will learn how to:
-
-<p>
-
-<ul>
-
-<li>Use <code>message_t</code>, the TinyOS 2.0 message buffer.
-
-<li>Send a message buffer to the radio.
-
-<li>Receive a message buffer from the radio.
-<!-- TODO add...
-<li>Access metadata in a message buffer.
--->
-</ul>
-
-
-<h1>Introduction</h1>
-
-TinyOS provides a number of <i>interfaces</i> to abstract the
-underlying communications services and a number of <i>components</i>
-that <i>provide</i> (implement) these interfaces.  All of these
-interfaces and components use a common message buffer abstraction,
-called <code>message_t</code>, which is implemented as a nesC struct
-(similar to a C struct).  The <code>message_t</code> abstraction replaces
-the TinyOS 1.x <code>TOS_Msg</code> abstraction.  Unlike TinyOS 1.x, the
-members of <code>message_t</code> are opaque, and therefore not accessed
-directly.  Rather, <code>message_t</code> is an
-<i>abstract data type</i>, whose members are read and written using
-accessor and mutator functions<a href="#fn1">(1)</a>.
-
-<h2>Basic Communications Interfaces</h2>
-
-<p>There are a number of interfaces and components that use
-<code>message_t</code> as the underlying data structure.  Let's take a
-look at some of the interfaces that are in the <code>tos/interfaces</code>
-directory to familiarize ourselves with the general functionality of
-the communications system:
-
-<p>
-<ul>
-
-<li><code><a href="../../../tos/interfaces/Packet.nc">Packet</a></code> -
-Provides the basic accessors for the <code>message_t</code> abstract data
-type.  This interface provides commands for clearing a message's
-contents, getting its payload length, and getting a pointer to its
-payload area.
-
-<li><code><a href="../../../tos/interfaces/Send.nc">Send</a></code> -
-Provides the basic <i>address-free</i> message sending interface.
-This interface provides commands for sending a message and canceling a
-pending message send.  The interface provides an event to indicate
-whether a message was sent successfully or not.  It also provides
-convenience functions for getting the message's maximum payload as
-well as a pointer to a message's payload area.
-
-<li><code><a href="../../../tos/interfaces/Receive.nc">Receive</a></code>
-- Provides the basic message reception interface.  This interface
-provides an event for receiving messages.  It also provides, for
-convenience, commands for getting a message's payload length and
-getting a pointer to a message's payload area.
-
-<li><code><a
-href="../../../tos/interfaces/PacketAcknowledgements.nc">PacketAcknowledgements</a></code>
-- Provides a mechanism for requesting acknowledgements on a per-packet
-basis.
-
-<li><code><a
-href="../../../tos/interfaces/RadioTimeStamping.nc">RadioTimeStamping</a></code>
-- Provides time stamping information for radio transmission and
-reception.
-
-</ul>
-
-<h2>Active Message Interfaces</h2>
-
-<p>Since it is very common to have multiple services using the same
-radio to communicate, TinyOS provides the Active Message (AM) layer to
-multiplex access to the radio.  The term "AM type" refers to the
-field used for multiplexing.  AM types are similar in function to the
-Ethernet frame type field, IP protocol field, and the UDP port in that
-all of them are used to multiplex access to a communication service.
-AM packets also includes a destination field, which stores an
-"AM address"  to address packets to particular motes. Additional 
-interfaces, also located in the <code>tos/interfaces</code> directory, 
-were introduced to support the AM services:
-
-<p>
-<ul>
-
-<li><code><a
-href="../../../tos/interfaces/AMPacket.nc">AMPacket</a></code> - Similar
-to <code>Packet</code>, provides the basic AM accessors for the
-<code>message_t</code> abstract data type.  This interface provides
-commands for getting a node's AM address, an AM packet's destination,
-and an AM packet's type.  Commands are also provides for setting an AM
-packet's destination and type, and checking whether the destination is
-the local node.
-
-<li><code><a href="../../../tos/interfaces/AMSend.nc">AMSend</a></code> -
-Similar to <code>Send</code>, provides the basic Active Message sending
-interface.  The key difference between <code>AMSend</code> and
-<code>Send</code> is that <code>AMSend</code> takes a destination AM address in its
-<code>send</code> command.
-
-</ul>
-
-<p>
-The AM address of a node can be set at installation time, using the
-<code>make install.<i>n</i></code> or <code>make reinstall.<i>n</i></code>
-commands. It can be changed at runtime using the
-<code>ActiveMessageAddressC</code> component (see below).  </ul>
-
-<h2>Components</h2>
-
-<p>A number of components implement the basic communications and
-active message interfaces.  Let's take a look at some of the
-components in the <code>/tos/system</code> directory.  You should be
-familiar with these components because your code needs to specify both
-the <i>interfaces</i> your application
-<i>uses</i> as well as the <i>components</i> which <i>provide</i>
-(implement) those interfaces:
-
-<p>
-<ul>
-
-<li><code><a
-href="../../../tos/system/AMReceiverC.nc">AMReceiverC</a></code> -
-Provides the following interfaces: <code>Receive</code>, <code>Packet</code>,
-and <code>AMPacket</code>.
-
-<li><code><a href="../../../tos/system/AMSenderC.nc">AMSenderC</a></code>
-- Provides <code>AMSend</code>, <code>Packet</code>, <code>AMPacket</code>, and
-<code>PacketAcknowledgements</code> as <code>Acks</code>.
-
-<li><code><a href="../../../tos/system/AMSnooperC.nc">AMSnooperC</a></code>
-- Provides <code>Receive</code>, <code>Packet</code>, and <code>AMPacket</code>.
-
-<li><code><a
-href="../../../tos/system/AMSnoopingReceiverC.nc">AMSnoopingReceiverC</a></code>
-- Provides <code>Receive</code>, <code>Packet</code>, and <code>AMPacket</code>.
-
-<li><code><a
-href="../../../tos/system/ActiveMessageAddressC.nc">ActiveMessageAddressC</a></code>
-- Provides commands to get and set the node's active message address.
-This interface is not for general use and changing the a node's active
-message address can break the network stack, so avoid using it unless
-you know what you are doing.
-
-</ul>
-
-<h2>Naming Wrappers</h2>
-
-<p>Since TinyOS supports multiple platforms, each of which might have
-their own implementation of the radio drivers, an additional,
-platform-specific, naming wrapper called <code>ActiveMessageC</code> is
-used to bridge these interfaces to their underlying, platform-specific
-implementations.  <code>ActiveMessageC</code> provides most of the
-communication interfaces presented above.  Platform-specific versions
-of <code>ActiveMessageC</code>, as well the underlying implementations
-which may be shared by multiple platforms (e.g. Telos and MicaZ)
-include:
-
-<p>
-
-<ul>
-
-<li><code>ActiveMessageC</code> for the <a
-href="../../../tos/platforms/eyesIFX/ActiveMessageC.nc">eyesIFX</a>
-platform is implemented by <code><a
-href="../../../tos/chips/tda5250/Tda5250ActiveMessageC.nc">Tda5250ActiveMessageC</a></code>.
-
-<li><code>ActiveMessageC</code> for the 
-<a href="../../../tos/platforms/intelmote2/ActiveMessageC.nc">intelmote2</a>,
-<a href="../../../tos/platforms/micaz/ActiveMessageC.nc">micaz</a>,
-<a href="../../../tos/platforms/telosa/ActiveMessageC.nc">telosa</a>, and
-<a href="../../../tos/platforms/telosa/ActiveMessageC.nc">telosb</a>
-are all implemented by 
-<code><a
-href="../../../tos/chips/cc2420/CC2420ActiveMessageC.nc">CC2420ActiveMessageC</a></code>.
-
-<li><code>ActiveMessageC</code> for the <a
-href="../../../tos/platforms/mica2/ActiveMessageC.nc">mica2</a>
-platform is implemented by <code><a
-href="../../../tos/chips/cc1000/CC1000ActiveMessageC.nc">CC1000ActiveMessageC</a></code>.
-
-</ul>
-
-<h1>The TinyOS 2.0 Message Buffer</h1>
-
-<p>TinyOS 2.0 introduces a new message buffer abstraction called
-<code>message_t</code>.  If you are familiar with earlier versions of
-TinyOS, you need to know that <code>message_t</code> replaces 
-<code>TOS_Msg</code>.  The <code>message_t</code> structure is defined in
-<code><a
-href="../../../tos/types/message.h">tos/types/message.h</a></code>.
-
-<pre>
-typedef nx_struct message_t {
-  nx_uint8_t header[sizeof(message_header_t)];
-  nx_uint8_t data[TOSH_DATA_LENGTH];
-  nx_uint8_t footer[sizeof(message_header_t)];
-  nx_uint8_t metadata[sizeof(message_metadata_t)];
-} message_t;
-</pre>
-
-<p><b>Note: The header, footer, and metadata fields are all opaque and
-must not be accessed directly.  It is important to access the
-<code>message_t</code> fields only through <code>Packet</code>,
-<code>AMPacket</code>, and other such interfaces, as will be demonstrated
-in this tutorial.</b> The rationale for this approach is that it allows
-the data (payload) to be kept at a fixed offset, avoiding a copy when
-a message is passed between two link layers. See
-Section 3 in <a href="#fn1">TEP 111</a>  for more details.
-
-<h1>Sending a Message over the Radio</h1>
-
-We will now create a simple application that increments a counter, displays
-the counter's three least significant bits on the three LEDs, and sends a
-message with the counter value over the radio.  Our implementation will use
-a single timer and a counter, in a way similar to the
-<code>BlinkSingle</code> example from <a href="lesson2.html">lesson 2</a>.
-
-<h2>Reimplementing Blink</h2>
-
-As a first step, we can reimplement <code>Blink</code> using a single
-timer and counter.  Create a new directory in <tt>apps</tt> named
-<tt>BlinkToRadio</tt>:
-
-<pre>
-$ cd tinyos-2.x/apps
-$ mkdir BlinkToRadio
-</pre>
-
-Inside this directory, create a file <code>BlinkToRadioC.nc</code>, which
-has this code: 
-
-<pre>
-#include &lt;Timer.h&gt;
-#include "BlinkToRadio.h"
-
-module BlinkToRadioC {
-  uses interface Boot;
-  uses interface Leds;
-  uses interface Timer&lt;TMilli&gt; as Timer0;
-}
-implementation {
-  uint16_t counter = 0;
-
-  event void Boot.booted() {
-    call Timer0.startPeriodic(TIMER_PERIOD_MILLI);
-  }
-
-  event void Timer0.fired() {
-    counter++;
-    call Leds.set(counter);
-  }
-}
-
-</pre>
-
-<p>Let's look at a few specific lines in this program.  First, notice
-the C preprocessor <code>include</code> directive on the first line.  This
-directive tells the compiler to simply replace the directive with the
-entire contents of <code>Timer.h</code>.  The compiler looks for
-<code>Timer.h</code> in the <i>standard</i> places.  In this case,
-standard means the TinyOS system directories that are located in
-<code>tos</code> or its subdirectories.  It is possible to tell the
-compiler to look beyond these standard directories by using the
-<code>-I</code> flag in the Makefile, for example, as is common when
-including contributed libraries located in <code>contrib</code> directory
-tree.
-
-<p>The second line of this program is also an <code>include</code>
-directive, but note that it uses quotes around the filename rather
-than angle brackets.  The quotes tell the preprocessor to look in the
-current directory before searching through the standard directories
-for the particular file.  In this case, the <code>BlinkToRadio.h</code>
-file is located in the same directory and defines some constants that
-are used in this program.  We will take a look at
-<code>BlinkToRadio.h</code> in just a bit.
-
-<p>Next, the call to <code>Leds.set</code> directly sets the three LEDs to 
-the three low-order bits of the counter.
-
-<p>Finally, note the <code>call
-Timer0.startPeriodic(TIMER_PERIOD_MILLI)</code> line in the
-<code>Boot.booted</code> function.  The value of
-<code>TIMER_PERIOD_MILLI</code> is defined in the <code>BlinkToRadio.h</code>
-header file:
-
-<pre>
-#ifndef BLINKTORADIO_H
-#define BLINKTORADIO_H
-
-enum {
-  TIMER_PERIOD_MILLI = 250
-};
-
-#endif
-</pre>
-
-<p><code>BlinkToRadio.h</code> is a pretty standard header file but there
-are two things to note here.  First, notice the use of the
-<code>ifndef</code>, <code>define</code>, and <code>endif</code> directives.
-These directives are used to ensure that the definitions in each
-header file is not included multiple times because the compiler would
-complain about multiply-defined objects.  By convention, the literal
-used for these directives is an all-caps version of the filename with
-any periods converted to underscores.  The other important thing to
-note is the use of an <code>enum</code> declaration for defining the
-constant <code>TIMER_PERIOD_MILLI</code>.  Using <code>enum</code> for
-defining constants is preferred over using <code>define</code> because
-<code>enum</code> does not indiscriminantly replace every occurence of the
-<code>define</code>d literal, regardless of where it appears in the
-source.  As a result, <code>enum</code>s provide better scoping as well.
-
-<p><code>BlinkToRadioC.nc</code> provides the <i>implementation</i> logic
-of the program and <code>BlinkToRadio.h</code> defines constants and/or
-data structures.  A third file is needed to <i>wire</i> the interfaces
-that the implementation <code>uses</code> to the actual components which
-<code>provide</code> these interfaces.  The <code>BlinkToRadioAppC.nc</code>
-provides the needed wiring:
-
-<pre>
-#include &lt;Timer.h&gt;
-#include "BlinkToRadio.h"
-
-configuration BlinkToRadioAppC {
-}
-implementation {
-  components MainC;
-  components LedsC;
-  components BlinkToRadioC as App;
-  components new TimerMilliC() as Timer0;
-
-  App.Boot -> MainC;
-  App.Leds -> LedsC;
-  App.Timer0 -> Timer0;
-}
-</pre>
-
-<p>The <code>BlinkToRadioAppC</code> should look familiar to you since it is
-essentially a subset of the <code>Blink</code> application/configuration
-from an earlier lesson.</p>
-
-<p>These three files constitute all of the application code: the only other
-thing it needs is a Makefile. Create a file named <code>Makefile</code>. For
-an application as simple as this one, the Makefile is very short:</p>
-
-<pre>
-COMPONENT=BlinkToRadioAppC
-include $(MAKERULES)
-
-</pre>
-
-<p>The first line tells the TinyOS make system that the top-level
-application component is BlinkToRadioAppC. The second line 
-loads in the TinyOS build system, which has all of the rules
-for building and installing on different platforms.</p>
-
-<h2>Defining a Message Structure</h2>
-
-<p>Now that <code>Blink</code> has been reimplemented using a single timer
-and counter, we can now turn our attention to defining a message
-format to send data over the radio.  Our message will send both the
-node id and the counter value over the radio.  Rather than directly
-writing and reading the payload area of the <code>message_t</code> with
-this data, we will use a structure to hold them and then use structure
-assignment to copy the data into the message payload area.  Using a
-structure allows reading and writing the message payload more
-conveniently when your message has multiple fields or multi-byte fields
-(like uint16_t or uint32_t) because you can avoid reading and writing
-bytes from/to the payload using indices and then shifting and adding
-(e.g. <code>uint16_t x = data[0] << 8 + data[1]</code>).  Even for a
-message with a single field, you should get used to using a structure
-because if you ever add more fields to your message or move any of the
-fields around, you will need to manually update all of the payload
-position indices if you read and write the payload at a byte level.
-Using structures is straightforward.  To define a message structure
-with a <code>uint16_t</code> node id and a <code>uint16_t</code> counter in
-the payload, we add the following lines to <code>BlinkToRadio.h</code>,
-just before the <code>endif</code> directive:
-
-<pre>
-typedef nx_struct BlinkToRadioMsg {
-  nx_uint16_t nodeid;
-  nx_uint16_t counter;
-} BlinkToRadioMsg;
-</pre>
-
-<p>If this code doesn't look even vaguely familiar, you should spend a
-few minutes reading up on C structures. If you are familiar with C
-structures, this syntax should look familar but the <code>nx_</code>
-prefix on the keywords <code>struct</code> and <code>uint16_t</code> should
-stand out.  The <code>nx_</code> prefix is specific to the nesC language
-and signifies that the <code>struct</code> and <code>uint16_t</code> are
-<i>external types</i><a href="#hint15">(3)</a><a
-href="#hint16">(4)</a>.  External types have the same representation
-on all platforms.  The nesC compiler generates code that transparently
-reorders access to <code>nx_</code> data types and eliminates the need
-to manually address endianness and alignment (extra padding in structs
-present on some platforms) issues.  So what is endianness?  Read on...
-
-<p>Different processors represent numbers in different ways in their
-memory: some processors use a "big endian" representation which means
-that the most significant byte of a multi-byte (e.g. 16- or 32-bit)
-number is located at a lower memory address than the least significant
-byte, while "little endian" stores data in exactly the opposite order.
-A problem arises when data is serialized and sent over the network
-because different processors will decode the same set of bytes in
-different ways, depending on their "endianness."  The main difficulty
-endianness presents is that it requires operations to rearrange byte
-orders to match the network protocol specification or the processor
-architecture -- an annoying and error-prone process.  The
-<code>htons</code>, <code>htonl</code>, <code>ntohs</code>, and
-<code>ntohl</code> calls used with the sockets API are an example of
-platform-specific calls that convert between network and host byte
-orders, but you have to remember to use them.  The nesC programming
-language takes a different approach to the problem and defines
-<i>external types</i> which allow the programmer to avoid dealing with
-byte reordering.  In particular, the <code>nx_</code> prefix on a type
-(e.g. <code>nx_uint16_t</code>) indicates the field is to serialized
-in big endian format.  In contrast, the <code>nxle_</code> prefix
-signifies that the field is serialized in little endian format.
-
-
-<h2>Sending a Message</h2>
-
-<p>Now that we have defined a message type for our application,
-<code>BlinkToRadioMsg</code>, we will next see how to send the message
-over the radio.  Before beginning, let's review the purpose of the
-application.  We want a timer-driven system in which every firing of
-the timer results in (i) incrementing a counter, (ii) displaying the
-three lowest bits of the counter on the LEDs, and (iii) transmitting
-the node's id and counter value over the radio.  To implement this
-program, we follow a number of simple steps, as described in the next
-paragraph.
-
-<p>First, we need to identify the interfaces (and components) that
-provide access to the radio and allow us to manipulate the
-<code>message_t</code> type.  Second, we must update the <code>module</code>
-block in the <code>BlinkToRadioC.nc</code> by adding <code>uses</code>
-statements for the interfaces we need.  Third, we need to declare 
-new variables and add any initialization and start/stop code that is
-needed by the interfaces and components.  Fourth, we must add any
-calls to the component interfaces we need for our application.  Fifth,
-we need to implmement any events specified in the interfaces we plan
-on using.  Sixth, the <code>implementation</code> block of the application
-configuration file, <code>BlinkToRadioApp.c</code>, must be updated by
-adding a <code>components</code> statement for each component we use that
-provides one of the interfaces we chose earlier.  Finally, we need to
-wire the the interfaces used by the application to the components
-which provide those interfaces.
-
-<p>Let's walk through the steps, one-by-one: 
-
-<ol>
-
-<p><li><b>Identify the interfaces (and components) that provide access
-to the radio and allow us to manipulate the <code>message_t</code>
-type.</b> 
-
-<p>We will use the <code>AMSend</code> interface to send packets as
-well as the <code>Packet</code> and <code>AMPacket</code> interfaces to access
-the <code>message_t</code> abstract data type.  Although it is possible to
-wire directly to the <code>ActiveMessageC</code> component, we will
-instead use the <code>AMSenderC</code> component.  However, we still need
-to start the radio using the <code>ActiveMessageC.SplitControl</code>
-interface.
-
-<p>The reason for using <code>AMSenderC</code> is because it provides a
-virtualized abstraction.  Earlier versions of TinyOS did not
-virtualize access to the radio, so it was possible for two components
-that were sharing the radio to interfere with each other.  It was not
-at all uncommon for one component to discover the radio was busy
-because some other component, unknown to the first component, was
-accessing the active message layer.  Radio virtualization was
-introduced in TinyOS 2.0 to address this interference and
-<code>AMSenderC</code> was written to provide this virtualization.  Every
-user of <code>AMSenderC</code> is provided with a 1-deep queue and
-the queues of all users are serviced in a fair manner.
-
-<p><li><b>Update the <code>module</code> block in the
-<code>BlinkToRadioC.nc</code> by adding <code>uses</code> statements for the
-interfaces we need:</b>
-
-<pre>
-module BlinkToRadioC {
-  ...
-  uses interface Packet;
-  uses interface AMPacket;
-  uses interface AMSend;
-  uses interface SplitControl as AMControl;
-}
-</pre>
-
-Note that <code>SplitControl</code> has been renamed to <code>AMControl</code>
-using the <code>as</code> keyword.  nesC allows interfaces to be renamed
-in this way for several reasons.  First, it often happens
-that two or more components that are needed in the same module provide the
-same interface.  The <code>as</code> keyword allows one or more such names
-to be changed to distinct names so that they can each be addressed
-individually.  Second, interfaces are sometimes renamed to something
-more meaningful.  In our case, <code>SplitControl</code> is a general
-interface used for starting and stopping components, but the name
-<code>AMControl</code> is a mnemonic to remind us that the particular
-instance of <code>SplitControl</code> is used to control the
-<code>ActiveMessageC</code> component.
-
-
-<p><li><b>Declare any new variables and add any needed initialization
-code.</b>
-
-<p>First, we need to declare some new module-scope variables.  We need a
-<code>message_t</code> to hold our data for transmission.  We also need a
-flag to keep track of when the radio is busy sending.  These
-declarations need to be added in the <code>implementation</code> block of
-<code>BlinkToRadioC.nc</code>:
-
-<pre>
-implementation {
-  bool busy = FALSE;
-  message_t pkt;
-  ...
-}
-</pre>
-
-<p>Next, we need to handle the initialization of the radio.  The radio
-needs to be started when the system is booted so we must call
-<code>AMControl.start</code> inside <code>Boot.booted</code>.  The only
-complication is that in our current implementation, we start a timer
-inside <code>Boot.booted</code> and we are planning to use this timer to
-send messages over the radio but the radio can't be used until it has
-completed starting up.  The radio signals that it has completed
-starting through the <code>AMControl.startDone</code> event.  To ensure
-that we do not start using the radio before it is ready, we need to
-postpone starting the timer until after the radio has completed
-starting.  We can accomplish this by moving the call to start the
-timer, which is now inside <code>Boot.booted</code>, to
-<code>AMControl.startDone</code>, giving us a new <code>Boot.booted</code> with
-the following body:
-
-<pre>
-  event void Boot.booted() {
-    call AMControl.start();
-  }
-</pre>
-
-<p>We also need to implement the <code>AMControl.startDone</code> and
-<code>AMControl.stopDone</code> event handlers, which have the
-following bodies:
-
-<pre>
-  event void AMControl.startDone(error_t err) {
-    if (err == SUCCESS) {
-      call Timer0.startPeriodic(TIMER_PERIOD_MILLI);
-    }
-    else {
-      call AMControl.start();
-    }
-  }
-
-  event void AMControl.stopDone(error_t err) {
-  }
-</pre>
-
-<p>If the radio is started successfully, <code>AMControl.startDone</code>
-will be called with the <code>error_t</code> parameter set to a value of
-<code>SUCCESS</code>.  If the radio starts successfully, then it is
-appropriate to start the timer.  If, however, the radio does not start
-successfully, then it obviously cannot be used so we try again to
-start it.  This process continues until the radio starts, and ensures
-that the node software doesn't run until the key components have
-started successfully.  If the radio doesn't start at all, a human
-operator might notice that the LEDs are not blinking as they are
-supposed to, and might try to debug the problem.
-
-
-<p><li><b>Add any program logic and calls to the used interfaces we
-need for our application.</b> 
-
-<p>Since we want to transmit the node's id and counter value every
-time the timer fires, we need to add some code to the
-<code>Timer0.fired</code> event handler:
-
-<pre>
-event void Timer0.fired() {
-  ...
-  if (!busy) {
-    BlinkToRadioMsg* btrpkt = (BlinkToRadioMsg*)(call Packet.getPayload(&amp;pkt, NULL));
-    btrpkt->nodeid = TOS_NODE_ID;
-    btrpkt->counter = counter;
-    if (call AMSend.send(AM_BROADCAST_ADDR, &amp;pkt, sizeof(BlinkToRadioMsg)) == SUCCESS) {
-      busy = TRUE;
-    }
-  }
-}
-</pre>
-
-This code performs several operations.  First, it ensures that a message
-transmission is not in progress by checking the busy flag. Then it
-gets the packet's payload portion and casts it to a pointer to the
-previously declared <code>BlinkToRadioMsg</code> external type. It can
-now use this pointer to initialise the packet's fields, and then send
-the packet by calling <code>AMSend.send</code>. The packet is sent to all 
-nodes in radio range by specyfing <code>AM_BROADCAST_ADDR</code> as the
-destination address. Finally, the test against SUCCESS verifies that the
-AM layer accepted the message for transmission. If so, the busy flag is set 
-to true. For the duration of the send attempt, the packet is owned by the
-radio, and user code must not access it.
-
-<p>Note that we could have avoided using the <code>Packet</code> interface,
-as it's <code>getPayload</code> command is repeated within <code>AMSend</code>.
-
-
-<p><li><b>Implmement any (non-initialization) events specified in the
-interfaces we plan on using.</b> 
-
-<p>Looking through the <code>Packet</code>,
-<code>AMPacket</code>, and <code>AMSend</code> interfaces, we see that there
-is only one <code>event</code> we need to worry about,
-<code>AMSend.sendDone</code>:
-
-<pre>
-  /** 
-   * Signaled in response to an accepted send request. msg is
-   * the message buffer sent, and error indicates whether
-   * the send was successful.
-   *
-   * @param  msg   the packet which was submitted as a send request
-   * @param  error SUCCESS if it was sent successfully, FAIL if it was not,
-   *               ECANCEL if it was cancelled
-   * @see send
-   * @see cancel
-   */ 
-  event void sendDone(message_t* msg, error_t error);
-</pre>
-
-This event is signaled after a message transmission attempt.  In
-addition to signaling whether the message was transmitted successfully
-or not, the event also returns ownership of <code>msg</code> from
-<code>AMSend</code> back to the component that originally called the
-<code>AMSend.send</code> command.  Therefore <code>sendDone</code> handler
-needs to clear the <code>busy</code> flag to indicate that the message
-buffer can be reused:
-
-<pre>
-  event void AMSend.sendDone(message_t* msg, error_t error) {
-    if (&amp;pkt == msg) {
-      busy = FALSE;
-    }
-  }
-</pre>
-
-Note the check to ensure the message buffer that was signaled is the
-same as the local message buffer.  This test is needed because if two
-components wire to the same <code>AMSend</code>, <i>both</i> will receive
-a <code>sendDone</code> event after <i>either</i> component issues a
-<code>send</code> command.  Since a component writer has no way to enforce
-that her component will not be used in this manner, a defensive style
-of programming that verifies that the sent message is the same one
-that is being signaled is required.
-
-
-<p><li><b>Update the <code>implementation</code> block of the application
-configuration file by adding a <code>components</code> statement for each
-component used that provides one of the interfaces chosen earlier.</b>
-
-<p>The following lines can be added just below the existing
-<code>components</code> declarations in the <code>implementation</code> block
-of <code>BlinkToRadioAppC.nc</code>:
-
-<pre>
-implementation {
-  ...
-  components ActiveMessageC;
-  components new AMSenderC(AM_BLINKTORADIO);
-  ...
-}
-</pre>
-
-These statements indicate that two components, <code>ActiveMessageC</code>
-and <code>AMSenderC</code>, will provide the needed interfaces.  However,
-note the slight difference in their syntax.  <code>ActiveMessageC</code>
-is a singleton component that is defined once for each type of
-hardware platform.  <code>AMSenderC</code> is a generic, parameterized
-component.  The <code>new</code> keyword indicates that a new instance of
-<code>AMSenderC</code> will be created.  The <code>AM_BLINKTORADIO</code>
-parameter indicates the AM type of the <code>AMSenderC</code>.  We can
-extend the <code>enum</code> in the <code>BlinkToRadio.h</code> header file to
-incorporate the value of <code>AM_BLINKTORADIO</code>:
-
-<pre>
-...
-enum {
-  AM_BLINKTORADIO = 6,
-  TIMER_PERIOD_MILLI = 250
-};
-...
-</pre>
-
-
-<p><li><b>Wire the the interfaces used by the application to the
-components which provide those interfaces.</b> 
-
-<p>The following lines
-will wire the used interfaces to the providing components.  These
-lines should be added to the bottom of the <code>implementation</code>
-block of <code>BlinkToRadioAppC.nc</code>:
-
-<pre>
-implementation {
-  ...
-  App.Packet -&gt; AMSenderC;
-  App.AMPacket -&gt; AMSenderC;
-  App.AMSend -&gt; AMSenderC;
-  App.AMControl -&gt; ActiveMessageC;
-}
-</pre>
-
-
-</ol>
-
-
-<h1>Receiving a Message over the Radio</h1>
-
-<p>Now that we have an application that is transmitting messages, we
-can add some code to receive and process the messages.  Let's write
-code that, upon receiving a message, sets the LEDs to the three least
-significant bits of the counter in the message.  To make this
-application interesting, we will want to remove the line
-<code><strike>call Leds.set(counter);</strike></code> from the
-<code>Timer0.fired</code> event handler.  Otherwise, both the timer events
-and packet receptions will update the LEDs and the resulting effect
-will be bizarre.
-
-<p>If two motes are programmed with our modified application, then
-each will display the other mote's counter value.  If the motes go out
-of radio range, then the LEDs will stop changing.  You can even
-investigate link asymmetry by trying to get one mote's LEDs to keep
-blinking while the other mote's LEDs stop blinking.  This would
-indicate that the link from the non-blinking mote to blinking mote was
-available but that the reverse channel was no longer available.
-
-<ol>
-
-<p><li><b>Identify the interfaces (and components) that provide access
-to the radio and allow us to manipulate the <code>message_t</code>
-type.</b> <p>We will use the <code>Receive</code> interface to receive
-packets.
-
-<p><li><b>Update the module block in the BlinkToRadioC.nc by adding
-uses statements for the interfaces we need:</b>
-
-<pre>
-module BlinkToRadioC {
-  ...
-  uses interface Receive;
-}
-</pre>
-
-<p><li><b>Declare any new variables and add any needed initialization
-code.</b> <p> We will not require any new variables to receive and process
-messages from the radio.
-
-<p><li><b>Add any program logic and calls to the used interfaces we
-need for our application.</b> <p> Message reception is an event-driven
-process so we do not need to call cny commands on the
-<code>Receive</code>.
-
-<p><li><b>Implemement any (non-initialization) events specified in the
-interfaces we plan on using.</b> <p>We need to implement the
-<code>Receive.receive</code> event handler:
-
-<pre>
-event message_t* Receive.receive(message_t* msg, void* payload, uint8_t len) {
-  if (len == sizeof(BlinkToRadioMsg)) {
-    BlinkToRadioMsg* btrpkt = (BlinkToRadioMsg*)payload;
-    call Leds.set(btrpkt->counter);
-  }
-  return msg;
-}
-</pre>
-
-<p>The <code>receive</code> event handler performs some simple operations.
-First, we need to ensure that the length of the message is what is
-expected.  Then, the message payload is cast to a structure pointer of
-type <code>BlinkToRadioMsg*</code> and assigned to a local variable.
-Then, the counter value in the message is used to set the states of
-the three LEDs.
-
-<p>Note that we can safely manipulate the <code>counter</code> variable
-outside of an atomic section.  The reason is that <rr>receive</code>
-event executes in task context rather than interrupt context (events
-that have the <code>async</code> keyword can execute in interrupt
-context).  Since the TinyOS execution model allows only one task to
-execute at a time, if all accesses to a variable occur in task
-context, then no race conditions will occur for that variable.  Since
-all accesses to <code>counter</code> occur in task context, no critical
-sections are needed when accessing it.
-
-<p><li><b>Update the implementation block of the application
-configuration file by adding a components statement for each component
-used that provides one of the interfaces chosen earlier.</b> <p>The
-following lines can be added just below the existing
-<code>components</code> declarations in the implementation block of
-<code>BlinkToRadioAppsC.nc</code>:
-
-<pre>
-implementation {
-  ...
-  components new AMReceiverC(AM_BLINKTORADIO);
-  ...
-}
-</pre>
-
-This statement means that a new instance of <code>AMReceiverC</code> will
-be created.  <code>AMReceiver</code> is a generic, parameterized
-component. The <code>new</code> keyword indicates that a new instance of
-<code>AMReceiverC</code> will be created. The <code>AM_BLINKTORADIO</code>
-parameter indicates the AM type of the <code>AMReceiverC</code> and is
-chosen to be the same as that used for the <code>AMSenderC</code> used
-earlier, which ensures that the same AM type is being used for both
-transmissions and receptions.  <code>AM_BLINKTORADIO</code> is defined in
-the <code>BlinkToRadio.h</code> header file.
-
-<p><li><b>Wire the the interfaces used by the application to the
-components which provide those interfaces.</b> <p>Update the wiring by
-insert the following line just before the closing brace of the
-<code>implementation</code> block in BlinkToRadioAppC:
-
-<pre>
-implementation {
-  ...
-  App.Receive -> AMReceiverC;
-}
-</pre>
-
-<p><li><b>Test your application!</b><p> Testing your application is easy.
-Get two motes.  They can be mica2, micaz, telosa, telosb, or tmote.
-For this exercise, let's assume that the motes are telosb (if not,
-skip past the motelist part and program the mote using whatever the
-appropriate programmer parameters are for your hardware).  Assuming
-you are using a telosb, first open a Cygwin or Linux shell and cd to
-the <code>apps/tutorials/BlinkToRadio</code> directory.  Then, insert the
-first telosb mote into an available USB port on the PC and type
-<code>motelist</code> the at the Cygwin or Linux prompt ($).  You should
-see exactly one mote listed.  For example:
-
-<pre>
-$ motelist
-Reference  CommPort   Description
----------- ---------- ----------------------------------------
-UCC89MXV   COM17      Telos (Rev B 2004-09-27)
-</pre>
-
-<p>Now, assuming you are in the <code>apps/tutorials/BlinkToRadio</code>
-directory, type <code>make telosb install,1</code>.  You should see a lot
-text scroll by that looks something like:
-
-<pre>
-$ make telosb install,1
-mkdir -p build/telosb
-    compiling BlinkToRadioAppC to a telosb binary
-ncc -o build/telosb/main.exe -Os -O -mdisable-hwmul -Wall -Wshadow -DDEF_TOS_AM_GROUP=0x7d -Wnesc-all -target=telosb -fnesc-cfile=build/telosb/app.c -board=   BlinkToRadioAppC.nc -lm 
-    compiled BlinkToRadioAppC to build/telosb/main.exe
-            9040 bytes in ROM
-             246 bytes in RAM
-msp430-objcopy --output-target=ihex build/telosb/main.exe build/telosb/main.ihex
-    writing TOS image
-tos-set-symbols --objcopy msp430-objcopy --objdump msp430-objdump --target ihex build/telosb/main.ihex build/telosb/main.ihex.out-1 TOS_NODE_ID=1 ActiveMessageAddressC$addr=1
-    found mote on COM17 (using bsl,auto)
-    installing telosb binary using bsl
-tos-bsl --telosb -c 16 -r -e -I -p build/telosb/main.ihex.out-1
-MSP430 Bootstrap Loader Version: 1.39-telos-8
-Mass Erase...
-Transmit default password ...
-Invoking BSL...
-Transmit default password ...
-Current bootstrap loader version: 1.61 (Device ID: f16c)
-Changing baudrate to 38400 ...
-Program ...
-9072 bytes programmed.
-Reset device ...
-rm -f build/telosb/main.exe.out-1 build/telosb/main.ihex.out-1 
-</pre>
-
-<p>Now, remove the first telosb from the USB port, insert the
-batteries, and set it aside.  Insert the second telos into the USB
-port and once again type <code>motelist</code>.  You should again see
-something like:
-
-<pre>
-$ motelist
-Reference  CommPort   Description
----------- ---------- ----------------------------------------
-UC9VN03I   COM14      Telos (Rev B 2004-09-27)
-</pre>
-
-<p>Finally, type <code>make telosb reinstall,2</code> and you should once
-again see something like the following scroll by:
-
-<pre>
-$ make telosb reinstall,2
-tos-set-symbols --objcopy msp430-objcopy --objdump msp430-objdump --target ihex build/telosb/main.ihex build/telosb/main.ihex.out-2 TOS_NODE_ID=2 ActiveMessageAddressC$addr=2
-    found mote on COM14 (using bsl,auto)
-    installing telosb binary using bsl
-tos-bsl --telosb -c 13 -r -e -I -p build/telosb/main.ihex.out-2
-MSP430 Bootstrap Loader Version: 1.39-telos-8
-Mass Erase...
-Transmit default password ...
-Invoking BSL...
-Transmit default password ...
-Current bootstrap loader version: 1.61 (Device ID: f16c)
-Changing baudrate to 38400 ...
-Program ...
-9072 bytes programmed.
-Reset device ...
-rm -f build/telosb/main.exe.out-2 build/telosb/main.ihex.out-2 
-</pre>
-
-<b><font color="red">At this point, both motes should be blinking
-their LEDs.</font></b> If you press the RESET button on either telosb,
-then the LEDs on the <i>other</i> telosb will pause on whatever was
-being displayed at the moment you pressed RESET.  When you release the
-RESET the button, the paused mote will be reset and then resume
-counting from one.
-
-</ol>
-
-<!--
-<h1>Accessing Message Metadata</h1>
--->
-
-<h1>Conclusions</h1>
-
-This lesson has introduced radio communications TinyOS 2.x.
-
-<a name=#related_docs>
-<h1>Related Documentation</h1>
-
-<ul>
-<li> (1) <a name="fn1"><a href="../tep111.html">TEP 111: message_t</a></a>
-<li> (2) <a name="fn2"><a href="../tep116.html">TEP 116: Packet Protocols</a></a>
-</ul>
-
-<p><a name="hint15">(3)</a><b>Programming Hint 15:</b>Always use platform
-independent types when defining message formats. 
-From Phil Levis' <a href="http://csl.stanford.edu/~pal/pubs/tinyos-programming-1-0.pdf">
-<i>TinyOS Programming</i></a>
-
-<p><a name="hint16">(4)</a><b>Programming Hint 16:</b>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.
-From Phil Levis' <a href="http://csl.stanford.edu/~pal/pubs/tinyos-programming-1-0.pdf">
-<i>TinyOS Programming</i></a>
-
-<!-- Begin footer -->
-<br>
-<hr>
-<center>
-<p>&lt;&nbsp;<b><a href="lesson2.html">Previous Lesson</a></b> |&nbsp; <b><a
- href="index.html">Top</a></b> &nbsp;|&nbsp; <b><a href="lesson4.html">Next Lesson </a>&nbsp;&gt;</b>
-</center>
-
+<p>Sorry, your browser does not support frames. Please <a href="http://docs.tinyos.net/index.php/Mote-mote_radio_communication" target="_top">go here</a>.</p>
 </body>
-</html>
+</noframes>
+</frameset>
+</html>
\ No newline at end of file
index eb76950be893e7dcfe890cfbfabe84e9a0955802..796e17d74328689ec87933b0cbef2619de38ce44 100644 (file)
-<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
-<html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" ^M   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
-  <title>Lesson 4: Mote-PC serial communication and SerialForwarder</title>
-  <link href="../../stylesheets/tutorial.css" rel="stylesheet" type="text/css">
+<title>klueska.com</title>
 </head>
+<frameset>
+<frame src="http://docs.tinyos.net/index.php/Mote-PC_serial_communication_and_SerialForwarder" name="redir_frame" />
+<noframes>
 <body>
-    <div class="title">Lesson 4: Mote-PC serial communication and SerialForwarder</div>
-    <div class="subtitle">Last updated June 27 2006</div>
-
-<p>To goal of this lesson is to show you how to communicate with a
-mote from a PC. This will allow you to collect data from the network,
-send commands to motes, and monitor network traffic.</p>
-
-<p>This tutorial presents the Java-based infrastructure for communicating
-with motes. There is also a C-based infrastructure, found in support/sdk/c.
-Please see the documentation found there, and the <code>mig</code> and 
-<code>ncg</code> man pages for more details.
-
-
-<h1>Packet sources and TestSerial</h1>
-
-<p>The first step is to check that you are able to get your PC to 
-communicate with a mote. Most motes have a serial port or similar
-interface. For example, the mica family can directly control a serial
-port: programming boards basically connect the mote's serial port
-pins to the actual serial port on the board. Telos motes also have
-a serial interface, but it talks to their USB hardware, which
-is similar in functionality but very different in terms of cables and
-connectors.</p>
-
-<p>The basic abstraction for mote-PC communication is a <b>packet
-source</b>. A packet source is exactly that: a communication medium
-over which an application can receive packets from and send packets to
-a mote. Examples of packet sources include serial ports, TCP sockets,
-and the SerialForwarder tool. Most TinyOS communication tools take
-an optional <code>-comm</code> parameter, which allows you to 
-specify the packet source as a string. For example:</p>
-
-<pre>
-$ java net.tinyos.tools.Listen -comm serial@COM1:telos
-</pre>
-
-<p>tells the Listen tool to use the COM1 serial port (on a Windows
-machine) at the correct speed for a telos mote, while</p>
-
-<pre>
-$ java net.tinyos.tools.Listen -comm serial@/dev/ttyS0:micaz
-</pre>
-
-<p>tells Listen to use the serial port <code>/dev/ttyS0</code> (on
-a UNIX machine) at the correct speed for a micaz mote.</p>
-
-<p>The first step to testing your serial port is to install
-the <code>apps/tests/TestSerial</code> application on a mote. This 
-application sends a packet to the serial port every second,
-and when it receives a packet over the serial port it displays
-the packet's sequence number on the LEDs.</p>
-
-<p>Once you have installed <code>TestSerial</code>, you need
-to run the corresponding Java application that communicates with
-it over the serial port. This is built when you build the TinyOS
-application. From in the application directory, type:</p>
-
-<pre>
-$ java TestSerial
-</pre>
-
-If you get a message like
-<pre>
-The java class is not found:  TestSerial
-</pre>
-it means that you either haven't compiled the Java code (try running <code>
-make <i>platform</i></code> again) or you don't have <code>.</code> (the
-current directory) in your Java <code>CLASSPATH</code>.
-
-<p>Because you haven't specified a packet source, TestSerial
-will fall back to a default, which is a SerialForwarder. Since
-you don't have a SerialForwarder running, TestSerial will
-exit, complaining that it can't connect to one. So let's specify
-the serial port as the source. The syntax for a serial port 
-source is as follows:</p>
-
-<pre>
-   serial@&lt;PORT&gt;:&lt;SPEED&gt;
-</pre>
-
-<p>PORT depends on your platform and where you have plugged the mote in.
-For Windows/Cygwin platforms, it is COM<i>N</i>, where <i>N</i> is the port
-number. For Linux/UNIX machines, it is <code>/dev/ttyS</code><i>N</i> for a
-built-in serial port, or one of <code>/dev/ttyUSB<i>N</I></code> or
-<code>/dev/usb/tts/<i>N</I></code> for a serial-over-USB port. Additionally
-as we saw in <a href="lesson1.html">lesson 1</a>, on Linux you will
-typically need to make this serial port world writeable.  As superuser,
-execute the following command:
-<pre>chmod 666 <i>serialport</i></pre>
-<p>
-
-<p>The SPEED
-can either be a numeric value, or the name of a platform. Specifying a
-platform name tells the serial packet source to use the default speed for
-the platform. Valid platforms are:</p>
-
-<CENTER>
-<table>
-<tr><td>Platform</td><td>Speed (baud)</td></tr>
-<tr><td colspan=2><hr></td></tr>
-<tr><td>telos</td><td>115200</td></tr>
-<tr><td>telosb</td><td>115200</td></tr>
-<tr><td>tmote</td><td>115200</td></tr>
-<tr><td>micaz</td><td>57600</td></tr>
-<tr><td>mica2</td><td>57600</td></tr>
-<tr><td>mica2dot</td><td>19200</td></tr>
-<tr><td>eyes</td><td>115200</td></tr>
-<tr><td>intelmote2</td><td>115200</td></tr>
-</table>
-</center>
-<br>
-
-<p>The Java file <tt>support/sdk/java/net/tinyos/packet/BaudRate.java</tt>
-determines these mappings. Unlike in TinyOS 1.x, all platforms have a common
-serial packet format. Following the table, these two serial 
-specfications are identical:</p>
-
-<pre>
-serial@COM1:micaz
-serial@COM1:57600
-</pre>
-
-<p>If you run <code>TestSerial</code> with the proper PORT and SPEED
-settings, you should see output like this:</p>
-
-<pre>
-Sending packet 1
-Received packet sequence number 4
-Sending packet 2
-Received packet sequence number 5
-Sending packet 3
-Received packet sequence number 6
-Sending packet 4
-Received packet sequence number 7
-Received packet sequence number 8
-Sending packet 5
-Received packet sequence number 9
-Sending packet 6
-</pre>
-
-<p>and the mote LEDs will blink.</p>
-
-<h2>Cannot find JNI error</h2>
-
-<p>If you try to run TestSerial and receive an error that Java cannot find
-TOSComm JNI support, this means the Java Native Interface (JNI) files that
-control the serial port haven't been correctly installed. Run the command
-<code>tos-install-jni</code> (on Linux, do this as the superuser). If this
-command does not exist, then you have either not installed the tinyos-tools
-RPM or it was installed incorrectly. The <tt>tos-</tt> commands are typically
-installed in /usr/bin. If you still cannot find the script, email <tt>tinyos-help</tt>.</p>
-
-<h3>Installing <tt>tos-install-jre</tt> from CVS sources</h3>
-<p>If you have not installed the tools RPM and are working directly from the 
-TinyOS CVS repository, you can manually install the tos-locate-jre script. 
-Go to <code>tinyos-2.x/tools/tinyos/java</code>. If
-the directory has a <code>Makefile</code> in it, type <code>make</code>
-and (again, on Linux, as superuser) <code>make
-install</code>.  If the directory does not have a <code>Makefile</code>, go
-to <code>tinyos-2.x/tools</code> and type:</p>
-
-<pre>
-$ ./Bootstrap
-$ ./configure
-$ ./make
-$ ./make install
-</pre>
-
-<p>Then type <code>tos-install-jni</code>. This should install
-serial support in your system.</p>
-
-<h2>MOTECOM</h2>
-
-<p>If you do not pass a
-<code>-comm</code> parameter, then tools will check the 
-<code>MOTECOM</code> environment variable for a packet source,
-and if there is no <code>MOTECOM</code>, they default to a
-SerialForwarder. This means that if you're always communicating
-with a mote over your serial port, you can just set <code>MOTECOM</code>
-and no longer have to specify the <code>-comm</code> parameter.
-For example:</p>
-
-<pre>
-export MOTECOM=serial@COM1:19200 # mica baud rate
-export MOTECOM=serial@COM1:mica  # mica baud rate, again
-export MOTECOM=serial@COM2:mica2 # the mica2 baud rate, on a different serial port
-export MOTECOM=serial@COM3:57600 # explicit mica2 baud rate
-</pre>
-
-<p>Try setting your MOTECOM variable and running TestSerial without
-a <code>-comm</code> parameter.</p>
-
-
-<h1>BaseStation and net.tinyos.tools.Listen</h1>
-
-<p><code>BaseStation</code> is a basic TinyOS utility application.
-It acts as a bridge between the serial port and radio network.
-When it receives a packet from the serial port,
-it transmits it on the radio; when it receives a packets over
-the radio, it transmits it to the serial port. Because TinyOS
-has a toolchain for generating and sending packets to a mote
-over a serial port, using a BaseStation allows PC tools to
-communicate directly with mote networks.</p>
-
-<p>Take one of the two nodes that had BlinkToRadio (from <a href="lesson3.html">lesson 3</a>) installed
-and install BaseStation on it. If you turn on the node that still
-has BlinkToRadio installed, you should see LED 1 on the BaseStation
-blinking. BaseStation toggles LED 0 whenever it sends a packet 
-to the radio and LED 1 whenever it sends a packet to the 
-serial port. It toggles LED 2 whenever it has to drop a packet:
-this can happen when one of the two receives packets faster
-than the other can send them (e.g., receiving micaZ radio packets
-at 256kbps but sending serial packets at 57.6kbps).</p>
-
-<p>BaseStation is receiving your BlinkToRadio packets and sending
-them to the serial port, so if it is plugged into a PC we can
-view these packets. The Java tool Listen is a basic packet
-sniffer: it prints out the binary contents of any packet it hears.
-Run Listen, using either MOTECOM or a -comm parameter:</p>
-
-<pre>
-$ java net.tinyos.tools.Listen
-</pre>
-
-<p>Listen creates a packet source and just prints out every
-packet it sees. Your output should look something like this:</p>
-
-<pre>
-00 FF FF 00 00 04 22 06 00 02 00 01
-00 FF FF 00 00 04 22 06 00 02 00 02
-00 FF FF 00 00 04 22 06 00 02 00 03
-00 FF FF 00 00 04 22 06 00 02 00 04
-00 FF FF 00 00 04 22 06 00 02 00 05
-00 FF FF 00 00 04 22 06 00 02 00 06
-00 FF FF 00 00 04 22 06 00 02 00 07
-00 FF FF 00 00 04 22 06 00 02 00 08
-00 FF FF 00 00 04 22 06 00 02 00 09
-00 FF FF 00 00 04 22 06 00 02 00 0A
-00 FF FF 00 00 04 22 06 00 02 00 0B
-</pre>
-
-
-<p>Listen is simply printing out the packets that are coming from the
-mote. Each data packet that comes out of the mote contains several fields
-of data. The first byte (00) indicates that this is packet is an AM
-packet. The next fields are the generic Active Message fields, defined in
-<tt>tinyos-2.x/tos/serial/Serial.h</tt>.  Finally, the remaining fields are
-the data payload of the message, which was defined in BlinkToRadio.h as:</p>
-
-<pre>
-typedef nx_struct BlinkToRadioMsg {
-  nx_uint16_t nodeid;
-  nx_uint16_t counter;
-} BlinkToRadioMsg;
-</pre>
-
-The overall message format for the BlinkToRadioC application is
-therefore (ignoring the first 00 byte): </p>
-<ul>
-  <li> <b>Destination address</b> (2 bytes)</li>
-  <li> <b>Source address</b> (2 bytes)</li>
-  <li> <b>Message length</b> (1 byte)</li>
-  <li> <b>Group ID</b> (1 byte)</li>
-  <li> <b>Active Message handler type</b> (1 byte)</li>
-  <li> <b>Payload</b> (up to 28 bytes):</li>
-  <ul>
-    <li> <b>source mote ID</b> (2 bytes)</li>
-    <li> <b>sample counter</b> (2 bytes)</li>
-  </ul>
-</ul>
-So we can interpret the data packet as follows:
-<table hspace="0" cellpadding="0" cellspacing="10" border="0">
-  <tbody>
-    <tr bgcolor="#d0d0d0">
-      <td><b>dest addr</b></td>
-      <td><b>src addr</b></td>
-      <td><b>msg len</b></td>
-      <td><b>groupID</b></td>
-      <td><b>handlerID</b></td>
-      <td><b>hop addr</b></td>
-      <td><b>counter</b></td>
-    </tr>    <tr>
-      <td bgcolor="#d0d0ff">ff ff</td>
-      <td bgcolor="#d0d0ff">00 00</td>
-      <td bgcolor="#d0d0ff">04</td>
-      <td bgcolor="#d0d0ff">22</td>
-      <td bgcolor="#d0d0ff">06</td>
-      <td bgcolor="#d0ffd0">00 02</td>
-      <td bgcolor="#d0ffd0">00 0B</td>
-    </tr>
-  </tbody>
-</table>
-
-<p>The hop address depends on what mote ID you installed your
-BlinkToRadio application with. The default (if you do not specify
-and ID) is <code>00 01</code>.
-Note that the data is sent by the mote in <i>big-endian</i>
-format;  for example, <code>01 02</code> means 258 (256*1 + 2).
-This format is independent of the endian-ness of the processor,
-because the packet format is an <code>nx_struct</code>, which is
-a network format, that is, big-endian and byte-aligned. Using
-<code>nx_struct</code> (rather than a standard C <code>struct</code>)
-for a message payload ensures that it will work across platforms.</p>
-
-<p>TinyOS serial stacks do not fill in the source address as the
-address of the sending mote. The assumption is that the serial connection
-can identify the node, and setting the source address prevents 
-applications such as BaseStation from working properly. This is
-because BaseStation just forwards radio packets to the serial port:
-it needs to fill in the <i>radio source</i> address as the source
-address of the serial packet.</p>
-<p>As you watch the packets scroll by, you should see the counter
-field increase as the BlinkToRadio app increments its counter.</p>
-
-<h1>MIG: generating packet objects</h1>
-
-<p>The <tt>Listen</tt> program is the most basic way of communicating
-with the mote; it just prints binary packets to the screen. Obviously 
-it is not easy to visualize the sensor data
-using this program. What we'd really like is a better way of retrieving
-and observing data coming from the sensor network. Of course, exactly
-what data to display and how to visualize it can be very application 
-specific. For this reason, TinyOS only 
-has a few applications for visualizing simple
-sensor data (in the next lesson, you'll use the Oscilloscope application), 
-but it provides support for building new visualization or logging systems.
-</p> 
-
-<p>One problem with Listen is that it just dumps binary data: a user has
-to be able to read the bytes and parse them into a given packet format.
-The TinyOS toolchain makes this process easier by providing tools for
-automatically generating message objects from packet descriptions.
-Rather than parse packet formats manually, you can use the <code>mig</code>
-(Message Interface Generator) tool to build a Java, Python, or C interface
-to the message structure. Given a sequence of bytes, the MIG-generated
-code will automatically parse each of the fields in the packet, and it
-provides a set of standard accessors and mutators for printing out 
-received packets or generating new ones.</p>
-
-<p>The mig tool takes three basic arguments: what programming language
-to generate code for (Java, Python, or C), which file in which to find
-the structure, and the name of the structure. The tool also takes standard
-C options, such as -I for includes and -D for defines. The TestSerial
-application, for example, uses mig so that it can easily create
-and parse the packets over the serial port. If you go back to TestSerial
-and type <code>make clean;make</code>, you should see this:</p>
-
-<pre>
-rm -rf build *.class TestSerialMsg.java
-rm -rf _TOSSIMmodule.so TOSSIM.pyc TOSSIM.py
-mkdir -p build/telosb
-mig java -target=telosb -I%T/lib/oski -java-classname=TestSerialMsg TestSerial.h TestSerialMsg -o TestSerialMsg.java
-javac *.java
-    compiling TestSerialAppC to a telosb binary
-ncc -o build/telosb/main.exe -Os -O -mdisable-hwmul -Wall -Wshadow -DDEF_TOS_AM_GROUP=0x66 -Wnesc-all -DCC2420_DEF_CHANNEL=19 -target=telosb -fnesc-cfile=build/telosb/app.c -board= -I%T/lib/oski  TestSerialAppC.nc -lm 
-    compiled TestSerialAppC to build/telosb/main.exe
-            6300 bytes in ROM
-             281 bytes in RAM
-msp430-objcopy --output-target=ihex build/telosb/main.exe build/telosb/main.ihex
-    writing TOS image
-</pre>
-
-<p>Before building the TinyOS application, the Makefile has a rule
-for generating <code>TestSerialMsg.java</code>. It then compiles
-TestSerialMsg.java as well as TestSerial.java, and finally
-compiles the TinyOS application. Looking at the Makefile, we can see
-that it has a few more rules than the one for BlinkToRadio:</p>
-
-<pre>
-COMPONENT=TestSerialAppC
-BUILD_EXTRA_DEPS += TestSerial.class
-CLEAN_EXTRA = *.class TestSerialMsg.java
-
-TestSerial.class: $(wildcard *.java) TestSerialMsg.java
-        javac *.java
-
-TestSerialMsg.java:
-        mig java -target=null -java-classname=TestSerialMsg TestSerial.h TestSerialMsg -o $@
-
-include $(MAKERULES)
-</pre>
-
-<p>The <code>BUILD_EXTRA_DEPS</code> line tells the TinyOS make system
-that the TinyOS application has additional dependencies that must
-be satisfied before it can be built. The Makefile tells the make system
-that <code>TestSerial.class</code>, the Java application that we ran
-to test serial communication. The <code>CLEAN_EXTRA</code> line tells
-the make system extra things that need to be done when a user types
-<code>make clean</code> to clean up.</p>
-
-<p>The <code>BUILD_EXTRA_DEPS</code> line tells make to compile 
-TestSerial.class before the application; the line</p>
-
-<pre>
-TestSerial.class: $(wildcard *.java) TestSerialMsg.java
-        javac *.java
-</pre>
-
-<p>tells it that TestSerial.class depends on all of the .java files 
-in the directory as well as TestSerialMsg.java. Once all of these
-dependencies are resolved, the make system will call <code>javac
-*.java</code>, which creates TestSerial.class. The final line,</p>
-
-<pre>
-TestSerialMsg.java:
-        mig java -target=null -java-classname=TestSerialMsg TestSerial.h TestSerialMsg -o $@
-</pre>
-
-<p>tells the make system how to create TestSerialMsg.java, the
-Java class representing the packet sent between the mote and PC.
-Because TestSerialMsg.java is a dependency for TestSerial.class,
-make will create it if it is needed. To create TestSerialMsg.java,
-the Makefile invokes the mig tool. Let's step through the parameters
-one by one:</p>
-
-<table>
-<tr>  <td>mig</td>  <td width=60></td>                <td>Invoke mig</td> </tr>
-<tr>  <td>java</td> <td></td>                         <td>Build a Java class</td> </tr>
-<tr>  <td>-target=null</td> <td></td>                        <td>For the <code>null</code>platform</td></tr>
-<tr>  <td>-java-classname=TestSerialMsg</td><td></td> <td>Name the Java class TestSerialMsg</td> </tr>
-<tr>  <td>TestSerial.h</td>        <td></td>          <td>The structure is in TestSerial.h</td> </tr>
-<tr>  <td>TestSerialMsg</td>      <td></td>           <td>The structure is named TestSerialMsg</td></tr>
-<tr>  <td>-o $@</td>               <td></td>          <td>Write the file to $@, which is TestSerialMsg.java</tr></tr>
-</table>
-
-<p>The <code>null</code> platform is a special platform which is convenient to use
-as the target when using <code>mig</code>. It includes all the standard
-system components, but with dummy do-nothing implementations. Building an
-application for the <code>null</code> platform is useless, but it allows
-<code>mig</code> to extract the layout of packets.
-
-<p>Let's build a Java packet object for BlinkToRadio.  Open the Makefile for 
-BlinkToRadio and add a dependency:</p>
-
-<pre>
-BUILD_EXTRA_DEPS=BlinkToRadioMsg.class
-</pre>
-
-<p>Then add a step which explains how to compile a .java to a .class:</p>
-
-<pre>
-BlinkToRadioMsg.class: BlinkToRadioMsg.java
-        javac BlinkToRadioMsg.java
-</pre>
-
-<p><b>Note that there must be a tab before javac, and not just spaces.</b>
-Finally, add the line which explains how to create BlinkToRadioMsg.java:</p>
-
-<pre>
-BlinkToRadioMsg.java:
-        mig java -target=null -java-classname=BlinkToRadioMsg BlinkToRadio.h BlinkToRadioMsg -o $@
-</pre>
-
-<p>As with javac, there must be a tab (not spaces) before mig. 
-Now, when you type <code>make</code> in <code>BlinkToRadio/</code>, 
-the make system will compile BlinkToRadioMsg.class, a Java class
-that parses a binary packet into message fields that can be accessed
-through methods.</p>
-
-<p>There is one more step, however. When you compiled, you probably saw this warning:
-
-<pre>
-warning: Cannot determine AM type for BlinkToRadioMsg
-         (Looking for definition of AM_BLINKTORADIOMSG)
-</pre>
-
-<p>One part of the TinyOS communication toolchain requires being able to
-figure out which AM types correspond to what kinds of packets.
-To determine this, for a packet type named X, mig looks for a constant
-of the form <code>AM_X</code>. The warning is because we defined our
-AM type as AM_BLINKTORADIO, but mig wants AM_BLINKTORADIOMSG. Modify
-BlinkToRadio.h so that it defines the latter. You'll also need to
-update BlinkToRadioAppC.nc so that the arguments to AMSenderC
-and AMReceiverC use it. Recompile the application, and you should
-see no warning. Install it on a mote.</p>
-
-<p>Now that we have a Java message class, we can use it to
-print out the messages we see from the BaseStation. With 
-BaseStation plugged into the serial port and BlinkToRadio
-running on another mote, from the BlinkToRadio directory
-type</p>
-
-<pre>
-java net.tinyos.tools.MsgReader BlinkToRadioMsg
-</pre>
-
-<p>Now, when the BaseStation sends a packet to the serial
-port, MsgReader reads it, looks at its AM type, and if
-it matches the AM type of one of the Java message classes
-passed at the command line, it prints out the packet. You
-should see output like this:</p>
-
-<pre>
-1152232617609: Message <BlinkToRadioMsg>
-  [nodeid=0x2]
-  [counter=0x1049]
-
-1152232617609: Message <BlinkToRadioMsg>
-  [nodeid=0x2]
-  [counter=0x104a]
-
-1152232617609: Message <BlinkToRadioMsg>
-  [nodeid=0x2]
-  [counter=0x104b]
-
-1152232617621: Message <BlinkToRadioMsg>
-  [nodeid=0x2]
-  [counter=0x104c]
-</pre>
-
-<h1>SerialForwarder and other packet sources</h1>
-
-<p>One problem with directly using the serial port is that
-only one PC program can interact with the mote. Additionally,
-it requires you to run the application on the PC which is
-physically connected to the mote. The SerialForwarder tool
-is a simple way to remove both of these limitations.</p>
-
-<p>Most generally, the <tt>SerialForwarder</tt> program 
-opens a packet source and lets many applications connect
-to it over a TCP/IP stream in order to use that source. 
-For example, you can run a SerialForwarder whose packet
-source is the serial port; instead of connecting to the
-serial port directly, applications connect to the 
-SerialForwarder, which acts as a proxy to read and write
-packets. Since applications connect to SerialForwarder
-over TCP/IP, applications can connect over the Internet.</p>
-
-<p>SerialForwarder is the second kind of packet source.
-A SerialForwarder source has this syntax:</p>
-
-<pre>
-sf@HOST:PORT
-</pre>
-
-<p>HOST and PORT are optional: they default to localhost (the
-local machine) and 9002. For example,</p>
-
-<pre>
-sf@dark.cs.berkeley.edu:1948
-</pre> 
-
-<p>will connect to a SerialForwarder running on the computer
-dark.cs.berkeley.edu and port 1948.</p>
-
-<p>The first step is to run a SerialForwarder; since it
-takes one packet source and exports it as an sf source,
-it takes a packet source parameter just like the other
-tools we've used so far: you can pass a -comm parameter,
-use MOTECOM, or just rely on the default. Close your
-MsgReader application so that it no longer uses
-the serial port, and run a SerialForwarder:</p>
-
-<pre>
-java net.tinyos.sf.SerialForwarder
-</pre>
-
-<p>You should see a window like this pop up:
-
-<center>
-<p><img height="300" width="500" src="img/sf.gif"></p>
-</center>
-
-<p>Since SerialForwarder takes any packet source as its source, you
-can even string SerialForwaders along:</p>
-
-<pre>
-java net.tinyos.sf.SerialForwarder -port 9003 -comm sf@localhost:9002
-</pre>
-
-<p>This command opens a second SerialForwarder, whose source is the first
-SerialForwarder. You'll see that the client count of the first one has
-increased to one. It's rare that you'd ever want to do this, but it
-demonstrates that in the message support libraries you can 
-use a variety of packet sources.</p>
-
-<p>Close the second SerialForwarder (the one listening on port 9003).
-Run MsgReader again, but this time tell it to connect to your
-SerialForwarder:</p>
-
-<pre>
-java net.tinyos.tools.MsgReader -comm sf@localhost:9002 BlinkToRadioMsg
-</pre>
-
-<p>You will see the client count increment, and MsgReader will start
-printing out packets.</p>
-
-<h2>Packet Sources</h2>
-
-<p>In addition to serial ports and SerialForwarders, the TinyOS
-messaging library supports a third packet source, motes which
-are connected to an ethernet port through a Crossbow MIB 600 
-ethernet board. This is the full
-set of packet sources:
-
-<br>
-<center>
-<table>
-<tr>
-<td><b>Syntax</b></td>
-<td width=100></td>
-<td><b>Source</b></td>
-</tr>
-<tr>
-<td>serial@PORT:SPEED</td>
-<td></td>
-<td>Serial ports</td>
-</tr>
-<tr>
-<td>sf@HOST:PORT</td>
-<td></td>
-<td>SerialForwarder, TMote Connect</td>
-</tr>
-<tr>
-<td>network@HOST:PORT</td>
-<td></td>
-<td>MIB 600</td>
-</tr>
-</table>
-</center>
-
-<p>In the <code>network</code> packet source, the default MIB 600 port
-is 10002. The Moteiv TMote Connect appliance is a SerialForwarder
-packet source.</p>
-
-<h2>The tool side</h2>
-
-<p>Code for the Java messaging toolchain lives in two java packages:
-<code>net.tinyos.message</code> and <code>net.tinyos.packet</code>.
-The <code>packet</code> package contains all of the code for 
-packet sources and their protocols: it is what reads and writes
-bytes. The <code>message</code> package is what turns streams of
-bytes into meaningful messages and provides packet source independent
-classes for communicating with motes.</p>
-
-<p>The key class for sending and receiving packets is <code>MoteIF</code>.
-It has methods for registering packet listeners (callbacks when a packet
-arrives) and sending packets. The tools <code>MsgReader</code>,
-<code>Listen</code>, and <code>Send</code> are good places to start
-to learn how to get Java applications to communicate with motes.</p>
-
-<p>There is also support for python and C.</p>
-
-<h1>Sending a packet to the serial port in TinyOS</h1>
-
-<p>Sending an AM packet to the serial port in TinyOS is very
-much like sending it to the radio. A component uses the AMSend
-interface, calls <code>AMSend.send</code>, and handles
-<code>AMSend.sendDone</code>. The serial stack will send
-it over the serial port regardless of the AM address specified.</p>
-
-<p>The TinyOS serial stack follows the same programming model as the radio
-stack. There is a <code>SerialActiveMessageC</code> for turning
-the stack on and off (mote processors often cannot enter their
-lowest power state while the serial stack is on), and generic
-components for sending and receiving packets. As the serial
-stack is a dedicated link, however, it does not provide a
-snooping interface, and it does not filter based on the destination
-address of the packet. These are the serial communication components
-and their radio analogues:</p>
-
-<center>
-<table cellspacing=4 cellpadding=2>
-  <tr align=center><td bgcolor="#d0d0d0"><b>Serial</b></td><td width=10></td><td bgcolor="#d0d0ff"><b>Radio</b></td></tr>
-  <tr>
-    <td bgcolor="#d0d0d0">SerialActiveMessageC</td>
-    <td></td>
-    <td bgcolor="#d0d0ff">ActiveMessageC</td>
-  </tr>
-  <tr>
-    <td bgcolor="#d0d0d0">SerialAMSenderC</td>
-    <td></td>
-    <td bgcolor="#d0d0ff">AMSenderC</td>
-  </tr>
-  <tr>
-    <td bgcolor="#d0d0d0">SerialAMReceiverC</td>
-    <td></td>
-    <td bgcolor="#d0d0ff">AMReceiverC</td>
-  </tr>
-</table>
-</center>
-
-<p>Because serial AM communication has the same interfaces as radio
-AM communication, you can in most situations use them interchangably.
-For example, to make BlinkToRadio send packets to the serial port
-rather than the radio, all you have to do is change the
-BlinkToRadioAppC configuration:</p>
-
-<center>
-<table>
- <tr><td><b>Radio</b></td><td width=10></td><td><b>Serial</b></td></tr>
- <tr><td>
-<pre>
-  components ActiveMessageC;
-  components new AMSenderC(AM_BLINKTORADIOMSG);
-
-  BlinkToRadioC.AMSend -> AMSenderC;
-  BlinkToRadioC.AMControl -> ActiveMessageC;
-</pre>
-</td>
-<td></td>
-<td>
-<pre>
-  components SerialActiveMessageC;
-  components new SerialAMSenderC(AM_BLINKTORADIOMSG);
-
-  BlinkToRadioC.AMSend -> SerialAMSenderC;
-  BlinkToRadioC.AMControl -> SerialActiveMessageC;
-</pre>
-</td>
-</tr>
-</table>
-</center>
-</table>
-<br>
-<hr>
-
-<p>Now, rather than have BlinkToRadio send packets which a BaseStation
-recieves and forwards to the serial port, the application will
-send them directly to a serial port. Connect a MsgReader to test
-that this is happening. Note that the binary code and data size
-has changed significantly, as nesC has included the serial stack
-rather than the radio stack.</p>
-
-<h1>Related Documentation</h1>
-
-<ul>
-<li> <a name="fn1"><a href="../tep113.html">TEP 113: Serial Communication</a></a>
-<li> <code>mig</code> man page
-<li> <code>ncg</code> man page
-<li> javadoc documentation for the net.tinyos.packet and net.tinyos.message packages
-</ul>
-
-<center>
-<p>&lt;&nbsp;<b><a href="lesson3.html">Previous Lesson</a></b> |&nbsp; <b><a
- href="index.html">Top</a></b> &nbsp;|&nbsp; <b><a href="lesson5.html">Next Lesson </a>&nbsp;&gt;</b>
-</center>
-
-                       
-<h1>CLASSPATH and Java classes</h1>
-                       
-<p>Note that the CLASSPATH variable points to <tt>tinyos.jar</tt>. This
-means that when Java looks for classes to load, it looks in tinyos.jar rather
-than the Java directories in <tt>support/sdk/java</tt>. Therefore,
-if you change and recompile the Java classes, you will not see the changes,
-as Java will only look at the jar file. To regenerate the
-jar from the Java code, go to <tt>support/sdk/java</tt> and type
-<tt>make tinyos.jar</tt>.
+<p>Sorry, your browser does not support frames. Please <a href="http://docs.tinyos.net/index.php/Mote-PC_serial_communication_and_SerialForwarder" target="_top">go here</a>.</p>
 </body>
-</html>
-
+</noframes>
+</frameset>
+</html>
\ No newline at end of file
index d6ac345e143bcb59f640c81a2412e51819075d4c..b2abe6489fd567480cd7d4f79da77b2a474855c0 100644 (file)
-<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
-<html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" ^M   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
-  <title>Lesson 5: Sensing</title>
-  <link href="../../stylesheets/tutorial.css" rel="stylesheet" type="text/css">
+<title>klueska.com</title>
 </head>
+<frameset>
+<frame src="http://docs.tinyos.net/index.php/Sensing" name="redir_frame" />
+<noframes>
 <body>
-
-<!-- $Id$ -->
-
-<div class="title">Lesson 5: Sensing</div>
-<div class="subtitle">Last Modified: 16 June 2006</div>
-
-<p> This lesson introduces sensor data acquisition in TinyOS. It demonstrates
-two sensor applications: a simple application called <a href="#sense">Sense</a>
-that periodically takes sensor readings and displays the values on the LEDs.
-And a more sophisticated application called <a
-href="#oscilloscope">Oscilloscope</a> where nodes periodically broadcast their
-sensor readings to a basestation node. Using the Mote-PC serial communication
-described in the <a href="lesson4.html">previous lesson</a> the basestation
-forwards the sensor readings to the PC, where they are visualized with a
-dedicated graphical user interface.  
-
-<a name="introduction"><h1>Introduction</h1></a>
-
-<p> Sensing is an integral part of sensor network applications. In TinyOS 1.x
-sensing was syntactically connected with analog-to-digital converters (ADCs):
-TinyOS 1.x applications such as <code>Oscilloscope</code> or <code>Sense</code>
-used the <code>ADC</code> and <code>ADCControl</code> interfaces to collect
-sensor data. When new platforms appeared with sensors that were read out via
-the serial interface, not only did additional interfaces like
-<code>ADCError</code> have to be introduced, but it became clear that equating
-a sensor with an ADC was not always the appropriate thing to do.
-
-<p> Usually sensing involves two tasks: configuring a sensor (and/or the
-hardware module it is attached to, for example the ADC or SPI bus) and reading
-the sensor data.  The first task is tricky, because a sensing application like,
-for example, <code>Sense</code> is meant to run on any TinyOS platform. How can
-<code>Sense</code> know the configuration details (like ADC input channel, the
-required reference voltage, etc.) of an attached sensor? It can't, because the
-configuration details of sensors will be different from platform to platform.
-Unless <code>Sense</code> knows about all sensors on all platforms it will be
-unable to perform the configuration task.  However, the second task - reading
-the sensor data - can be solved so that the <code>Sense</code> application can
-collect sensor data even though it is agnostic to the platform it is running
-on. 
-
-<p> In TinyOS 2.0 <i>platform independent</i> sensing applications such as
-<code>Oscilloscope</code>, <code>Sense</code> or <code>RadioSenseToLeds</code>
-do not use configuration interfaces like <code>ADCControl</code> anymore;
-instead they use the standard data acquisition interfaces
-<code>Read</code>, <code>ReadStream</code> or <code>ReadNow</code> for
-collecting sensor data. All configuration details are hidden from the
-application and this is why you can compile <code>Sense</code> and display
-sensor data on the <i>telosb</i> or the <i>micaz</i> platform, even though the
-actual sensors and their connection to the rest of the system may be completely
-different.
-
-<p> This raises questions like the following:
-
-<ul>
-
-<li> Since the <code>Sense</code> application component only uses standard
-data acquisition interfaces who is in charge of defining which sensor it samples?
-
-<li> If the <code>Sense</code> application component is not configuring the
-sensor, then who is responsible for that?
-
-<li> How can an applications like <code>Sense</code> display sensor data when they
-do not know the details about sensor configuration? This includes questions
-like "what is the value range of the sensor data" or "is a temperature reading
-to be interpreted in degrees Celsius or Fahrenheit"?
-
-<li> Let's assume there are several sensors on a platform: what steps have to
-be taken to let the <code>Sense</code> or <code>Oscilloscope</code> application
-display data from a different sensor?
-
-</ul> 
-
-<p> After reading this tutorial you should be able to answer these questions.
-Using the <code>Sense</code> and <code>Oscilloscope</code> application as an
-example, the following sections explain how the data acquisition interfaces are
-used, how the configuration procedure works and, as an example, how
-<code>Sense</code> can be hooked up to sensors other than the default one on
-the <i>telosb</i> platform.
-
-<a name="sense"><h1>The Sense application</h1></a>
-
-<code>Sense</code> is a simple sensing demo application. It periodically
-samples the default sensor and displays the bottom bits of the readings on the
-LEDs. The <code>Sense</code> application can be found in
-<code>tinyos-2.x/apps/Sense</code>.  Let's first look at the <code><a
-href="../../../apps/Sense/SenseAppC.nc">SenseAppC.nc</a></code> configuration:
-
-<pre>
-configuration SenseAppC 
-{ 
-} 
-implementation { 
-  components SenseC, MainC, LedsC, new TimerMilliC();
-  components new DemoSensorC() as Sensor;
-
-  SenseC.Boot -> MainC;
-  SenseC.Leds -> LedsC;
-  SenseC.Timer -> TimerMilliC;
-  SenseC.Read -> Sensor;
-}
-</pre>
-
-The <code>SenseAppC</code> configuration looks similar to the
-<code>BlinkAppC</code> configuration described in <a href="lesson1.html">lesson
-1</a> (if you have not done so, read the sections on the Blink application in
-lesson 1). To understand the wiring let's look at the signature of the <code><a
-href="../../../apps/Sense/SenseC.nc">SenseC.nc</a></code> module:
-
-<pre>
-module SenseC
-{
-  uses {
-    interface Boot;
-    interface Leds;
-    interface Timer&lt;TMilli&gt;;
-    interface Read&lt;uint16_t&gt;;
-  }
-} 
-</pre>
-
-Like the <code>BlinkC.nc</code> module the <code>SenseC.nc</code> module uses
-the interfaces <code>Boot</code>, <code>Leds</code> and
-<code>Timer&lt;TMilli&gt;</code>. Additionally, it uses the
-<code>Read&lt;uint16_t&gt;</code> interface. The       sequence of actions in the
-<code>SenseC.nc</code> implementation is as follows: <code>SenseC.nc</code>
-uses the <code>Boot</code> interface to start a periodic timer after the system
-has been initialized. Every time the timer expires <code>SenseC.nc</code> is
-signalled a timer event and reads data via the
-<code>Read&lt;uint16_t&gt;</code> interface. Reading data is a split-phase
-operation, it is divided in a command <code>Read.read()</code> and an event
-<code>Read.readDone()</code>. Thus every time the timer expires
-<code>SenseC.nc</code> calls <code>Read.read()</code> and waits for the
-<code>Read.readDone()</code> event. When data is signalled in the
-<code>Read.readDone()</code> event <code>SenseC.nc</code> displays it on the
-leds: the least significant bit is displayed on LED 0 (0 = off, 1 = on), the
-second least significant bit is displayed on LED 1 and so on. <p> The <code><a
-href="../../../tos/interfaces/Read.nc">Read</a></code> interface (in
-<code>tinyos-2.x/tos/interfaces</code>) can be used to read a single piece of
-sensor data, let's look at it in detail:
-
-<pre>
-interface Read&lt;val_t&gt; {
-  /**
-   * Initiates a read of the value.
-   *
-   * @return SUCCESS if a readDone() event will eventually come back.
-   */
-  command error_t read();
-
-  /**
-   * Signals the completion of the read().
-   *
-   * @param result SUCCESS if the read() was successful
-   * @param val the value that has been read
-   */
-  event void readDone( error_t result, val_t val );
-}
-</pre>
-
-If you are not familiar with generic interfaces you will wonder what the
-meaning of <code>&lt;val_t&gt;</code> (in the first line) is and why the
-signature of <code>SenseC.nc</code> is using <code>Read&lt;uint16_t&gt;</code>.
-What you see above is a <i>generic interface definition</i>, because the
-<code>Read</code> interface takes a type parameter. Generic interfaces are
-explained in the nesC Language Reference Manual (version 1.2 and above).
-For now it is enough to know that generic interfaces have at least one type
-parameter and two components can be wired together only if they provide/use the
-interface with the same types (note that the <code>readDone</code> event passes
-a parameter of the <code>&lt;val_t&gt;</code> parameter, which is a placeholder
-for the actual data type). This means that since <code>SenseC.nc</code> is
-using the <code>uint16_t</code> variant of the <code>Read</code> interface, it
-can only be wired to a component that provides the
-<code>Read&lt;uint16_t&gt;</code> interface and thus <code>SenseC.nc</code>
-expects to read 16 bit unsigned integer sensor data.  If you tried to wire
-<code>SenseC.nc</code> to a component that provides, for example, a
-<code>Read&lt;uint8_t&gt;</code> interface you would get an error from the
-nesC compiler. 
-
-<p>Recall that the wiring is defined in the <code>SenseAppC.nc</code>
-configuration. Let's again take a look at which component <code>SenseC.nc</code>
-is wired to using the <code>Read&lt;uint16_t&gt;</code> interface in the
-<code>SenseAppC</code> configuration. The interesting lines are
-
-<pre>
-  components new DemoSensorC() as Sensor;
-</pre>
-and
-<pre>
-  SenseC.Read -> Sensor;
-</pre>
-
-This means that the <i>generic</i> <code>DemoSensorC</code> component provides
-the <code>Read&lt;uint16_t&gt;</code> interface to <code>SenseC.nc</code>
-
-<p> It is important to understand that the <code>SenseC.nc</code> module has no
-way of telling which sensor it is connected to; in fact it cannot even tell
-whether it is getting data from a sensor at all, because it can be wired to any
-component that provides a <code>Read&lt;uint16_t&gt;</code> interface. On a
-platform without any built-in sensors (like <i>micaz</i>) and no attached
-sensorboard the <code>DemoSensorC</code> component could simply return constant
-values. The last sentence hints that the <code>DemoSensorC</code> component is
-different for every platform: therefore you will not find
-<code>DemoSensorC.nc</code> in the TinyOS libraries. Instead, a different
-<code>DemoSensorC.nc</code> has to be written for every platform, i.e. the
-<code>DemoSensorC.nc</code> implementation for telosb will be different than
-the <code>DemoSensorC.nc</code> implementation for micaz.  This is the
-answer to the first question asked in the <a
-href="#introduction">introduction</a> section: the <i>platform dependent</i>
-<code>DemoSensorC</code> component defines which sensor the <code>Sense</code>
-or <code>Oscilloscope</code> application is sampling and every platform that
-wants to run sensing applications such as <code>Oscilloscope</code>,
-<code>Sense</code> or <code>RadioSenseToLeds</code> has to provide its own
-version of <code>DemoSensorC</code>. Additionally, sensor boards may come
-with their own version of <code>DemoSensorC</code> (e.g., the 
-<code>basicsb</code> sensorboard for the mica-family of motes define 
-<code>DemoSensorC.nc</code> to be that board's light sensor).
-
-<a name="demosensorc"><h2>The DemoSensorC component</h2></a>
-
-<p> Let's take a closer look at the <code>DemoSensorC</code> component. Every
-<code>DemoSensorC</code> component has the following signature:
-
-<pre>
-generic configuration DemoSensorC()
-{
-  provides interface Read&lt;uint16_t&gt;;
-}
-</pre>
-
-In its implementation section, however, <code>DemoSensorC</code> may differ
-from platform to platform. For example, on the <i>telosb</i> platform
-<code>DemoSensorC</code> instantiates a component called <code>VoltageC</code>,
-which reads data from the MCU-internal voltage sensor. Because the <i>micaz</i>
-doesn't have any built-in sensors its <code>DemoSensorC</code> uses system
-library component like <code>ConstantSensorC</code> or
-<code>SineSensorC</code>, which return "fake" sensor data. Thus
-<code>DemoSensorC</code> is a means of indirecting sensor data acquisition from
-a platform-specific sensor component (like <code>VoltageC</code>) to
-platform-independent applications like <code>Sense</code> or
-<code>Oscilloscope</code>. Usually the configuration of a sensor is done in the
-component that <code>DemoSensorC</code> instantiates.
-
-<p> How can <code>Sense</code> be changed to sample a sensor other than the platform's
-default sensor? Usually this requires changing only a single line of code in
-<code>DemoSensorC</code>; for example, if you wanted to replace the
-<code>VoltageC</code> component on <i>telosb</i> by the constant sensor
-component <code>ConstantSensorC</code> you could change the follwoing line in
-<code>DemoSensorC</code> from:
-
-<pre>
-components new VoltageC() as DemoSensor;
-</pre>
-to something like
-<pre>
-components new ConstantSensorC(uint16_t, 0xbeef) as DemoSensor;
-</pre>
-
-What sensors are available depends on the platform. Sensor components are
-usually located in the respective platform subdirectory
-(<code>tinyos-2.x/tos/platforms</code>), in the respective sensorboard
-subdirectory (<code>tinyos-2.x/tos/sensorboards</code>) or, in case of
-microprocessor-internal sensors, in the respective chips subdirectory
-(<code>tinyos-2.x/tos/chips</code>). <code>ConstantSensorC</code> and
-<code>SineSensorC</code> can be found in <code>tinyos-2.x/tos/system</code>.
-
-
-<h2>Running the Sense application</h2>
-
-To compile the <code>Sense</code> application, go to the
-<code>apps/Sense</code> directory and depending on which hardware you have,
-type something similar to <code>make telosb install</code>.  If you get errors such as 
-the following,
-
-<pre>
-SenseAppC.nc:50: component DemoSensorC not found
-SenseAppC.nc:50: component `DemoSensorC' is not generic
-SenseAppC.nc:55: no match
-</pre>
-
-your platform has not yet implemented the <code>DemoSensorC</code> component.
-For a quick solution you can copy <code>DemoSensorC.nc</code> from
-<code>tinyos-2.x/tos/platforms/micaz</code> to your platform directory (a good
-starting point on how to create sensor components is probably <a
-  href="../tep101.html">TEP 101</a> and <a href="../tep114.html">TEP 114</a>). 
-
-<p>If you have a mica-family mote and a "basic" (mda100) sensor board, you
-can get a more interesting test by compiling with
-<pre>
-SENSORBOARD=basicsb make <i>platform</i> install
-</pre>
-to run <code>Sense</code> using the mda100's light sensor.
-
-<p> Once you have installed the application the three least significant bits of
-the sensor readings are displayed on the node's LEDs (0 = off, 1 = on). It is
-the least significant bits, because <code>Sense</code> cannot know the
-precision (value range) of the returned sensor readings and, for example, the
-three most significant bits in a <code>uint16_t</code> sensor reading sampled
-through a 12-bit ADC would be meaningless (unless the value was left-shifted).
-If your <code>DemoSensorC</code> represents a sensor whose readings are
-fluctuating you may see the LEDs toggle, otherwise <code>Sense</code> is not
-very impressive.  Let's take a look at a more interesting application:
-<code>Oscilloscope</code>.
-
-<a name="oscilloscope"><h1>The Oscilloscope application</h1></a>
-
-<code>Oscilloscope</code> is an application that let's you visualize sensor
-readings on the PC. Every node that has <code>Oscilloscope</code> installed
-periodically samples the default sensor (<a href="#demosensorc">via
-<code>DemoSensorC</code></a>) and broadcasts a message with 10 accumulated
-readings over the radio. A node running the <code>BaseStation</code>
-application will forward these messages to the PC using the serial
-communication. To run <code>Oscilloscope</code> you therefore need at least two
-nodes: one node attached to your PC running the <code>BaseStation</code>
-application (<code>BaseStation</code> can be found at
-<code>tinyos-2.x/apps/BaseStation</code> and was introduced in the <a
-href="lesson4.html">previous lesson</a>) and one or more nodes running the
-<code>Oscilloscope</code> application. 
-
-<p> Let's take a look at the <code><a
-href="../../../apps/Oscilloscope/OscilloscopeAppC.nc">OscilloscopeAppC.nc</a></code>
-configuration:
-
-<pre>
-configuration OscilloscopeAppC 
-{ 
-}
-implementation
-{
-  components OscilloscopeC, MainC, ActiveMessageC, LedsC,
-    new TimerMilliC(), new DemoSensorC() as Sensor,
-    new AMSenderC(AM_OSCILLOSCOPE), new AMReceiverC(AM_OSCILLOSCOPE);
-
-  OscilloscopeC.Boot -> MainC;
-  OscilloscopeC.RadioControl -> ActiveMessageC;
-  OscilloscopeC.AMSend -> AMSenderC;
-  OscilloscopeC.Receive -> AMReceiverC;
-  OscilloscopeC.Timer -> TimerMilliC;
-  OscilloscopeC.Read -> Sensor;
-  OscilloscopeC.Leds -> LedsC;
-}
-</pre>
-
-The actual implementation of the application is in <code><a
-href="../../../apps/Oscilloscope/OscilloscopeC.nc">OscilloscopeC.nc</a></code>.
-This is the signature of <code>OscilloscopeC.nc</code>:
-
-<pre>
-module OscilloscopeC
-{
-  uses {
-    interface Boot;
-    interface SplitControl as RadioControl;
-    interface AMSend;
-    interface Receive;
-    interface Timer<TMilli>;
-    interface Read<uint16_t>;
-    interface Leds;
-  }
-}
-</pre>
-
-<code>Oscilloscope</code> is a combination of different building blocks
-introduced in previous parts of the tutorial. Like <a
-  href="#sense"><code>Sense</code></a>,  <code>Oscilloscope</code> uses
-<code>DemoSensorC</code> and a timer to periodically sample the default sensor
-of a platform. When it has gathered 10 sensor readings
-<code>OscilloscopeC</code> puts them into a message and broadcasts that message
-via the <code>AMSend</code> interface.  <code>OscilloscopeC</code> uses the
-<code>Receive</code> interface for synchronization purposes (see below) and the
-<code>SplitControl</code> interface, to switch the radio on. If you want to
-know more about mote-mote radio communication read <a
-  href="lesson3.html">lesson 3</a>.
-
-<h2>Running the Oscilloscope application</h2>
-
-To install the <code>Oscilloscope</code> application go to
-<code>tinyos-2.x/apps/Oscilloscope</code> and depending on which hardware you
-have, type something similar to <code>make telosb install,1</code>. Note the "<code>,1</code>"
-after the <code>install</code> option, which assigns ID 1 to the node.
-Assigning IDs to nodes is helpful to differentiate them later on in the GUI, so
-make sure you assign different IDs to all nodes on which
-<code>Oscilloscope</code> is installed (e.g. install <code>Oscilloscope</code>
-on a second node with <code>make telosb install,2</code> and so on). A node
-running <code>Oscilloscope</code> will toggle its second LED for every message
-it has sent and it will toggle its third LED when it has received an
-<code>Oscilloscope</code> message from another node: incoming messages are used
-for sequence number synchronization to let nodes catch up when they are
-switched on later than the others; they are also used for changing the sample
-rate that defines how often sensor values are read. In case of a problem with
-the radio connection the first LED will toggle. 
-
-<p> Install <code>BaseStation</code> on another node and connect it to your PC.
-As usual, on the <code>BaseStation</code> node you should see the second LED
-toggle for every message bridged from radio to serial.
-
-
-<h2>Running the Java GUI</h2>
-
-To visualize the sensor readings on your PC first go to
-<code>tinyos-2.x/apps/Oscilloscope/java</code> and type <code>make</code>. This
-creates/compiles the necessary message classes and the
-<code>Oscilloscope</code> Java GUI. Now start a SerialForwarder and make sure
-it connects to the node on which you have installed the
-<code>BaseStation</code> application (how this is done is explained in the <a
-  href="lesson4.html">previous lesson</a>). In case you have problems with the
-Java compilation or the serial connection work through the <a
-  href="lesson4.html">previous lesson</a>. 
-
-<p>Once you have a SerialForwarder running you can start the GUI by typing
-<code>./run</code> (in <code>tinyos-2.x/apps/Oscilloscope/java</code>). You
-should see a window similar to the one below:
-
-<p>
-<CENTER>
-  <IMG SRC="img/oscilloscope.jpg">
-</CENTER>
-</p>
-
-Each node is represented by a line of different color (you can change the color
-by clicking on it in the mote table). The x-axis is the packet counter number
-and the y-axis is the sensor reading. To change the sample rate edit the
-number in the "sample rate" input box. When you press enter, a message
-containing the new rate is created and broadcast via the
-<code>BaseStation</code> node to all nodes in the network. You can clear all
-received data on the graphical display by clicking on the "clear data" button.
-
-<p> The <code>Oscilloscope</code> (or <code>Sense</code>) application displays
-the raw data as signalled by the <code>Read.readDone()</code> event. How the
-values are to be interpreted is out of scope of the application, but the GUI
-let's you adapt the visible portion of the y-axis to a plausible range (at the
-bottom right).
-
-<p>
-<a name="related_docs">
-<h1>Related Documentation</h1>
-</a>
-</p><ul>
-<li> <a href="http://nescc.sourceforge.net/papers/nesc-ref.pdf">nesC reference manual</a>
-</li><li> <a href="../tep101.html">TEP 101: ADC</a>
-</li><li> <a href="../tep114.html">TEP 114: SIDs: Source and Sink Independent Drivers</a>
-</li><li> <a href="http://csl.stanford.edu/%7Epal/pubs/tinyos-programming-1-0.pdf">TinyOS Programming Guide</a>
-</li></ul>
-
-
-<!-- Begin footer -->
-<br>
-<hr>
-<center>
-<p>&lt;&nbsp;<b><a href="lesson4.html">Previous Lesson</a></b> |&nbsp; <b><a
- href="index.html">Top</a></b> &nbsp;|&nbsp; <b><a href="lesson6.html">Next Lesson </a>&nbsp;&gt;</b>
-</center>
-
+<p>Sorry, your browser does not support frames. Please <a href="http://docs.tinyos.net/index.php/Sensing" target="_top">go here</a>.</p>
 </body>
-</html>
+</noframes>
+</frameset>
+</html>
\ No newline at end of file
index 3af80d7b51fe5d7915cb60d76c0884322a351cbc..bbf0cbe974873582b6351cce106cc8e0bebfab81 100644 (file)
-<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
-<html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" ^M   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
-  <title>TinyOS Tutorial Lesson 6: TinyOS Boot and System Initialization</title>
-  <link href="../../stylesheets/tutorial.css" rel="stylesheet" type="text/css">
+<title>klueska.com</title>
 </head>
+<frameset>
+<frame src="http://docs.tinyos.net/index.php/Boot_Sequence" name="redir_frame" />
+<noframes>
 <body>
-
-<div class="title">Lesson 6: TinyOS Boot and System Initialization</div>
-<div class="subtitle">Last updated 30 October 2006</div>
-
-<h1>Introduction</h1>      
-<p>One of the frequently asked questions regarding TinyOS is, "Where is
-       <code>main()</code>?".  In previous lessons, we deferred detailed
-       discussion of the TinyOS boot sequence: applications handle the
-       <tt>Boot.booted</tt> event and start from there. This tutorial
-       describes the steps that occur before and after this event,
-       showing how to properly initialize components.</p>
-
-<h1>Boot Sequence</h1>
-<p>The TinyOS boot sequence has four steps:
-      <ol> 
-       <li> Scheduler initialization</li>
-       <li> Component initialization</li>
-       <li> Signal that the boot process has completed</li>
-       <li> Run the scheduler</li>
-      </ol>
-
-       The application-level boot sequence component is <tt>MainC</tt> (in tos/system).
-       MainC provides one interface, <tt>Boot</tt> and uses one interface,
-       <tt>Init as SoftwareInit</tt>. The boot sequence calls SoftwareInit.init() as
-       part of step 2 and signals Boot.booted in step 3.</p>
-
-      <p>The default real boot sequence is in the component <tt>RealMainP</tt>. Note
-       that its name ends in P, denoting that components should not directly wire to
-       it. This is RealMainP's signature:</p>
-
-      
-      <pre>
-  module RealMainP {
-    provides interface Booted;
-    uses {
-      interface Scheduler;
-      interface Init as PlatformInit;
-      interface Init as SoftwareInit;
-    }
-  }
-      </pre>
-      
-      <p>MainC only provides Boot and uses SoftwareInit; RealMainP uses
-       two additional interfaces, PlatformInit and Scheduler. MainC hides
-       these from applications by automatically wiring them to the system's
-       scheduler and platform initialization sequence. The difference between
-       PlatformInit and SoftwareInit is predominantly one of hardware vs. software.
-       PlatformInit is responsible for placing core platform services into
-       meaningful states; for example, the PlatformInit of mica platforms
-       calibrates their clocks.</p>
-
-      <p>This is the code of RealMainP:</p>
-
-      <pre>
-  implementation {
-    int main() __attribute__ ((C, spontaneous)) {
-      atomic {
-        call Scheduler.init();
-        call PlatformInit.init();
-        while (call Scheduler.runNextTask());
-        call SoftwareInit.init();
-        while (call Scheduler.runNextTask());
-      }
-      __nesc_enable_interrupt();
-      signal Boot.booted();
-      call Scheduler.taskLoop();
-      return -1;
-    }
-    default command error_t PlatformInit.init() { return SUCCESS; }
-    default command error_t SoftwareInit.init() { return SUCCESS; }
-    default event void Boot.booted() { }
-  }
-</pre>
-
-      <p>The code shows the four steps described above.</p>
-       
-<h2>Scheduler Initialization</h2>
-<p>
-The first boot step is to initialize the scheduler.
-If the scheduler were not
-initialized before the components, component initialization
-routines would not be able to post tasks. While not all components
-require tasks to be posted, this gives the flexibility required for
-       those components that do. The boot sequence runs tasks after each
-         initialization stage in order to allow long-running operations,
-         since they only happen once. <A HREF="../tep106.html">TEP 106</A>
-       describes TinyOS schedulers in greater detail, including information
-       on how to replace the scheduler.</p>
-
-
-<h2>Component initialization.</h2>
-
-<p>After RealMainP initializes the scheduler,
-it initializes the platform. The <code>Init</code> interface implements only
-the single command <code>init()</code>. </p>
-
-<pre></pre>
-<prehead>tos/interfaces/Init.nc:</prehead>
-<pre>
-
-interface Init {
-  command error_t init();
-}
-</pre>
-
-<p>The platform initialization phase is the responsability of the platform
-implementer. Thus, <code>PlatformInit</code> is wired to the
-platform-specific initialization component, <code>PlatformC</code>. No
-other component should be wired to <code>PlatformInit</code>.  Any
-component that requires initialization can implement the <code>Init</code>
-interface and wire itself to <code>MainC</code>'s <code>SoftwareInit</code>
-interface:
-
-<pre></pre>
-<prehead>tos/system/MainC.nc:</prehead>
-<pre>
-configuration MainC {
-  provides interface Boot;
-  uses interface Init as SoftwareInit;
-}
-implementation {
-  components PlatformC, RealMainP, TinySchedulerC;
-
-  RealMainP.Scheduler -> TinySchedulerC;
-  RealMainP.PlatformInit -> PlatformC;
-
-  // Export the SoftwareInit and Booted for applications
-  SoftwareInit = RealMainP.SoftwareInit;
-  Boot = RealMainP;
-}
-</pre>
-
-A common issue in initialization code is dependencies between different
-parts of the system. These are handled in three ways in TinyOS:
-<ul>
-<li> Hardware-specific initialization issues are handled directly by
-each platform's <code>PlatformC</code> component.
-
-<li> System services (e.g., the timer, the radio) are typically written to
-be independently initializable. For instance, a radio that uses a timer
-does not setup the timer at radio initialisation time, rather it defers
-that action until the radio is started. In other words, initialisation
-is used to setup software state, and hardware state wholly owned by
-the service.
-
-<li> When a service is split into several components, the <code>Init</code>
-interface for one of these components may well call <code>Init</code>
-(and other) interfaces of the other components forming the service,
-                 if a specific order is needed.
-</ul>
-
-<h2>Signal that the boot process has completed.</h2> 
-
-<p>Once all
-initialization has completed, <code>MainC</code>'s
-<code>Boot.booted()</code> event is signaled. Components are now free to
-call <code>start()</code> and other commands on any components they are
-using. Recall that in the <code>Blink</code> application, the timers were
-started from the <code>booted()</code> event. This <code>booted</code>
-event is TinyOS's analogue of <code>main</code> in a Unix application.</p>
-
-<h2>Run the scheduler loop.</h2> 
-<p>Once the application has been informed
-           that the system as booted and started needed services, TinyOS
-           enters its core scheduling loop. The scheduler runs as long
-             as there are tasks on the queue. As soon as it detects an empty
-             queue, the scheduler puts the microcontroller into the lowest
-             power state allowed by the active hardware resources. For example,
-             only having timers running usually allows a lower power state than
-             peripheral buses like the UART. <A HREF="../tep112.html">TEP 112</A>
-             describes in detail how this process works.</p>
-
-           <p>The processor goes to sleep until it handles an interrupt. When
-             an interrupt arrives, the MCU exits its sleep state and runs the
-             interrupt handler. This causes the scheduler loop to restart. If
-             the interrupt handler posted one or more tasks, the scheduler runs
-             tasks until the task queue and then returns to sleep.</p>
-
-
-           <h1>Boot and SoftwareInit</h1>
-
-           <p>From the perspective of an application or high-level services, the two
-             important interfaces in the boot sequence are those which MainC exports:
-             Boot and SoftwareInit. Boot is typically only handled by the top-level application:
-             it starts services like timers or the radio. SoftwareInit, in contrast,
-             touches many difference parts of the system. If a component needs code
-             that runs once to initialize its state or configuration, then it can wire
-             to SoftwareInit.</p>
-
-           <p>Typically, service components that require intialization wire themselves
-             to SoftwareInit rather than depend on the application writer to do so. When
-             an application developer is writing a large, complex system, keeping track of
-             all of the initialization routines can be difficult, and debugging when one
-             is not being called can be very difficult. To prevent bugs and simplify
-             application development, services typically use <i>auto-wiring</i>.</p>
-
-           <p>The term auto-wiring refers to when a component automatically wires its
-             dependencies rather than export them for the application writer to resolve.
-             In this case, rather than provide the Init interface, a service component
-             wires its Init interface to RealMainC. For example, <tt>PoolC</tt> is a generic
-             memory pool abstraction that allows you to declare a collection of memory
-             objects for dynamic allocation. Underneath, its implementation (<tt>PoolP</tt>)
-             needs to initialize its data structures. Given that this must happen for
-             the component to operate properly, an application writer shouldn't have to
-             worry about it. So the PoolC component instantiates a PoolP and wires it
-             to MainC.SoftwareInit:
-
-           <pre>
-generic configuration PoolC(typedef pool_t, uint8_t POOL_SIZE) {
-  provides interface Pool<pool_t>;
-} 
-
-implementation {
-  components MainC, new PoolP(pool_t, POOL_SIZE);
-
-  MainC.SoftwareInit -> PoolP;
-  Pool = PoolP;
-}
-</pre>
-
-             <p>In practice, this means that when MainP calls SoftwareInit.init,
-               it calls Init.init on a large number of components. In a typical large
-               application, the initialization sequence might involve as many as thirty
-               components. But the application developer doesn't have to worry about this:
-               properly written components take care of it automatically.</p>
-
-             
-<p>
-<a name=#related_docs>
-<h1>Related Documentation</h1>
-</a>
-<ul>
-<li> <a href="../tep106.html">TEP 106: Schedulers and Tasks</a>
-<li> <a href="../tep107.html">TEP 107: Boot Sequence</a>
-</ul>
-
-<p><b>Programming Hint 8:</b> 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.
-From <a href="../../pdf/tinyos-programming.pdf">
-<i>TinyOS Programming</i></a>
-
-<!-- Begin footer -->
-<br>
-<hr>
-<center>
-<p>&lt;&nbsp;<b><a href="lesson5.html">Previous Lesson</a></b> |&nbsp; <b><a
- href="index.html">Top</a></b> &nbsp;|&nbsp; <b><a href="lesson7.html">Next Lesson </a>&nbsp;&gt;</b>
-</center>
-
+<p>Sorry, your browser does not support frames. Please <a href="http://docs.tinyos.net/index.php/Boot_Sequence" target="_top">go here</a>.</p>
 </body>
-</html>
+</noframes>
+</frameset>
+</html>
\ No newline at end of file
index c23d97df57fb3134f60e1f40e09cc640b22ace4d..74ce0211a9600d1578821c861a8a02d8c1c2007f 100644 (file)
-<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
-<html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" ^M   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
-  <title>Lesson 7: Permanent Data Storage</title>
-  <link href="../../stylesheets/tutorial.css" rel="stylesheet" type="text/css">
+<title>klueska.com</title>
 </head>
+<frameset>
+<frame src="http://docs.tinyos.net/index.php/Storage" name="redir_frame" />
+<noframes>
 <body>
-
-<div class="title">Lesson 7: Permanent Data Storage</div>
-<div class="subtitle">Last Modified: April 13, 2007</div>
-
-<p>This lesson introduces permanent (non-volatile) data storage in
-TinyOS.  Permanent storage allows a node to persist data even if power
-is disconnected or the node is reprogrammed with a new image.  You
-will become familar with different kinds of data storage including
-small objects, logs, and large objects.  You will be exposed to the
-TinyOS interfaces and components that support permanent data storage
-on motes and you will learn how to:
-
-<p>
-
-<ul>
-
-<li>Divide the flash chip into volumes, which allows multiple and/or
-different type of data to be stored.
-
-<li>Store configuration data that survives a power cycle.
-
-<li>Store packets using the logging abstraction and retransmit the
-overheard packets after a power cycle.
-
-
-</ul>
-
-
-<h1>Introduction</h1>
-
-TinyOS 2.x provides three basic storage abstractions: small objects,
-circular logs, and large objects.  TinyOS 2.x also provides
-<i>interfaces</i> to abstract the underlying storage services and
-<i>components</i> that <i>provide</i> (implement) these interfaces.
-
-<h2>Interfaces</h2>
-
-Let's take a look at some of the interfaces that are in the
-<code>tos/interfaces</code> directory and the types defined in the
-<code>tos/types</code> to familiarize ourselves with the general
-functionality of the storage system:
-
-
-<p>
-<ul>
-
-<li><code>
-<a href="../../../tos/interfaces/BlockRead.nc">BlockRead</a></code> 
-
-<li><code>
-<a href="../../../tos/interfaces/BlockWrite.nc">BlockWrite</a></code>
-
-<li><code>
-<a href="../../../tos/interfaces/Mount.nc">Mount</a></code>
-
-<li><code>
-<a href="../../../tos/interfaces/ConfigStorage.nc">ConfigStorage</a></code>
-
-<li><code>
-<a href="../../../tos/interfaces/LogRead.nc">LogRead</a></code>
-
-<li><code>
-<a href="../../../tos/interfaces/LogWrite.nc">LogWrite</a></code>
-
-<li><code>
-<a href="../../../tos/types/Storage.h">Storage.h</a></code>
-
-
-</ul>
-
-<h2>Components</h2>
-
-<p>Components provide concrete implementations of the interfaces.  You
-should be familiar with these components because your code needs to
-specify both the <i>interfaces</i> your application
-<i>uses</i> as well as the <i>components</i> which <i>provide</i>
-(implement) these interfaces:
-
-<p>
-<ul>
-
-<li><code><a href="../../../tos/chips/stm25p/ConfigStorageC.nc">ConfigStorageC</a></code>
-
-<li><code><a href="../../../tos/chips/stm25p/LogStorageC.nc">LogStorageC</a></code>
-
-<li><code><a href="../../../tos/chips/stm25p/BlockStorageC.nc">BlockStorageC</a></code>
-
-</ul>
-
-<p>
-
-<h2>Implementations</h2>
-
-<p>The preceding components are actually <em>chip-specific
-implementations</em> of these abstractions.  Since TinyOS supports
-multiple platforms, each of which might have its own implementation of
-the storage drivers, you may need to be aware of platform-specific
-constants or other details (e.g. erase size) that can couple a storage
-client to the underlying chip-specific implementation.
-
-<p>For example, the preceding links are all specific to the ST
-Microelectronics M25Pxx family of flash memories used in the Telos and
-Tmote Sky motes.  You <em>do not</em> need to worry about the details
-of where these files reside because TinyOS's make system includes the
-correct drivers automatically.  However, you <em>do</em> need to know
-what these components are called because your code must list them in a
-<code>components</code> declaration.
-
-<p>If you are curious, the following links will let you browse the
-implementations of the Atmel AT45DB family of flash memories used in
-the Mica2/MicaZ motes:
-
-<p>
-<ul>
-
-<li><code><a href="../../../tos/chips/at45db/ConfigStorageC.nc">ConfigStorageC</a></code>
-
-<li><code><a href="../../../tos/chips/at45db/LogStorageC.nc">LogStorageC</a></code>
-
-<li><code><a href="../../../tos/chips/at45db/BlockStorageC.nc">BlockStorageC</a></code>
-
-</ul>
-
-<p>Finally, the following links will let you browse the implementation
-for the Intel imote2 flash memory:
-
-<p>
-<ul>
-
-<li><code><a href="../../../tos/platforms/intelmote2/ConfigStorageC.nc">ConfigStorageC</a></code>
-
-<li><code><a href="../../../tos/platforms/intelmote2/LogStorageC.nc">LogStorageC</a></code>
-
-<li><code><a href="../../../tos/platforms/intelmote2/BlockStorageC.nc">BlockStorageC</a></code>
-
-</ul>
-
-
-<h1>Volumes</h1>
-
-<p>TinyOS 2.x divides a flash chip into one or more fixed-sized
-<em>volume</em>s that are specified at compile-time using an XML file.
-This file, called the volume table, allows the application developer
-to specify the name, size, and (optionally) the base address of each
-volume in the flash.  Each volume provides a single type of storage
-abstraction (e.g. configuration, log, or block storage).  The
-abstraction type defines the physical layout of data on the flash
-memory.  A volume table might look like:
-
-<pre>
-&lt;volume_table&gt;
-  &lt;volume name="CONFIGLOG" size="65536"/&gt;
-  &lt;volume name="PACKETLOG" size="65536"/&gt;
-  &lt;volume name="SENSORLOG" size="131072"/&gt;
-  &lt;volume name="CAMERALOG" size="524288"/&gt;
-&lt;/volume_table&gt;
-</pre>
-
-<p>The volume table for a particular application must be placed in the
-application's directory (where one types 'make') and must be named
-<code>volumes-CHIPNAME.xml</code> where CHIPNAME is replaced with the
-platform-specific flash chip's name.  For example, the Telos mote uses
-the ST Microelectronics M25P family of flash memories.  The drivers
-for these chips can be found in the <code>tos/chips/stm25p</code>
-directory.  Therefore, a Telos-based application that uses the storage
-abstractions needs a file named <code>volumes-stm25p.xml</code>.
-
-<p>Note that the size parameter is a multiple of the erase unit for a
-particular flash chip.  See Section 4.1 in <a href="#fn1">TEP 103</a>
-for more details.
-
-<h1>Storing Configuration Data</h1>
-
-<p>This lesson shows how configuration data can be written to and read
-from non-volatile storage.  Configuration data typically exhibit some
-subset of the following properties.  They are <b>limited in size</b>,
-ranging from a fews tens to a couple hundred bytes.  Their values may
-be <b>non-uniform</b> across nodes.  Sometimes, their values are
-<b>unknown</b> prior to deployment in the field and sometimes their
-values are <b>hardware-specific</b>, rather than being tied to the
-software running on a node.
-
-<p>Because configuration data can be non-uniform across nodes or
-unknown <em>a priori</em>, their values may be difficult to specify at
-compile-time and since the data are sometimes hardware-specific, their
-values must survive reprogramming, suggesting that encoding these
-values in the program image is not the simplest approach.  Storing
-configuration data in volatile memory is also problematic since this
-data would not survive a reset or power cycle.
-
-<p>In summary, configuration data must persist through node resets,
-power cycles, or reprogramming, and then be restored afterward.  The
-ability to persist and restore configuration data in this manner is
-useful in many scenarios.
-
-<p><ul>
-
-<li><b>Calibration.</b> Calibration coefficients for sensors might be
-factory-configured and persisted, so they are not lost when power is
-removed for shipping or the node is reprogrammed post-calibration.
-For example, a hypothetical temperature sensor might have an offset
-and gain that must be calibrated, because these parameters are
-hardware-specific, and stored because they are needed to convert the
-output voltage into the more useful units of degrees Celcius.  The
-calibration data for such a sensor might look like:
-
-<pre>
-typedef struct calibration_config_t {
-  int16_t temp_offset;
-  int16_t temp_gain;
-} calibration_config_t;
-</pre>
-
-<li><b>Identification.</b> Device identification information, like
-IEEE-compliant MAC addresses or the TinyOS TOS_NODE_ID parameters are
-non-uniform across nodes although they are not hardware-specific, once
-they are assigned to a node, these values should be <em>sticky</em> in
-that they are persisted across reset, power cycle, and reprogramming
-operations (and not lost or reassigned to another node).
-
-<pre>
-typedef struct radio_config_t {
-  ieee_mac_addr_t mac;
-  uint16_t tos_node_id;
-} radio_config_t;
-</pre>
-
-<li><b>Location.</b> Node location data may be unknown at compile-time
-and only become available during deployment.  An application might,
-for example, store node coordinates as follows and update these values
-in the field:
-
-<pre>
-typedef struct coord_config_t {
-  uint16_t x;
-  uint16_t y;
-  uint16_t z;
-} coord_config_t;
-</pre>
-
-<li><b>Sensing.</b> Sensing and signal processing parameters like
-sample period, filter coefficients, and detection thresholds might be
-adjusted in the field.  The configuration data for such an application
-might look like:
-
-<pre>
-typedef struct sense_config_t {
-  uint16_t temp_sample_period_milli;
-  uint16_t temp_ema_alpha_numerator;
-  uint16_t temp_ema_alpha_denominator;
-  uint16_t temp_high_threshold;
-  uint16_t temp_low_threshold;
-} sense_config_t;
-</pre>
-
-</ul>
-
-<p>
-
-
-Now that we have discussed <i>why</i> one might use this type of
-storage, let's see <i>how</i> to use it.  We will implement a simple
-demo application that illustrates how to use the <code>Mount</code>
-and <code>ConfigStorage</code> abstractions.  A timer period will be
-read from flash, divided by two, and written back to flash.  An LED is
-toggled each time the timer fires.  But, before diving into code,
-let's discuss some high-level design considerations.
-
-<p>
-See <a href="../../../apps/tutorials/BlinkConfig/">
-<code>tinyos-2.x/apps/tutorials/BlinkConfig/</code></a> for the
-accompanying code.
-
-<p>
-
-Prior to its first usage, a volume does not contain any valid data.
-So, our code should detect the first usage of a volume and take any
-appropriate actions (e.g. preload it with default values).  Similarly,
-when the data layout of the volume changes (for example, if the
-application requires new or different configuration variables), then
-application code should detect this and take appropriate actions
-(e.g. migrate the old data to the new layout or erase the volume and
-reload the defaults).  These requirements suggest that we should have
-a way of keeping track of the volume version.  We will use a version
-number for this purpose (and will need to maintain a discipline of
-updating the version number when the data layout changes
-incompatibly).  Our configuration struct might have the following
-fields for the version number and blink period:
-
-<pre>
-typedef struct config_t {
-  uint16_t version;
-  uint16_t period;
-} config_t;
-</pre>
-
-<p>
-
-
-<ol>
-
-<li>Create a <code>volumes-CHIPNAME.xml</code> file, enter the volume
-table in this file, and place the file in the application directory.
-Note that <code>CHIPNAME</code> is the flash chip used on your target
-plaform.  For example, <code>CHIPNAME</code> will be
-<code>stm25p</code> for the Telos platform and <code>at45db</code> for
-the MicaZ platform.  Our file will have the following contents:
-
-<pre>
-&lt;volume_table&gt;
-  &lt;volume name="LOGTEST" size="262144"/&gt;
-  &lt;volume name="CONFIGTEST" size="131072"/&gt;
-&lt;/volume_table&gt;
-</pre>
-
-This volume information is used by the toolchain to create an include
-file.  The auto-generated file, however, has to be included manually.
-Place the following line in the configuration file which declares the
-ConfigStorageC component (e.g. <code>BlinkConfigAppC.nc</code>):
-
-<pre>
-#include "StorageVolumes.h"
-</pre>
-
-<li>BlinkConfigC, the application code for this simple demo,
-<em>uses</em> the <code>Mount</code> and <code>ConfigStorage</code>
-interfaces (note that we rename <code>ConfigStorage</code> to
-<code>Config</code>).
-
-<pre>
-module BlinkConfigC {
-  uses {
-    ...
-    interface ConfigStorage as Config;
-    interface Mount;
-    ...
-  }
-}
-</pre>
-
-<li>Each interface must be wired to an <em>implementation</em> that
-will provide it:
-
-<pre>
-configuration BlinkConfigAppC {
-}
-implementation {
-  components BlinkConfigC as App;
-  components new ConfigStorageC(VOLUME_CONFIGTEST); 
-  ...
-
-  App.Config     -> ConfigStorageC.ConfigStorage;
-  App.Mount      -> ConfigStorageC.Mount;
-  ...
-}
-</pre>
-
-<li>Before the flash chip can be used, it must be mounted using the
-two-phase mount/mountDone command.  Here we show how this might be
-chained into the boot sequence:
-
-<pre>
-  event void Boot.booted() {
-    conf.period = DEFAULT_PERIOD;
-
-    if (call Mount.mount() != SUCCESS) {
-      // Handle failure
-    }
-  }
-</pre>
-
-<li>If the Mount.mount succeeds, then the <code>Mount.mountDone</code>
-event will be signaled.  The following code shows how to check if the
-volume is valid, and if it is, how to initiate a read from the volume
-using the <code>ConfigStore.read</code> command.  If the volume is
-invalid, calling <code>Config.commit</code> will make it valid (this
-call is also used to flush buffered data to flash much like the UNIX
-fsync system call is supposed to flush buffered writes to disk):
-
-<pre>
-  event void Mount.mountDone(error_t error) {
-    if (error == SUCCESS) {
-      if (call Config.valid() == TRUE) {
-        if (call Config.read(CONFIG_ADDR, &conf, sizeof(conf)) != SUCCESS) {
-          // Handle failure
-        }
-      }
-      else {
-        // Invalid volume.  Commit to make valid.
-        call Leds.led1On();
-        if (call Config.commit() == SUCCESS) {
-          call Leds.led0On();
-        }
-        else {
-          // Handle failure
-        }
-      }
-    }
-    else{
-      // Handle failure
-    }
-  }
-</pre>
-
-
-<li>If the read is successful, then a <code>Config.readDone</code>
-event will occur.  In this case, we first check for a successful read,
-and if successful, we then check the version number.  If the version
-number matches what we expected, we copy of the configuration data to
-a local variable, and adjust its values.  If there is a version
-mismatch, we set the value of the configuration information to a
-default value.  Finally, we call the the <code>Config.write</code>
-function:
-
-<pre>
-  event void Config.readDone(storage_addr_t addr, void* buf, 
-    storage_len_t len, error_t err) __attribute__((noinline)) {
-
-    if (err == SUCCESS) {
-      memcpy(&conf, buf, len);
-      if (conf.version == CONFIG_VERSION) {
-        conf.period = conf.period/2;
-        conf.period = conf.period > MAX_PERIOD ? MAX_PERIOD : conf.period;
-        conf.period = conf.period < MIN_PERIOD ? MAX_PERIOD : conf.period;
-      }
-      else {
-        // Version mismatch. Restore default.
-        call Leds.led1On();
-        conf.version = CONFIG_VERSION;
-        conf.period = DEFAULT_PERIOD;
-      }
-      call Leds.led0On();
-      call Config.write(CONFIG_ADDR, &conf, sizeof(conf));
-    }
-    else {
-      // Handle failure.
-    }
-  }
-
-</pre>
-
-<li>Data is not necessarily "written" to flash when
-<code>ConfigStore.write</code> is called and
-<code>Config.writeDone</code> is signaled.  To ensure data is
-persisted to flash, a <code>ConfigStore.commit</code> call is
-required:
-
-<pre>
-  event void Config.writeDone(storage_addr_t addr, void *buf, 
-    storage_len_t len, error_t err) {
-    // Verify addr and len
-
-    if (err == SUCCESS) {
-      if (call Config.commit() != SUCCESS) {
-        // Handle failure
-      }
-    }
-    else {
-      // Handle failure
-    }
-  }
-</pre>
-
-<li>Finally, when the <code>Config.commitDone</code> event is
-signaled, data has been durably written to flash and will survive a
-node power cycle:
-
-<pre>
-  event void Config.commitDone(error_t err) {
-    call Leds.led0Off();
-    call Timer0.startPeriodic(conf.period);
-    if (err == SUCCESS) {
-      // Handle failure
-    }
-  }
-</pre>
-
-</ol>
-
-<h1>Logging Data</h1>
-
-Reliable (atomic) logging of events and small data items is a common
-application requirement.  Logged data should not be lost if a system
-crashes.  Logs can be either linear (stop logging when the volume is
-full) or circular (overwrite the least recently written data when the
-volume is full).
-
-<p>
-
-The TinyOS LogStorage abstraction supports these requirements. The log
-is record based: each call to LogWrite.append (see below) creates a
-new record.  On failure (a crash or power cycle), the log only loses
-whole records from the end of the log.  Additionally, once a circular
-log wraps around, log writes only lose whole records from the
-beginning of the log.
-
-<p>
-
-A demo application called <code>PacketParrot</code> shows how to use
-the <code>LogWrite</code> and <code>LogRead</code> abstractions.  A
-node writes received packets to a circular log and retransmits the
-logged packets (or at least the parts of the packets above the AM
-layer) when power is cycled.
-
-<p>
-
-See <a href="../../../apps/tutorials/PacketParrot/">
-<code>tinyos-2.x/apps/tutorials/PacketParrot/</code></a> for the
-accompanying code.
-
-<p>
-
-The application logs packets it receives from the radio to flash.  On
-a subsequent power cycle, the application transmits any logged
-packets, erases the log, and then continues to log packets again.  The
-red LED is on when the log is being erased.  The blue (yellow) LED
-turns on when a packet is received and turns off when a packet has
-been logged successfully.  The blue (yellow) LED remains on when
-packets are being received but are not logged (because the log is
-being erased).  The green LED flickers rapidly after a power cycle
-when logged packets are transmitted.
-
-
-<ol>
-
-<li>The first step when using the log is to decide what kind of data
-you want to store in the log.  In this case, we will declare a struct
-of the type:
-
-<pre>
-  typedef nx_struct logentry_t {
-    nx_uint8_t len;
-    message_t msg;
-  } logentry_t;
-</pre>
-
-<li>Unlike Config storage, Log storage does not require the volume to
-be explicitly mounted by the application.  Instead, a simple read
-suffices in which a buffer and the number of bytes to read are passed
-to <code>LogRead.read</code>:
-
-<pre>
-  event void AMControl.startDone(error_t err) {
-    if (err == SUCCESS) {
-      if (call LogRead.read(&m_entry, sizeof(logentry_t)) != SUCCESS) {
-        // Handle error
-      }
-    }
-    else {
-      call AMControl.start();
-    }
-  }
-</pre>
-
-<li>If the call to <code>LogRead.read</code> returns SUCCESS, then a
-<code>LogRead.readDone</code> event will be signaled shortly
-thereafter.  When that happens, we check if the data that was returned
-is the same length as what we expected.  If it is, we use the data but
-if not, we assume that either the log is empty or that we have lost
-synchronization, so the log is erased:
-
-<pre>
-
-  event void LogRead.readDone(void* buf, storage_len_t len, error_t err) {
-    if ( (len == sizeof(logentry_t)) && (buf == &m_entry) ) {
-      call Send.send(&m_entry.msg, m_entry.len);
-      call Leds.led1On();
-    }
-    else {
-      if (call LogWrite.erase() != SUCCESS) {
-        // Handle error.
-      }
-      call Leds.led0On();
-    }
-  }
-
-</pre>
-
-<li>The <code>PacketParrot</code> application stores packets received
-over the radio to flash by first saving the <code>message_t</code> and
-its length to a <code>log_entry_t</code> struct and then calling
-<code>LogWrite.append</code>:
-
-<pre>
-  event message_t* Receive.receive(message_t* msg, void* payload, uint8_t len){
-    call Leds.led2On();
-    if (!m_busy) {
-      m_busy = TRUE;
-      m_entry.len = len;
-      m_entry.msg = *msg;
-      if (call LogWrite.append(&m_entry, sizeof(logentry_t)) != SUCCESS) {
-        m_busy = FALSE;
-      }
-    }
-    return msg;
-  }
-</pre>
-
-<li>If the <code>LogWrite.write</code> returned SUCCESS, then a short
-time later, a <code>LogWrite.appendDone</code> will be signaled.  This
-event returns the details of the write including the source buffer,
-length of data written, whether any records were lost (if this is a
-circular buffer) and any error code.  If no errors occurred, then the
-data was written to flash with atomicity, consistency, and durability
-guarantees (and will survive node crashes and reboots):
-
-<pre>
-  event void LogWrite.appendDone(void* buf, storage_len_t len, 
-                                 bool recordsLost, error_t err) {
-    m_busy = FALSE;
-    call Leds.led2Off();
-  }
-
-</pre>
-
-</ol>
-
-<h1>Storing Large Objects</h1>
-
-Block storage is generally used for storing large objects that cannot
-easily fit in RAM.  Block is a low-level system interface that
-requires care when using since it is essentially a write-once model of
-storage.  Rewriting requires an erase which is time-consuming, occurs
-at large granularity (e.g. 256 B to 64 KB), and can only happen a
-limited number of times (e.g. 10,000 to 100,000 times is typical).
-The TinyOS network reprogramming system uses Block storage to store
-program images.
-
-<p>
-
-See <a href="../../../apps/tests/storage/Block/">
-<code>tinyos-2.x/apps/tests/storage/Block/</code></a> for an example
-of code that uses the Block storage abstraction.
-
-<h1>Conclusions</h1>
-
-This lesson introduced the basic storage abstractions in Tiny 2.x.
-
-<a name=#related_docs>
-<h1>Related Documentation</h1>
-
-<ul>
-<li> (1) <a name="fn1"><a href="../tep103.html">TEP 103: Permanent Data Storage</a></a>
-<li> (2) <a name="fn2"><a href="lesson1.html">Lesson 1: Getting Started with TinyOS and nesC</a></a>
-<i>TinyOS Programming</i></a>
-</ul>
-
-<!-- Begin footer -->
-<br>
-<hr>
-<center>
-<p>&lt;&nbsp;<b><a href="lesson6.html">Previous Lesson</a></b> |&nbsp; <b><a
- href="index.html">Top</a></b> &nbsp;|&nbsp; <b><a href="lesson8.html">Next Lesson </a>&nbsp;&gt;</b>
-</center>
-
+<p>Sorry, your browser does not support frames. Please <a href="http://docs.tinyos.net/index.php/Storage" target="_top">go here</a>.</p>
 </body>
-</html>
+</noframes>
+</frameset>
+</html>
\ No newline at end of file
index 9ed2d1a6e9e8792ed4bef7e162ba5551e892816f..6bd24bdc25f7efa6feb334b87673d504ad37c7da 100644 (file)
-\r
-<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">\r
-<html>\r
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" ^M   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">\r
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\r
 <head>\r
-  <title>TinyOS Tutorial Lesson 8: Resource Arbitration and Power Management </title>\r
-  <link href="../../stylesheets/tutorial.css" rel="stylesheet" type="text/css">\r
+<title>klueska.com</title>\r
 </head>\r
+<frameset>\r
+<frame src="http://docs.tinyos.net/index.php/Resource_Arbitration_and_Power_Management" name="redir_frame" />\r
+<noframes>\r
 <body>\r
-\r
-<div class="title">Lesson 8: Resource Arbitration and Power Management </div>\r
-<div class="subtitle">Last updated 30 October 2006</div>\r
-\r
-<h1>Introduction</h1>\r
-\r
-<p>\r
-TinyOS distinguishes between three kinds of resource abstractions: <b>dedicated</b>, <b>virtualized</b>, and <b>shared</b>. Two fundamental questions must be asked about each type of abstraction.\r
-<ol>\r
-<li>How can a client gain access to the resource provided through this abstraction?</li>\r
-<li>How can the power state of that resource be controlled?</li>\r
-</ol>\r
-Components offer resource sharing mechanisms and power mangement capabilites according to the goals and level of abstraction required by their clients.\r
-</p>\r
-\r
-<hr>\r
-\r
-<p>\r
-An abstraction is dedicated if it represents a resource which a subsystem needs exclusive access to at all times. In this class of resources, no sharing policy is needed since only a single component ever requires use of the resource.  Resource clients simply call commands from the interfaces provided by the resource just as they would with any other TinyOS component.  Resources of this type provide either an <tt>AsyncStdControl</tt>, <tt>StdControl</tt>, or <tt>SplitControl</tt> interface for controlling their power states.  The definition of each of these interfaces can be found in <tt>tinyos-2.x/tos/interfaces</tt>.\r
-</p>\r
-\r
-<pre>\r
-interface AsyncStdControl {\r
-  async command error_t start();\r
-  async command error_t stop();\r
-}\r
-</pre>\r
-\r
-<pre>\r
-interface StdControl {\r
-  command error_t start();\r
-  command error_t stop();\r
-}\r
-</pre>\r
-\r
-<pre>\r
-interface SplitControl {\r
-  async command error_t start();\r
-  async command void startDone(error_t error);\r
-  async command error_t stop();\r
-  async command void stopDone(error_t error);\r
-}\r
-</pre>\r
-\r
-<p>\r
-Currently, the power states of all dedicated resources are controlled by one of these three interfaces.  They are only allowed to enter one of two logical power states (on/off), regardless of the number of physical power states provided by the hardware on top of which their resource abstraction has been built. Which of these interfaces is provided by a particular resource depends on the timing requirements for physically powering it on or off.\r
-<p>\r
-\r
-<hr>\r
-\r
-<p>\r
-Virtual abstractions hide multiple clients from each other through software virtualization. Every client of a virtualized resource interacts with it as if it were a dedicated resource, with all virtualized instances being multiplexed on top of a single underlying resource. Because the virtualization is done in software, there is no upper bound on the number of clients using the abstraction, barring memory or efficiency constraints.  The power states of a virtualized resource are handled automatically, and no interface is provided to the user for explicity controlling its power state.  As they are built on top of shared resources, the reason their power states can be automatically controlled will become clearer after reading the following section.\r
-</p>\r
-\r
-<hr>\r
-\r
-<p>\r
-Dedicated abstractions are useful when a resource is always controlled by a single component. Virtualized abstractions are\r
-useful when clients are willing to pay a bit of overhead and sacrifice control in order to share a resource in a simple way. There are situations, however, when many clients need precise control of a resource. Clearly, they can't all have such control at the same time:  some degree of multiplexing is needed.\r
-</p>\r
-\r
-<p>\r
-A motivating example of a shared resource is a bus. The bus may have multiple peripherals on it, corresponding to \r
-different subsystems. For example, on the Telos platform the flash chip (storage) and the radio (network) share a bus. The storage and network stacks need exclusive access to the bus when using it, but they also need to share it with the other subsystem. In this case, virtualization is problematic, as the radio stack needs to be able to perform a series of operations in quick succession without having to reacquire the bus in each case. Having the bus be a shared resource allows the radio stack to send a series of operations to the radio atomically, without having to buffer them all up \r
-in memory beforehand (introducing memory pressure in the process).\r
-</p>\r
-\r
-<p>\r
-In TinyOS, a resource <b>arbiter</b> is responsible for multiplexing between the different clients of a shared resource. It determines which client has access to the resource at which time. While a client holds a resource, it has complete and unfettered control. Arbiters assume that clients are cooperative, only acquiring the resource when needed \r
-and holding on to it no longer than necessary. Clients explicitly release resources: there is no way for an arbiter to forcibly reclaim it.\r
-</p>\r
-\r
-<p>\r
-Shared resources are essentially built on top of dedicated resources, with access to them being controlled by an arbiter component.  In this way, <b>power managers</b> can be used to automatically control the power state of these resources through their <tt>AsyncStdControl</tt>, <tt>StdControl</tt>, or <tt>SplitControl</tt> interfaces.  They communicate with the arbiter (through the use of a <tt>ResourceDefaultOwner</tt> interface), monitoring whether the resource is being used by any of its clients and powering it on/off accordingly.  The figure below shows how an arbiter component and a power manager can be wired together to provide arbitration and automatic power management for a shared resource.\r
-</p>\r
-\r
-<center>\r
-<img src="img/arbiter_pm_graph.png",\r
-     alt="This is a picture of how an arbiter and power manager work together", \r
-     height=225\r
-     center\r
-></img><br>\r
-Figure 1: Arbiters and Power Managers\r
-</center>\r
-\r
-<p>\r
-The arbiter component provides the <tt>Resource</tt>, <tt>ArbiterInfo</tt>, <tt>ResourceRequested</tt>, and <tt>ResourceDefaultOwner</tt> interfaces and uses the <tt>ResourceConfigure</tt> interface.  The power manager doesn't provide any interfaces, but uses one of either the <tt>AsyncStdControl</tt>, <tt>StdControl</tt>, or <tt>SplitControl</tt> interfaces from the underlying resource, as well as the <tt>ResourceDefaultOwner</tt> interface provided by the arbiter.  The figure below shows how these interface are then wired together with the implementation of a shared resource.  Please refer to TEP 108 for more information on arbiters and TEP 115 for more information on Power Managers.\r
-</p>\r
-\r
-<center>\r
-<img src="img/shared_resource_graph.png",\r
-     alt="This is a picture of how a shared resource works together with an arbiter and a power manager", \r
-     height=450\r
-     center\r
-></img><br>\r
-Figure 2: Shared Resource Configuration\r
-</center>\r
-\r
-<p>\r
-From this figure, we see that the only interfaces exposed to a client through the shared resource abstraction are the <tt>Resource</tt> and <tt>ResourceRequested</tt> interfaces provided by the arbiter as well as any resource specific interfaces provided by the resource itself.  It also uses a <tt>ResourceConfigure</tt> interface, expecting it to be  implemented on a client by client basis depending on their requirements. A client requests access to a shared resource through the <tt>Resource</tt> interface and runs operations on it using whatever resource specific interfaces are provided.  A client may choose to wire itself to the <tt>ResourceRequested</tt> interface if it wishes to hold onto a resource indefinitely and be informed whenever other clients request its use.\r
-</p>  \r
-\r
-<p>\r
-The rest of this tutorial is dedicated to teaching users how to use shared resources and show them how wiring is done between all components that make them up.</p>\r
-<p>\r
-Specifically, this tutorial will teach users how to:\r
-<ol> \r
-<li> Wire in a shared resource for use by a client.\r
-<li> Use the <tt>Resource</tt> interface to gain access to a shared resource.</li>\r
-<li> Change the arbitration policy used by a particular shared resource.</li>\r
-<li> Wire up a power manager for use by a shared resource.</li>\r
-</ol>\r
-</p>\r
-\r
-<h1>Working with Shared Resources</h1>\r
-<p>This section shows you how to gain access to and use shared resources in TinyOS.  It walks through the process of making a request through the <code>Resource</code> interface and handling the <tt>granted</tt> event that is signaled back.  We will connect multiple clients to a single shared resources and see how access to each of them gets arbitrated.  We also show how to hold onto a resource until another client has requested it by implementing the <tt>ResourceRequested</tt> interface.\r
-</p>\r
-\r
-<p>To begin, go to the <tt>tinyos-2.x/apps/tutorials/SharedResourceDemo</tt> directory and install this application on a mote.  After installing the application you should see three leds flashing in sequence.</p> \r
-\r
-<p>Let's take a look at the different components contained in this directory to see whats going on.  Start with the top level application component: <code>SharedResourceDemoAppC</code></p>\r
-\r
-<pre>\r
-configuration SharedResourceDemoAppC{\r
-}\r
-implementation {\r
-  components MainC,LedsC, SharedResourceDemoC as App,\r
-  new TimerMilliC() as Timer0,\r
-  new TimerMilliC() as Timer1,\r
-  new TimerMilliC() as Timer2;\r
-  App -> MainC.Boot;\r
-  App.Leds -> LedsC;\r
-  App.Timer0 -> Timer0;\r
-  App.Timer1 -> Timer1;\r
-  App.Timer2 -> Timer2;\r
-  \r
-  components\r
-  new SharedResourceC() as SharedResource0,\r
-  new SharedResourceC() as SharedResource1, \r
-  new SharedResourceC() as SharedResource2;\r
-  App.Resource0 -> SharedResource0;\r
-  App.Resource1 -> SharedResource1;\r
-  App.Resource2 -> SharedResource2;\r
-  App.ResourceOperations0 -> SharedResource0;\r
-  App.ResourceOperations1 -> SharedResource1;\r
-  App.ResourceOperations2 -> SharedResource2;\r
-}\r
-</pre>\r
-\r
-<p>Other than the instantiation and wiring of the interfaces provided by the <code>SharedResourceC</code> component, this configuration is identical to the one presented in Lesson 1 for the Blink Application.</p>  \r
-\r
-<p>All shared resources in TinyOS are provided through a generic component similar to the <code>SharedResourceC</code> component.  A resource client simply instantiates a new instance of this component and wires to the interfaces it provides.  In this application, three instances of the <code>SharedResourceC</code> component are instantiated and wired to three different clients from the <code>SharedResourceDemoC</code> component.  Each instantiation provides a <tt>Resource</tt>, <tt>ResourceOperations</tt>, and <tt>ResourceRequested</tt> interface, and uses a <tt>ResourceConfgigure</tt> interface. In this example, no wiring is done to the <tt>ResourceConfigure</tt> or <tt>ResourceRequested</tt> interface as wiring to to these interfaces is optional.  The <tt>ResourceOperations</tt> interface is an <b>EXAMPLE</B> of a resource specific interface that a resource may provide to perform operations on it.  Calls to commands through this interface will only succeed if the client calling them happens to have access to the resource when they are called.\r
-</p>\r
-\r
-<p>Let's take a look at the <code>SharedResourceDemoC</code> to see how access is actually granted to a Resource.\r
-</p>\r
-\r
-<pre>\r
-module SharedResourceDemoC {\r
-  uses {\r
-    interface Boot;  \r
-    interface Leds;\r
-    interface Timer<TMilli> as Timer0;\r
-    interface Timer<TMilli> as Timer1;\r
-    interface Timer<TMilli> as Timer2;\r
-    \r
-    interface Resource as Resource0;\r
-    interface ResourceOperations as ResourceOperations0;\r
-    \r
-    interface Resource as Resource1;\r
-    interface ResourceOperations as ResourceOperations1;\r
-    \r
-    interface Resource as Resource2;\r
-    interface ResourceOperations as ResourceOperations2;\r
-  }\r
-}\r
-</pre>\r
-\r
-<p>Each pair of <code>Resource/ResourceOperations</code> interfaces reperesents a different client of the shared resource used by this application.  At boot time, we put in a request for the shared resource through each of these clients in the order (0,2,1).</p>\r
-\r
-<pre>\r
-event void Boot.booted() {\r
-  call Resource0.request();\r
-  call Resource2.request();\r
-  call Resource1.request();\r
-}\r
-</pre>\r
-\r
-<p>Each of these requests is serviced in the order of the arbitration policy used by the shared resource.  In the case of <code>SharedResourceC</code>, a Round-Robin policy is used, so these requests are serviced in the order (0,1,2).  If a first-come-first-serve policy were in use, they would we be serviced in the order the were put in, i.e. (0,2,1).</p>\r
-\r
-<p>Whenever a client's request for a resource has been granted, the <code>Resource.granted()</code> event for that client gets signaled.  In this application, the body of the granted event for each client simply performs an operation on the resource as provided through the <code>ResourceOperations</code> interface.</p>\r
-\r
-<pre>\r
-event void Resource0.granted() {\r
-  call ResourceOperations0.operation();   \r
-}  \r
-event void Resource1.granted() {\r
-  call ResourceOperations1.operation();\r
-}  \r
-event void Resource2.granted() {\r
-  call ResourceOperations2.operation();\r
-} \r
-</pre>\r
-\r
-<p>Whenever one of these operations completes, a <code>ResourceOperations.operationDone()</code> event is signaled.  Once this event is received by each client, a timer is started to hold onto the resource for 250 (binary) ms and an LED corresponding to that client is toggled.</p>\r
-\r
-<pre>\r
-#define HOLD_PERIOD 250\r
-\r
-event void ResourceOperations0.operationDone(error_t error) {\r
-  call Timer0.startOneShot(HOLD_PERIOD);  \r
-  call Leds.led0Toggle();\r
-}\r
-event void ResourceOperations1.operationDone(error_t error) {\r
-  call Timer1.startOneShot(HOLD_PERIOD);  \r
-  call Leds.led1Toggle();\r
-}\r
-event void ResourceOperations2.operationDone(error_t error) {\r
-  call Timer2.startOneShot(HOLD_PERIOD);  \r
-  call Leds.led2Toggle();\r
-}\r
-</pre> \r
-\r
-<p>Whenever one of these timers goes off, the client that started it releases the resource and immediately puts in a request for it again.</p>\r
-\r
-<pre>\r
-event void Timer0.fired() {\r
-  call Resource0.release();\r
-  call Resource0.request();\r
-}\r
-event void Timer1.fired() {\r
-  call Resource1.release();\r
-  call Resource1.request();\r
-}\r
-event void Timer2.fired() {\r
-  call Resource2.release();\r
-  call Resource2.request();\r
-}\r
-</pre>\r
-\r
-<p>In this way, requests are continuously put in by each client, allowing the application to continuously flash the LEDs in the order in which requests are being serviced.  As stated before, the <code>SharedResourceC</code> component services these requests in a round-robin fashion.  If you would like to see the requests serviced in the order they are received (and see the LEDs flash accordingly), you can open up the <code>SharedResourceP</code> component in the <tt>apps/tutorials/SharedResourceDemo</tt> directory and replace the <code>RoundRobinArbiter</code> component with the <code>FcfsArbiter</code> component.</p>\r
-\r
-<table>\r
- <tr><td><b>RoundRobinArbiter</b></td><td width=10></td><td><b>FcfsArbiter</b></td></tr>\r
- <tr><td>\r
-<pre>\r
-configuration SharedResourceP {\r
-       provides interface Resource[uint8_t id];\r
-       provides interface ResourceRequested[uint8_t id];\r
-       provides interface ResourceOperations[uint8_t id];\r
-       uses interface ResourceConfigure[uint8_t id];\r
-}\r
-implementation {\r
-  components new RoundRobinArbiterC(UQ_SHARED_RESOURCE) as Arbiter;\r
-  ...\r
-  ...\r
-}\r
-</pre>\r
-</td>\r
-<td></td>\r
-<td>\r
-<pre>\r
-configuration SharedResourceP {\r
-       provides interface Resource[uint8_t id];\r
-       provides interface ResourceRequested[uint8_t id];\r
-       provides interface ResourceOperations[uint8_t id];\r
-       uses interface ResourceConfigure[uint8_t id];\r
-}\r
-implementation {\r
-  components new FcfsArbiterC(UQ_SHARED_RESOURCE) as Arbiter;\r
-  ...\r
-  ...\r
-}\r
-</pre>\r
-</td>\r
-</tr>\r
-</table>\r
-</center>\r
-</table>\r
-\r
-<p>Looking through the rest of this component, you can see how its wiring matches the connections shown in Figure 2.</p>\r
-\r
-<pre>\r
-#define UQ_SHARED_RESOURCE   "Shared.Resource"\r
-configuration SharedResourceP {\r
-       provides interface Resource[uint8_t id];\r
-       provides interface ResourceRequested[uint8_t id];\r
-       provides interface ResourceOperations[uint8_t id];\r
-       uses interface ResourceConfigure[uint8_t id];\r
-}\r
-implementation {\r
-  components new RoundRobinArbiterC(UQ_SHARED_RESOURCE) as Arbiter;\r
-  components new SplitControlPowerManagerC() as PowerManager;\r
-  components ResourceP;\r
-  components SharedResourceImplP;\r
-\r
-  ResourceOperations = SharedResourceImplP;\r
-  Resource = Arbiter;\r
-  ResourceRequested = Arbiter;\r
-  ResourceConfigure = Arbiter;\r
-  SharedResourceImplP.ArbiterInfo -> Arbiter;\r
-  PowerManager.ResourceDefaultOwner -> Arbiter;\r
-  \r
-  PowerManager.SplitControl -> ResourceP;\r
-  SharedResourceImplP.ResourceOperations -> ResourceP;\r
-}\r
-</pre>\r
-\r
-<p>\r
-Four different components are instantiated by this configuration:\r
-</p>\r
-\r
-<pre>\r
-components new RoundRobinArbiterC(UQ_SHARED_RESOURCE) as Arbiter;\r
-components new SplitControlPowerManagerC() as PowerManager;\r
-components ResourceP;\r
-components SharedResourceImplP;\r
-</pre>\r
-\r
-<p>\r
-As we've already seen, the <tt>RoundRobinArbiterC</tt> component is used to provide arbitration between clients using <tt>SharedResourceC</tt>.  The <tt>SplitControlPowerManagerC</tt> component is used to perform automatic power management of the resource to turn it on whenever a new client requests its use and shut it down whenever it goes idle.  The <tt>ResourceP</tt> component is the implementation of a dedicated resource which provides a <tt>SplitControl</tt> interface and a <tt>ResourceOperations</tt> interface.  This dedicated resource is wrapped by the <tt>SharedResourceImplP</tt> component in order to provide protected shared access to it.  <tt>SharedResourceImplP</tt> wraps all the commands provided by the dedicated resource, and uses the <tt>ArbiterInfo</tt> interface to keep clients from calling them without first being granted access to the resource.\r
-</p>\r
-\r
-<p>\r
-If you would like to see more examples of how to use the different arbiters and power managers provided in the default TinyOS distribution, please refer to the test applications located in <tt>tinyos-2.x/apps/tests/TestArbiter</tt> and <tt>tinyos-2.x/apps/tests/TestPowerManager</tt>.  This tutorial has provided enough background information on how to use these components in order for you to sift through these applications on your own. \r
-</p>\r
-\r
-<h1>Conclusion</h1>\r
-<p>\r
-This tutorial has given an overview of how resource arbitration and mechanisms for performing power management on those resources is provided in TinyOS.  It walked us through the steps necessary for:\r
-<ol> \r
-<li> Wiring in a shared resource for use by a client.\r
-<li> Using the <tt>Resource</tt> interface to gain access to a shared resource.</li>\r
-<li> Changing the arbitration policy used by a particular shared resource.</li>\r
-<li> Wrapping a dedicated resource and wiring in a power manager in order to create a shared resource.</li>\r
-</ol>\r
-</p>\r
-\r
-<p>\r
-While the power managers presented in this tutorial are powerful components for providing power management of shared resources, they are not the only power management mechanisms provided by TinyOS.  Microcontroller power management is also preformed as outlined in TEP115.  Whenever the task queue empties, the lowest power state that the microcontroller is capable of dropping to is automatically calculated and then switched to.  In this way, the user is not burdened with explicity controlling these power states.  The cc1000 and cc2420 radio implementations also provide "Low Power Listening" (LPL) interfaces for controlling their duty cycles.  The LPL implementation for the cc2420 can be found under <tt>tinyos-2.x/tos/chips/cc2420</tt> and the LPL implementation for the cc1000 can be found under <tt>tinyos-2.x/tos/chips/cc1000</tt>.  Take a look \r
-at <a href=lesson16.html>lesson 16</a> to see how this interface is used.\r
-</p>\r
-\r
-<!-- Related Docs -->\r
-<p>\r
-<a name=#related_docs>\r
-<h1>Related Documentation</h1>\r
-</a>\r
-<ul>\r
-<li> <a href="http://csl.stanford.edu/~pal/pubs/tinyos-programming-1-0.pdf">TinyOS Programming Guide                   \r
-       <i>Sections 6.2 and 7.4</i></a>\r
-<li> <a href="../tep108.html">TEP 108: Resource Arbitration</a>\r
-<li> <a href="../tep112.html">TEP 112: Microcontroller Power Management</a>\r
-<li> <a href="../tep115.html">TEP 115: Power Management of Non-Virtualized Devices</a>\r
-</ul>\r
-\r
-<p>\r
-<hr>\r
-\r
-<!-- Begin footer -->\r
-<br>\r
-<hr>\r
-<center>\r
-<p>&lt;&nbsp;<b><a href="lesson7.html">Previous Lesson</a></b> |&nbsp; <b><a\r
- href="index.html">Top</a></b> &nbsp;|&nbsp; <b><a href="lesson10.html">Next Lesson </a>&nbsp;&gt;</b>\r
-</center>\r
-\r
+<p>Sorry, your browser does not support frames. Please <a href="http://docs.tinyos.net/index.php/Resource_Arbitration_and_Power_Management" target="_top">go here</a>.</p>\r
 </body>\r
-</html>\r
+</noframes>\r
+</frameset>\r
+</html>
\ No newline at end of file