Lesson 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 7 .
Building and Running an Application

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 to this:

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.
Adding Debugging Statements

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 printf() semantics. For example, open tos/lib/Counters/Counter.ncin your editor. In Timer.fired(), add this line just before the return statement:

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.
Using gdb with TOSSIM

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, ledsOn 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: The TOSSIM User Interface

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.
Getting Started

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:


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.

  1. Startup TinyViz with DBG=usr1, tinyviz -run build/pc/main.exe 30 if it is not already running.
  2. Select the Debug messages, Radio links, and Set breakpoint plugins from the Plugins menu, and resume the simulation by clicking the pause/play button.
  3. Clicking on the Debug messages tab in the control panel will show you all of the debug messages generated by the simulation. Click on a given mote (say, mote 3) then click "Selected motes only" to restrict the display to just that mote.
  4. Type a phrase (for example, "Received") in the box at the bottom of the control panel, then click "Highlight". This will highlight all messages matching the chosen string - very useful for visually scanning for "interesting" messages.
  5. Pause the simulation, then click on the "Set breakpoint" tab. Pull down the bar at the top of the control panel (which says "Current breakpoints") and choose "Add debug message breakpoint". In the "Message contains" box, type "Received message", then click "Enable breakpoint". This will add a new breakpoint that pauses the simulation whenever a matching debug message is printed. Click on the pause/play button to resume the simulation. Very soon afterwards, the simulation will pause and the control panel at the bottom of the screen will print something like
  6. Breakpoint 0 fired: Debug message: [24] 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.
  7. Select "Current breakpoints" from the bar at the top of the control panel. Disable the breakpoint by clicking on it in the breakpoints list, then click "Disable breakpoint".
  8. Select the Radio model plugin from the Plugins menu and click on the "Radio model" tab in the control panel, then pick "Fixed radius (100.0)" from the list of radio models. Drag the mouse across the mote display to select all motes; you will see a very densely-connected mesh, indicating that nearly every mote has connectivity with all others, due to the large radius of the radio model. Type "4" in the "Distance scaling factor" box, then click "Update model". The radio model will be updated -- which may take some time -- and the resulting connectivity mesh will be much more sparse.



    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.

AutoRun - Scripting TOSSIM runs

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 plugins 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.
Further Use

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