5: Simulating TinyOS Applications in TOSSIM
Last updated 25 August 2003
TOSSIM, the TinyOS simulator, compiles directly from TinyOS code. Built with make pc, the simulation runs natively on a desktop or laptop. TOSSIM can simulate thousands of nodes simultaneously. Every mote in a simulation runs the same TinyOS program.
TOSSIM provides run-time configurable debugging output, allowing a user
to examine the execution of an application from different perspectives
without needing to recompile. TinyViz is a Java-based GUI that allows you
to visualize and control the simulation as it runs, inspecting debug messages,
radio and UART packets, and so forth. The simulation provides several mechanisms
for interacting with the network; packet traffic can be monitored, packets
can be statically or dynamically injected into the network. In this lesson,
we won't be dealing with packet injection, which is discussed in Lesson
TOSSIM is compiled by typing make pc in an application directory. In addition to the expected TinyOS components, a few simulator-specific files are compiled; these files provide functionality such as support for network monitoring over TCP sockets.
Enter the apps/CntToLedsAndRfm directory. This application runs a 4Hz counter. It assumes a Mica mote which has 3 LEDs. On each counter tick, the application displays the least significant three bits of the counter on the three mote LEDs and sends the entire 16-bit value in a packet. Build and install the application on a Mica mote as in Lesson 4. You should see the LEDs blink.
Build a TOSSIM version of the application with make pc. The TOSSIM executable is build/pc/main.exe. Type build/pc/main.exe --help to see a brief summary of its command-line usage. TOSSIM has a single required parameter, the number of nodes to simulate. Type build/pc/main.exe 1 to run a simulation of a single node. You should see a long stream of output fly by, most of which refer to radio bit events. Hit control-C to stop the simulation.
By default, TOSSIM prints out all debugging information. As radio bit
events are fired at 20 or 40 KHz, these are the most frequent events in
the simulator, they comprise most of the output in CntToLedsAndRfm. Given
the application, we're more concerned with the packet output and mote LEDs
than individual radio bits. TOSSIM output can be configured by setting
the DBG environment variable in a shell. Type export DBG=am,led
in your shell; this makes only LED and AM (active messages) packet output
enabled. Run the one-mote simulation again. You should see output similar
0: LEDS: Yellow off. 0: LEDS: Green off. 0: LEDS: Red off. 0: Sending message: ffff, 4 ff ff 04 7d 08 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3b f3 00 00 01 00 00 00 0: LEDS: Yellow off. 0: LEDS: Green off. 0: LEDS: Red on. 0: Sending message: ffff, 4 ff ff 04 7d 08 21 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ac e6 00 00 01 00 00 00
The sixth byte of the packet contains the least significant byte of the two byte counter; in this example the first packet is hex 0x20 (32), in the second, it's hex 0x21 (33). As the LEDs show the bottom three bits of the counter, they are all off for the first packet and bit one is on for the second.
Almost every message is preceded by a 0:; this means that the message pertains to the execution of mote 0. Run a simulation of two motes (build/pc/main.exe 2); after it runs for a few seconds, stop the simulation with control-C. You should see messages for both mote 0 and mote 1.
Set DBG to crc. Run two mote simulation of CntToLedsAndRfm. You should see output indicating that both nodes are successfully receiving packets from each-other.
The full set of DBG modes can be seen by typing build/pc/main.exe
--help; they are listed at the bottom of the output.
Four DBG modes are reserved for application components and debugging
use: usr1, usr2, usr3, and temp. In
TinyOS code, debug message commands have this syntax:
dbg(<mode>, const char* format, ...);
The mode parameter specifies which under which DBG modes this message
will be printed. The full set of modes can be found in tos/types/dbg_modes.h.
The format and following parameters specify the string to output and have
semantics. For example, open tos/lib/Counters/Counter.ncin
your editor. In Timer.fired(), add this line just before the return
dbg(DBG_TEMP, "Counter: Value is %i\n", (int)state);
Set DBG to be temp and run a single mote simulation. You'll see the counter increment. In general, the DBG mode name in TinyOS code is the name used when you run the simulator, with DBG_prepended. For example, am is DBG_AM, packet is DBG_PACKET and boot is DBG_BOOT.
Just as you can enable multiple modes when running the simulator, a
single debug message can be activated on multiple modes. Each mode is a
bit in a large bitmask; one can use all of the standard logical operators
(e.g. |, ~) . For example, change the debug message you
just added to:
dbg(DBG_TEMP|DBG_USR1, "Counter: Value is %i\n", (int)state);
It will now be printed if either temp or usr1 is enabled.
Run the application to see this is the case.
One significant advantage of TOSSIM is that, because it runs natively on a PC, you can use traditional debugging tools such as gdb. However, because TOSSIM is a discrete event simulation for large numbers of motes, traditional step-through debugging techniques only work on an event basis, and not cross-events.
Unfortunately, gdb is generally 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 redOff
command of the Leds interface of LedsC, one must type:
gdb build/pc/main.exe // start gdb (gdb) break *LedsC$Leds$redOff Breakpoint 1 at 0x804c644: file tos/system/LedsC.td, line 97. run 1 // run CntToLedsAndRfm with one mote
The leading * is necessary so gdb can parse the function name correctly; otherwise, it looks for the function LedsC.
Variables are similarly named. For example, to print the ledsOn
variable of LedsC (which keeps track of on/off for the toggle
commands), one types:
(gdb) print LedsC$ledsOn $3 = '\0' <repeats 999 times>
Actually, this isn't quite correct, as the output above shows; in TOSSIM,
isn't a single uint8_t, but an array of 1000 of them. This is
how TOSSIM handles the state of many motes; it compiles fields to be arrays
of n elements, where n is the maximum simulation size. Whenever
a mote accesses a component's state, it indexes into the array based on
its node ID. Therefore, to refer to a specific mote's state, one needs
to index into the array properly:
(gdb) print LedsC$ledsOn[tos_state.current_node] $2 = 0 '\0'
We've supplied a simple gdb macro named VAR that handles
this for you. Copy tos/platform/pc/.gdbinit
to your home directory (if there's already a .gdbinit there, just
append this file). Type quit and start gdb it again.
Break in LedsC$Leds$redOff as before. Now, instead of the above
command line, you can type:
(gdb) VAR LedsC$ledsOn $3 = 0 '\0'
TinyViz provides an extensible graphical user interface for debugging,
visualizing, and interacting with TOSSIM simulations of TinyOS applications.
Using TinyViz, you can easily trace the execution of TinyOS apps, set breakpoints
when interesting events occur, visualize radio messages, and manipulate
the virtual position and radio connectivity of motes. In addition, TinyViz
supports a simple "plugin" API that allows you to write your own TinyViz
modules to visualize data in an application-specific way, or interact with
the running simulation.
To get started, look at the apps/TestTinyViz application, which causes motes to periodically send a message to a random neighbor. There isn't anything interesting about the application itself, but it will allow us to demonstrate the basic features of TinyViz. Go ahead and build the app with make pc.
To compile TinyViz, cd to the tools/java/net/tinyos/sim directory and type make. This will build the TinyOS program as tinyviz.jar, a stand-alone Java JAR file that you can run with the tinyviz script, found in this directory. Place this script on your PATH and you will be able to run tinyviz directly from the command line.
Start up TinyViz, running the TestTinyViz app, as follows:
export DBG=usr1 tinyviz -run build/pc/main.exe 30
You will see a window looking something like the following:
On the left is the graphical display of the sensor network. On the right is the control panel where you can interact with a series of plugins that control how TinyViz works.
In the mote window, you can select motes by clicking on them, or select a group of motes by dragging a rectangle around the group. You can move motes around by dragging them around. Selecting motes is meaningful for certain plugins, and other operations, such as toggling the power state of the motes.
The "pause/play" button pauses or resumes the simulation. The "grid button" toggles grid-lines on the display. The "clear" button clears out the display state. The "stop" button kills the simulation. The "delay" slider introduces a delay between the handling of each TOSSIM event, which will slow down the display -- useful in cases where you have a small number of motes and want to watch the simulation operating in "real time". The "On/off" button toggles the power state of the selected motes.
A TinyViz plugin is a software module that watches for events coming from the simulation -- such as debug messages, radio messages, and so forth -- and reacts by drawing information on the display, setting simulation parameters, or actuating the simulation itself, for example, by setting the sensor values that simulated motes will read. TinyViz comes with a suite of built-in plugins, in the tools/java/net/tinyos/sim/plugins directory, and you can write your own. Not all plugins are used for all applications -- for example, the Calamari plugin is used mainly for testing the Calamari localization service -- but many of them are generally useful.
Plugins can be selectively enabled or disabled, depending on what information you are interested in seeing during the simulation. You select plugins from the Plugins menu. When a plugin is enabled, its corresponding tab in the right-hand control panel window is active, which may have additional information and controls provided by that plugin. Plugins are designed to be independent of each other so you can enable or disable any group of plugins you like.
The main plugins you are likely to use are:
DBG=usr1,am tinyviz -run build/pc/main.exe 30
Layout of the motes is controlled by the Layout menu, which gives you several options including random, grid-based, or a "grid+random" (grid-based but with a random perturbation) layout. You can also save and load layouts from a file. The location of the motes on the display is used in two ways. First, it is used to determine radio connectivity, when the RadioModelPlugin is enabled. Second, it is used to set the virtual location of the motes, when using the LocationPlugin.
Trying it out
OK, now we're ready to try out the various features.
Breakpoint 0 fired: Debug message:  DebugMsgEvent [24: TestTinyVizM: Received message from 13]which simply means that this debug message triggered the breakpoint. Clicking the play button again will resume the simulation, causing the breakpoint to be hit again.
Note that once you restart the simulation, nodes that can no longer communicate (due to no connectivity) will still be sending messages to each other; this is because the TestTinyViz application accumulates a list of nodes to send messages to, but changing the underlying connectivity model does not modify this list. However, if you watch the debug messages from each node, you will notice that nodes are only receiving messages from those nodes they are connected to, as you would expect.
The TinyViz AutoRun feature allows you to "script" the configuration and execution of a TinyOS simulation, by setting parameters in a file that controls TinyViz. This allows you to automatically enable plugins, set breakpoints, run multiple simulations, log data to files, and execute commands both before and after each simulation runs. This is useful when you are using TinyViz as an analysis tool.
Look at the file apps/TestTinyViz/sample.autorun in the TestTinyViz directory. The autorun file specifies one or more simulations to run; a simulation stops either when a specified number of simulated seconds have elapsed (the "numsec" option), when a substring match on a debug message occurs (the "stopstring" option), or when the simulation exits itself (e.g., a crash or deliberate call to exit()). The parameters for each simulation are separated by a blank line. When a parameter is set in the file for one simulation, it will carry forward for subsequent simulations in the file, saving you from having to re-specify parameters for each run.
Here is the sample file:
# This is a sample TinyViz autorun file. To use it, run # tinyviz -autorun sample.autorun # Set the layout layout gridrandom # Enable some plugins plugin DebugMsgPlugin plugin RadioLinkPlugin plugin RadioModelPlugin # Total number of simulated seconds to run numsec 20 # Name of the executable file executable build/pc/main.exe # DBG messages to include dbg usr1 # The radio model and scaling factor to use radiomodel disc100 radioscaling 5 # Number of motes nummotes 10 # Command to run before starting precmd echo "This is a command that will run before the simulation" # File to log all DBG messages to logfile logfile-20.txt # The blank line above indicates that we are starting another simulation # This time run with a different number of motes nummotes 30 logfile logfile-30.txt
The AutoRun file specifies two simulations, one with 20 motes and another with 30. All debug messages are logged to two different logfiles. We enable a few different plugins (specified by the Java class names as they are found in tools/java/net/tinyos/sim/plugins.
To run the simulations with this autorun file, just type:
tinyviz -autorun sample.autorun
TinyViz starts up, enables and configures the appropriate plugins, and automatically runs each simulation for 10 simulated seconds, then exits. You can set up AutoRun to run a series of simulations and then go to lunch -- the data will be waiting for you in your logfiles when you get back.
AutoRun supports a number of features not shown here -- just look at the arConfig class in the tools/java/net/tinyos/sim/AutoRun.javasource file. Note that all options specified in the file that aren't used by AutoRun itself, however they made available to plugins. So, for example, the radiomodel option is interpreted by the RadioModelPlugin to configure the radio model. You can write your own plugins that are configured through AutoRun in this way.
Writing TinyViz plugins
By far the most useful feature of TinyViz is the ability to write your own plugins to interact with the simulation. Writing plugins is beyond the scope of this document, but we wanted to give you a couple of pointers on where to start. Look at tools/java/net/tinyos/sim/plugins/RadioLinkPlugin.javafor a simple, well-documented plugin implementation. Essentially, plugins must provide a method that receives events from the TOSSIM simulation and the TinyViz framework. Plugins react to events by changing internal state, updating the display, or possibly sending commands back into the simulation. TinyViz delivers events to plugins for initialization, debug messages, radio messages, a change in the location of a mote (e.g., when the user moves it), and when new motes join the simulation. Plugins provide additional methods that are called when the plugin is enabled or disabled, as well as when the mote window is redrawn.
Using RadioLinkPlugin.java as an example, it is straightforward
to write your own plugins. Currently, all plugins must be located in the
subdirectory of the TinyViz directory. (In the future we will add support
for a "plugin path"). Note that when you modify a plugin you need to recompile
the tinyviz.jar file by typing
make in the main TinyViz
directory (tools/java/net/tinyos/sim); just typing make in the
plugins directory is not adequate.
This tutorial only covers some of the functionality and usefulness of TOSSIM; for example, as TOSSIM simulates the TinyOS networking stack at bit granularity, radio models can simulate some of the difficult issues that arise. Similarly, one can test and debug low-level protocols (such as start symbol detection) in addition to application components and routing protocols. The TOSSIM System Description goes into greater details on these capabilities and presents some information on TOSSIM's implementation.
< Previous Lesson | Next Lesson > | Top