Instrumenting Programs in Simulation

A simulator is only as useful as the output it provides about a program as it is running and after it has finished. Imagine a simulator that executed a program from start to finish but never produced any output; it would not provide any more insight into the program's operation than running the program on the hardware.

Avrora allows programs that are running in the simulation to be instrumented so that information can be collected as they execute and statistics reported after they complete. Unlike other simulators that offer a fixed set of statistics or output options that report on a program's execution, Avrora allows users of the simulator to add instrumentation to programs as they run, without modifying either the program source, program binary, or the simulator.

Probes, Watches, Events

The simulator supports instrumenting programs through three basic mechanisms: probes, watches, and events. Probes are instrumentation objects that can be inserted at specific instructions in the program so that they will fire when that instruction is executed. Watches are instrumentation attached to memory addresses in the program that fire before and after reads and writes to specific memory addresses in the program. Events are time-triggered instrumentation that are fired when the simulation reaches a particular point in time, measured in clock cycles.

These three mechanisms offer a complete set of basic instrumentations that can be added to programs, covering all three important quantities in programs: code, data, and time.


Many instrumentation tasks can be accomplished by adding instrumentation code at particular points in the program that is triggered when that part of the program executes. A probe is an a piece of instrumentation that can be added to any instruction in the program. For example, if we are interested in recording all calls to a particular function, we can add a probe to the first instruction in the function. The probe will fire when this instruction executes and can produce output, record the time, or collect statistics about the call that we are interested in.

The simulator exposes an interface that allows users to write probe code that they can insert at various locations in their program. Here is a snippet of the simulator's code that shows the Simulator.Probe interface.

For more information about probes and an example application, see the page on instrumenting with probes.


Watches are inserted at locations in the memory of an executing program, and implement an interface simulator to that implemented by a probe; the Simulator.Watch interface. This interface is nested inside the Simulator class and looks like this:

For more information and an example usage of a watch, see the page on instrumenting with watches.


Avrora's simulator maintains a cycle-accurate notion of time. The simulator allows the user to add instrumentation not only at particular points in the program, but also at particular points in time. The simulator allows the user to add an event to the simulation that will fire at a specific time. The simulator will advance time by executing instructions and simulating devices until it reaches the point in time when the event should fire.

Here is an example of Simulator.Event interface that allows users to add instrumentation at various points during time:

For more information about using events and an example, see the page on instrumenting with events.


Handling interrupts is an important part of a microcontroller application's design. Interrupts may arrive from external pins, may be generated in response to reception of data over a serial port, or may be generated by on-chip devices such as timers or the EEPROM. The program can enable and disable individual interrupts as well. Avrora allows all of these events to be extended with instrumentation code to provide simulation output or compute statistics.

The simulator exposes an interface called a Simulator.InterruptProbe that can be implemented by user code to add instrumentation to particular interrupts. When the probe is inserted on a particular interrupt number, the probe will be notified when the program enables or disables the interrupt, when the interrupt posted or unposted, and before and after the interrupt is invoked (executed).

For more information about using interrupt probes, see the page on instrumenting interrupts.

Finite State Machines

Many hardware devices, both on-chip and off-chip, can be represented as finite state machines where the device is in a particular state until it transitions to another state after some time elapses or in response to an external event. For example, the microcontroller itself can be thought to be either in the active mode executing instructions, or in one of the many different sleep modes. The microcontroller is put to sleep by executing the sleep instruction and is awakened by external interrupts.

Several device implementations contain an explicit finite state machine model in the simulation. These finite state machines are represented by the avrora.sim.FiniteStateMachine, which, like a Simulator, allows probes to add instrumentation to the simulation without altering the behavior. The FiniteStateMachine exposes an interface FiniteStateMachine.Probe that allows users to add behavior to the transitions between states that happen during simulation.

For more information and an example application, see the page on instrumenting finite state machines.

Radio Instrumentation

Radios are the primary communication mechanism in wireless sensor networks. Avrora simulates the radio hardware and its interface to the microcontroller which gives it the ability to simulate entire sensor networks, including the transmission and reception of packets over the radio. Similar to the Simulator and FiniteStateMachine classes, the Radio class exposes an interface called Radio.RadioProbe that allows users to add instrumentation to the operation of each radio device in the network.

Fore more information, see the page on radio instrumentation.