]> oss.titaniummirror.com Git - tinyos-2.x.git/commitdiff
Updated instructions.
authorscipio <scipio>
Wed, 2 May 2007 03:12:46 +0000 (03:12 +0000)
committerscipio <scipio>
Wed, 2 May 2007 03:12:46 +0000 (03:12 +0000)
doc/html/install-tinyos.html
doc/html/tutorial/lesson11-200.html [new file with mode: 0644]
doc/html/upgrade-tinyos.html
doc/index.html

index fff256e9c67248d23ff8c2fbb674d9932fead735..d135a445e71ed7f4c344b513f1b26175c6d8150c 100644 (file)
@@ -8,7 +8,7 @@
 <body>
 
 <div class="title">Installing TinyOS 2.0</div>
-<div class="subtitle">Last updated 8 April 2007</div>
+<div class="subtitle">Last updated 1 May 2007</div>
 
 <p>If you already have a 1.x tree or an existing 2.x tree, you are better off 
 following the <i>upgrade</i> instructions at 
@@ -20,8 +20,9 @@ following the <i>upgrade</i> instructions at
       <h1>One-step Install with a Live CD</h1>
 
       <p><A
-      HREF="http://toilers.mines.edu/Public/XubunTOS/">Download a
-      Linux live CD that has a TinyOS installation on it</A>. All you
+      HREF="http://toilers.mines.edu/Public/XubunTOS">Download a
+      Linux live CD that has a TinyOS installation on it</A>. 
+      All you
       need to do is download the CD image, burn it onto a CD, and
       install from there. This saves you all of the complexities of
       installation, and it's the recommended way to install
@@ -33,7 +34,13 @@ following the <i>upgrade</i> instructions at
 <p>Currently, the TinyOS Core Working Group supports TinyOS on two platforms: Cygwin (Windows)
 and Linux. There have been some <A HREF="">successful efforts</A> to getting TinyOS environments working
 on Mac OSX, but OSX is not supported by the Core WG.</p>
-      
+
+<p>If you are running a version of Linux that supports Debian packages, then
+   you may want to use the TinyOS package repository. There is a <A HREF="http://www.tinyos.net/scoop/story/2007/3/1/142950/4912">story on www.tinyos.net</A> 
+   that describes how to use it. If you do this, then you do not have to
+   install the instructions here, except that you will need to check
+   that your environment is set up correctly (the final step)</p>
+
 <p>Installing a TinyOS enviromnent has five basic steps; Windows requires an extra step,
 installing Cygwin, which is a UNIX-like environment. The steps are:</p>
 
@@ -311,8 +318,8 @@ bypass the erroneous error by using 'rpm -ivh --ignoreos
 
 <tr>
   <td>TinyOS</td>
-  <td><a href="http://www.tinyos.net/dist-2.0.0/tinyos/windows/tinyos-2.0.0-3.cygwin.noarch.rpm">tinyos-2.0.0-3.cygwin.noarch.rpm</a></td>
-  <td><a href="http://www.tinyos.net/dist-2.0.0/tinyos/linux/tinyos-2.0.0-3.noarch.rpm">tinyos-2.0.0-3.noarch.rpm</a></td>
+  <td><a href="http://www.tinyos.net/dist-2.0.0/tinyos/windows/tinyos-2.0.1-5.cygwin.noarch.rpm">tinyos-2.0.1-5.cygwin.noarch.rpm</a></td>
+  <td><a href="http://www.tinyos.net/dist-2.0.0/tinyos/linux/tinyos-2.0.1-5.noarch.rpm">tinyos-2.0.1-5.noarch.rpm</a></td>
 </tr>
 
 </tbody></table>
diff --git a/doc/html/tutorial/lesson11-200.html b/doc/html/tutorial/lesson11-200.html
new file mode 100644 (file)
index 0000000..a495f6a
--- /dev/null
@@ -0,0 +1,1594 @@
+<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+  <title>Lesson 11: Simulation with TOSSIM</title>
+  <link href="../../stylesheets/tutorial.css" rel="stylesheet" type="text/css">
+</head>
+<body>
+
+<div class="title">Lesson 11: Simulation with TOSSIM</div>
+<div class="subtitle">Last Modified: 18 May 2006</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>
+
+
+<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>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', '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>remove(src, dest)</code></b>: Remove the link from
+          <i>src</i> to <i>dest</i>.</li>
+
+
+          <li><b><code>setNoise(node, mean, variance)</code></b>: Set the noise
+          floor at <i>node</i> to be a gaussian distribution with
+          <i>mean</i> and <i>variance</i>.</li>
+
+          <li><b><code>sensitivity()</code></b>: Return the receive sensitivity of
+            the nodes.</li>
+
+          <li><b><code>setSensitivity(val)</code></b>: Set the receive sensitivity
+          of nodes to be <i>val</i>. The sensitivity is how much
+          stronger a signal must be for it to be received
+          uncorrupted. E.g., a sensitivity of 3.0 (the default value)
+          means that a packet must be 3dBm greater than the sum of
+          noise and concurrent transmissions for it to be received
+          uncorrupted.</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 -95.</li>
+          
+        </ul>
+
+        <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)
+
+t.getNode(1).bootAtTime(100001);
+t.getNode(2).bootAtTime(800008);
+t.getNode(3).bootAtTime(1800009);
+
+r.setNoise(1, -100.0, 5.0)
+r.setNoise(2, -100.0, 5.0)
+r.setNoise(3, -100.0, 5.0)
+
+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 the noise to be 30 plus or minus 5 dBm instead
+        of 80 plus or minus 5 dBm, then nodes will never transmit, as
+        the default CCA threshold is -95 dBm. 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>
+noise n avg std
+gain src dest g
+          </pre>
+
+          where each statement is on a separate line. The <i>noise</i>
+          statement defines the noise observed at node <i>n</i> with
+          an average of <i>avg</i> and a standard deviation of
+          <i>std</i>.  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("mirage-1.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]))
+    elif (s[0] == "noise"):
+      r.setNoise(int(s[1]), float(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 two sample configuration
+        files generated from the tool in
+        <code>tos/lib/tossim/topologies</code>. The first is <code><A
+        HREF="">grid.txt</A></code>, which is a 10x10 grid of nodes
+        spaced roughly 40 feet apart. Each node is placed randomly
+        within a 40'x40' "cell." The cells follow a strict grid. The
+        second file is <code><A HREF="">scatter.txt</A></code>, which is
+        100 nodes scattered randomly (with a uniform distribution)
+        over a 360'x360' area. 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>mirage-1.txt</code>.</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:</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]))
+    elif (s[0] == "noise"):
+      r.setNoise(int(s[1]), float(s[2]), float(s[3]))
+
+for i in range (0, 4):
+  m = t.getNode(i)
+  m.bootAtTime(randint(1000, 2000) * 1000000)
+
+m = t.getNode(0)
+v = m.getVariable("RadioCountToLedsC.counter")
+
+while (v.getData() < 10):
+  t.runNextEvent()
+
+        </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]))
+    elif (s[0] == "noise"):
+      r.setNoise(int(s[1]), float(s[2]), float(s[3]))
+
+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 " + msg.__str__() + " 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:</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
+
+from RadioCountMsg import *
+
+t = TOSSIM.Tossim([])
+r = t.radio();
+
+for i in range(0, 999):
+  m = t.getNode(i);
+  m.bootAtTime(5000003 * i + 1);
+  r.setNoise(i, -99.0, 3.0);
+  for j in range (0, 2):
+    if (j != i):
+      r.add(i, j, -50.0);
+
+
+
+
+for i in range(0, 1000000):
+  t.runNextEvent();
+           </PRE>
+          </TD>
+          <TD VALIGN=TOP>
+            <PRE>
+#include &lt;tossim.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);
+    r->setNoise(i, -99.0, 3);
+    for (int j = 0; j &lt; 2; j++) {
+      if (i != j) {
+        r->add(i, j, -50.0);
+      }
+    }
+  }
+
+  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 UscGainInterferenceModelC$receiving[23]
+Hardware watchpoint 2: UscGainInterferenceModelC$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>
+
+</body>
+</html>
index b74fd6a84fe2828e458893e525b4d6a005218d32..df4fcb77413b8c4cf0ee03e9bb7ac2b549666260 100644 (file)
@@ -8,7 +8,7 @@
   <body>
 
     <div class="title">Upgrading from TinyOS 1.x to TinyOS 2.x</div>
-    <div class="subtitle">Last updated 8 April 2007</div>
+    <div class="subtitle">Last updated 1 May 2007</div>
 <p>
 This document describes how to upgrade your TinyOS 1.x environment to
 a TinyOS 2.x environment. This requires that you not only install the 
@@ -233,8 +233,8 @@ recommend removing it before installing the new one with a forced install.</p>
 
 <tr>
   <td>TinyOS</td>
-  <td><a href="http://www.tinyos.net/dist-2.0.0/tinyos/windows/tinyos-2.0.0-3.cygwin.noarch.rpm">tinyos-2.0.0-3.cygwin.noarch.rpm</a></td>
-  <td><a href="http://www.tinyos.net/dist-2.0.0/tinyos/linux/tinyos-2.0.0-3.noarch.rpm">tinyos-2.0.0-3.noarch.rpm</a></td>
+  <td><a href="http://www.tinyos.net/dist-2.0.0/tinyos/windows/tinyos-2.0.1-5.cygwin.noarch.rpm">tinyos-2.0.1-5.cygwin.noarch.rpm</a></td>
+  <td><a href="http://www.tinyos.net/dist-2.0.0/tinyos/linux/tinyos-2.0.1-5.noarch.rpm">tinyos-2.0.1-5.noarch.rpm</a></td>
   <td><tt>rpm -Uvh</tt> (to upgrade)<br>
       <tt>rpm -ivh</tt> (to install)<br>
       <tt>rpm -ivh --force</tt> (to force install)<br>
index df424bff167b46a97dd9e04b91322eaa3a146e0b..bf256ffac5158cfdfae207a0fddf7e56b61f02a8 100644 (file)
@@ -1,4 +1,4 @@
-1<HTML>
+<HTML>
 
   <HEAD>
     <TITLE>TinyOS 2.0 Documentation</TITLE>
        <TR>
          <TD CLASS="title">
            TinyOS 2.0 Documentation<br>
-           <DIV CLASS="subtitle">Last Modified: April 19 20067</DIV>
+           <DIV CLASS="subtitle">Last Modified: April 19 2007</DIV>
          </TD>
        </TR>
        <TR>
          <TD>
-           <p>TinyOS 2.0 has four sets of documentation. The first
+           <p>TinyOS 2.0 has three sets of documentation. The first
            set is the release notes and high-level overviews of the
            system. The second set is a series of tutorials and a
            TinyOS programming manual, which explore different parts
@@ -28,7 +28,7 @@
            documentation. </p>
 
            <p>If you're just getting started, the best place to start
-             is with the tutorials.<.p>
+             is with the tutorials.</p>
 
          </TD>
        </TR>
           </TD>
         </TR>
        <TR>
-         <TD CLASS="subtitle"><A HREF="html/tos-javasdk-javadoc/index.html">TinyOS Java toolchain Code Documentation</A></TD>
+         <TD CLASS="subtitle"><A HREF="html/tos-javasdk-javadoc/index.html"> 3C. TinyOS Java toolchain Code Documentation</A></TD>
        </TR>
         <TR>
           <TD>