]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - doc/html/tutorial/lesson11.html
Update to tutorials to redirect them to the wiki now instead of directly being modifi...
[tinyos-2.x.git] / doc / html / tutorial / lesson11.html
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