Avrora Architecture"Good performance through good architecture, great performance through great compilers."Avrora has been designed with the goal of a clean, consistent, and flexible architecture from the very beginning. Repeated incremental change and restructuring has given rise to flexibility and extensibly in the areas that matter. This page will walk you through the big picture of the design; more details are always available by browsing the Java API.
In the Beginning was the Program...Avrora is a program analysis framework and simulation tool for programs. It should come as no surprise to find that the core of the design focuses around representing programs in a clean and straightforward way.
Instruction RepresentationEach type of instruction in the AVR instruction set has its own class in Avrora. Instructions of common formats share super classes that collect their functionality together. Instances of these instruction classes represent actual instructions within the program.
The Visitor PatternThe visitor pattern is common where a fixed class hierarchy exists, but extension by adding operations is common. The fixed set of classes in this case are the instruction classes; the operations are interpretation, abstract interpretation, or any other type of per-instruction-class type of operation.
The Core of the Onion: The SimulatorTheavrora.sim Java package contains a set of classes that implement
the simulator. Principal among these is the Simulator class that
implements that encapsulates the notion of an "execution engine" that can execute
an AVR program.
Probing and MonitoringSimply executing a program with no way of inspecting its results or execution is hardly useful. The program's behavior is of interest--either to debug the program, test its correctness, or study its characteristics. For this reason, the simulator exposes an API that allows probes to be inserted into the program that can inspect the state of the entire program. This one simple, powerful interface is used to implement tracing, profiling, or monitoring.
The
The
Time is AsynchronousTheSimulator is cycle-accurate in the sense that it tracks the number of clock
cycles consumed by each executing instruction and at any point records the
correct number of clock cycles that have passed since the beginning of the
simulation. This time information is vital to the correct simulation of
time-variant phenomenon such as the operation of timers or devices connected
to the microcontroller. Each Simulator instance is independent of
others; it has its own local time in clock cycles and runs in its own thread.
Many things about the execution of a microcontroller are dependent upon time. For example, the onchip timers execute "in the background" and trigger an interrupt when they overflow or their counter value matches a compare register. An external device may send data at some time in the future. A serial device might trigger an interrupt when it has completed a transfer.
In the Two good examples of this are the implementation of the timer and timeouts. Timer0 is a hardware timer available on the ATMega family of microcontrollers. It has programmable resolution, an 8-bit count register, and an 8-bit compare register. It is clocked off the main CPU clock with a programmable divisor (i.e. it can run up to full cpu clock speed or as slow as 1/1024th cpu clock speed). The only work it needs to do is increment a counter register when it receives a clock signal. It simply creates a periodic event with the frequency of the divisor and does it work in the event handler.
With asynchronous programming, timeouts are a breeze to program! An event
can simply be inserted into the event queue of the simulator that will be
fired at the desired time in the future. The simulator will run unimpeded
until it reaches that time at which it will fire the event. The event can
simply throw a Java exception (or call /** * TheThen, to use this class, one can just do the following, supposing that simulator
is an instance of Simulator :
// terminate the simulation 200 clock cycles in the future simulator.addTimerEvent(new ClockCycleTimeout(200), 200);
MicrocontrollersTheSimulator represents the core execution engine of a simulation. It contains
an interpreter for all of the instructions in the AVR instruction set, stores the state of
the program including the SRAM, the IO registers, and the general purpose registers, and
manages a delta queue of events. However, real microcontrollers have real devices built into the
chip, and real programs want to use those devices. Another layer of the onion is necessary
that encloses the Simulator , and that is the Microcontroller .
PlatformsJust as theSimulator was a just the engine inside of a Microcontroller ,
the Microcontroller is just an engine inside a real device. Real devices have
electronics hooked up externally to the microcontroller such as simple LEDs, sensors, and
communications devices. All such external devices communicate to the microcontroller through
pins on the physical chip. Again, another layer of the onion is necessary to encapsulate
all of these, and that layer is called the Platform .
|