thesis - plex-svn

advertisement
Embedded Systems Simulator
By
James McGill
The School of Information Technology and Electrical Engineering
The University of Queensland
Submitted for the degree of Bachelor of Engineering (Honours)
in the division of Computer Systems Engineering
5th February 2016
James McGill - 40793625
Embedded Systems Simulator
ii
James McGill - 40793625
Embedded Systems Simulator
5th June 2009
Head of School,
School of Information Technology and Electrical Engineering,
The University of Queensland,
St. Lucia QLD 4072
Professor Paul Bailes,
In accordance with the requirements of the Degree of Bachelor of Engineering (Honours) in
the School of Information Technology and Electrical Engineering, I submit the following
thesis entitled
“Embedded Systems Simulator”
This thesis was performed under the supervision of Dr. Peter Sutton. I declare that the work
submitted in this thesis is my own, except as acknowledged in the text and footnotes, and has
not been previously submitted for a degree at The University of Queensland or any other
institution.
Yours sincerely,
James McGill
iii
James McGill - 40793625
Embedded Systems Simulator
iv
James McGill - 40793625
Embedded Systems Simulator
Dedicated to my friends and family
v
James McGill - 40793625
Embedded Systems Simulator
Acknowledgements
I would like to acknowledge the guidance and support of Dr. Peter Sutton throughout this
thesis, and also thank him for initiating this project. I would also like to thank those who
made the evaluation of this thesis possible by allowing me to collect and use their embedded
systems projects.
vi
James McGill - 40793625
Embedded Systems Simulator
Abstract
Embedded systems are designed to perform specific computing tasks, and therefore often lack
the resources required to allow iterative software development and debugging without
specialized hardware. To overcome these issues, PC based simulators can be used to allow the
behaviour of a digital system to be evaluated and to utilise the debugging capabilities of a PC.
This thesis presents the implementation of a cross-platform C++ framework and application
for performing simulations of digital embedded systems composed of multiple components.
Components are loaded from dynamic libraries, allowing extensions to the system to be
developed independently, and simulated using a discrete event algorithm. The simulators
flexibility has been utilized to develop several components, including an implementation of
the AT90S8515 8-bit AVR microcontroller.
The simulator has been demonstrated to correctly perform perceptually real-time
hardware/software co-simulation of a benchmark system composed of an AT90S8515
microcontroller, clocked at 4 MHz, and several other components, while maintaining an
accurate graphical representation of the system state. Automated testing has been used to
verify the basic functionality of the full AT90S8515 instruction set, as well as the
microcontroller’s Timer/Counters, interrupt and USART peripherals, while structured system
testing has been used to verify that the project meets and exceeds all requirements originally
proposed.
vii
James McGill - 40793625
Embedded Systems Simulator
Table of Contents
Acknowledgements ................................................................................................................... vi
Abstract .................................................................................................................................... vii
Table of Contents .................................................................................................................... viii
List of Figures .......................................................................................................................... xii
1.0 Introduction and motivation ................................................................................................. 2
1.1 Scope ................................................................................................................................ 2
1.2 Outcomes .......................................................................................................................... 3
1.3 Report Outline .................................................................................................................. 4
2.0 Literature review and background information .................................................................... 6
2.1 Discrete event and embedded systems simulation ........................................................... 6
2.2 Event set data structures ................................................................................................... 7
2.3 Development tools............................................................................................................ 8
2.4 Testing methodologies ................................................................................................... 10
2.5 Past theses ...................................................................................................................... 11
3.0 Prior art ............................................................................................................................... 12
3.1 AVR Simulator IDE ....................................................................................................... 12
3.2 Proteus VSM .................................................................................................................. 13
3.3 Atmel AVR Studio ......................................................................................................... 15
3.4 miSim DE ....................................................................................................................... 16
4.0 Goals and project requirements .......................................................................................... 18
4.1 Software architecture requirements ................................................................................ 18
4.2 Required components ..................................................................................................... 19
4.3 Required documentation ................................................................................................ 20
4.4 Performance and portability requirements ..................................................................... 20
4.5 Additional work.............................................................................................................. 21
4.6 Elements considered to be outside scope ....................................................................... 21
viii
James McGill - 40793625
Embedded Systems Simulator
5.0 Implementation of the simulation framework .................................................................... 22
5.1 Architectural overview ................................................................................................... 22
5.2 Components .................................................................................................................... 23
5.2.1 Providing a graphical representation of a components state ................................... 24
5.3 Events ............................................................................................................................. 24
5.4 Pins ................................................................................................................................. 25
5.5 Discrete event simulation ............................................................................................... 27
5.5.1 Enqueuing events .................................................................................................... 28
5.5.2 Simulator timestamp ............................................................................................... 28
5.5.3 Memory management .............................................................................................. 29
5.6 Real-time execution........................................................................................................ 29
5.7 Error reporting ................................................................................................................ 29
5.8 Graphical user interface ................................................................................................. 30
5.9 Cross platform plug-in architecture................................................................................ 31
5.10 Automatic plug-in documentation generation .............................................................. 33
5.11 Persistence of simulation properties using simulation projects.................................... 33
5.11.1 Loading simulation projects .................................................................................. 34
6.0 Implementation of plug-in components ............................................................................. 36
6.1 Atmel AT90S8515 8-bit microcontroller ....................................................................... 36
6.1.1 Common AVR functionality ................................................................................... 36
6.1.2 Instructions .............................................................................................................. 37
6.1.3 Registers and data storage ....................................................................................... 38
6.1.4 Automatic generation of skeleton classes ............................................................... 39
6.1.5 Interrupts ................................................................................................................. 40
6.1.6 Cycle correct execution ........................................................................................... 41
6.1.7 Status register .......................................................................................................... 41
6.1.8 Graphical user interface and debugging functionality ............................................ 42
ix
James McGill - 40793625
Embedded Systems Simulator
6.1.9 Internal AVR peripherals ........................................................................................ 43
6.1.10 EEPROM Peripheral ............................................................................................. 44
6.1.11 AT90S8515 Implementation ................................................................................. 44
6.2 TCP/IP based RS-232 Transceiver ................................................................................. 45
6.3 Speaker ........................................................................................................................... 46
6.4 Additional components .................................................................................................. 47
7.0 Verification of solution ...................................................................................................... 50
7.1 Testing methodologies ................................................................................................... 50
7.1.1 Testing of the complete system ............................................................................... 50
7.1.2 System benchmark .................................................................................................. 52
7.1.3 Automated testing of the Atmel AT90S8515 plug-in ............................................. 54
7.2 Results ............................................................................................................................ 56
7.2.1 Manual testing of components and simulator framework ....................................... 56
7.2.2 Performance ............................................................................................................ 56
7.2.3 Stability ................................................................................................................... 58
7.2.4 AT90S8515 ............................................................................................................. 58
7.3 Functionality and deliverables ....................................................................................... 59
7.3.1 Required components .............................................................................................. 60
7.3.2 Maintainability ........................................................................................................ 60
7.3.3 Documentation ........................................................................................................ 60
7.3.4 Portability ................................................................................................................ 61
7.4 Discussion ...................................................................................................................... 62
7.5 Reflection of project management ................................................................................. 65
8.0 Future work ........................................................................................................................ 68
8.1 Project editor .................................................................................................................. 68
8.2 Improved debugging capabilities ................................................................................... 68
8.3 Automated testing framework ........................................................................................ 68
x
James McGill - 40793625
Embedded Systems Simulator
8.4 Development of additional components ......................................................................... 69
8.5 Improved separation of simulator state from graphical state ......................................... 69
9.0 Conclusion .......................................................................................................................... 70
Appendix A : XML Schema for simulation project files ......................................................... 77
Appendix B : Django templates for AvrInstruction and AvrMemory skeleton classes ........... 79
Appendix C : Manual testing plan............................................................................................ 90
Appendix D : Summary of manual tests .................................................................................. 91
Appendix E : Automated testing command language .............................................................. 95
Appendix F : Python script to save simulator state from AVR Studio .................................... 96
Appendix G : Project progress plan ......................................................................................... 98
xi
James McGill - 40793625
Embedded Systems Simulator
List of Figures
Figure 1: CSSE1000 project board............................................................................................. 9
Figure 2: AVR Simulator IDE with EEPROM and LCD peripherals enabled. ....................... 13
Figure 3: Real time simulation of a graphical LCD in Proteus VSM ...................................... 14
Figure 4: Expanded register view from AVR Studio. .............................................................. 16
Figure 5: Overview of simulator architecture .......................................................................... 23
Figure 6: Cyclic notification problem. ..................................................................................... 26
Figure 7: Transitive pin connections. ....................................................................................... 26
Figure 8: Simulator graphical user interface. ........................................................................... 31
Figure 9: Documentation automatically produced for the switch component. ........................ 33
Figure 10: AT90S8515 class architecture ................................................................................ 37
Figure 11: Demonstration of operands within an opcode (MOV opcode) ............................... 38
Figure 12: AVR address segments for an AT90S8515. ........................................................... 39
Figure 13: Conditions required for an interrupt to be triggered. .............................................. 41
Figure 14: The AVRCore debugging window. ........................................................................ 43
Figure 15: Detection of incorrect baud rates during simulation............................................... 46
Figure 16: Formula for conversion between frequency (Hz) and MIDI Note ID .................... 47
Figure 17: Simulation of an 80 character LCD, driven by an AT90S8515 microcontroller. ... 48
Figure 18: Simulator error, as identified by the automated project testing framework. .......... 51
Figure 19: Hardware used by the Tetris benchmark. ............................................................... 53
Figure 20: Simulation of the Tetris benchmark. ...................................................................... 53
Figure 21: Output from the AVR Testing Framework. ............................................................ 55
Figure 22: Error between simulation time and wall clock time over 150mS. .......................... 57
Figure 23: Error between simulation time and wall clock time over 9 seconds ...................... 58
Figure 24: Frequency distribution of total instruction coverage (calls) over all automatic tests.
.................................................................................................................................................. 59
Figure 25: Simulator running on Ubuntu Linux (a) and Mac OS X 10.5 (b)........................... 61
Figure 26: Comparison of simulator speed on multiple operating systems. ............................ 62
xii
James McGill - 40793625
Embedded Systems Simulator
List of Tables
Table 1: Pin value protocol. ..................................................................................................... 25
xiii
James McGill - 40793625
Embedded Systems Simulator
1
James McGill - 40793625
Embedded Systems Simulator
1.0 Introduction and motivation
Embedded systems computing is a broad field, encompassing the development of all digital
systems developed to perform specific computing tasks [1]. The narrow focus on functionality
within embedded systems means that they often lack the resources required to allow iterative
software development and debugging without expensive tools [2]. These systems also often
require the design and manufacture of specialized hardware to be completed before software
can be tested. To overcome these issues, PC based simulators can be used to allow the
behaviour of the system to be evaluated prior to construction, and to utilise the debugging
facilities of a PC, such as a monitor and keyboard.
While many programs capable of simulating embedded digital logic already exist [3,4,5] they
are often targeted at professionals and are difficult to use or prohibitively expensive.
Additionally, few of these products are able to simulate a microcontroller executing code as
part of a system consisting of multiple peripherals, such as switches or Liquid Crystal
Displays (LCDs).
The need for those new to the development of embedded systems to be able to easily develop
and test systems without incurring an unreasonable level of expense led to the proposal by Dr.
Peter Sutton and Mr James McGill to develop an extensible embedded systems simulator.
1.1 Scope
The proposed software is intended to support fast and accurate simulation of systems
composed of multiple simulated digital electronic components, while remaining flexible
enough to allow additional components to easily be developed. The state of the simulation is
2
James McGill - 40793625
Embedded Systems Simulator
intended to be displayed using a graphical interface, providing a simple method for
developers to interact with the system under simulation.
Accurate simulation of analogue components, or of the effects of capacitance, resistance and
inductance on digital logic, is considered to be outside the scope of the project, as is the
development of a schematic editor for the simulator.
A more detailed examination of the goals of the project is presented in Chapter 4.0.
1.2 Outcomes
A simulation framework has been developed which is able to perform fast and accurate
simulations of systems composed of multiple components. The framework allows additional
simulated components to be developed independently and dynamically loaded as required.
The state of the system is represented using an extensible Graphical User Interface (GUI)
which, combined with real-time simulation speeds, allows users to interact with the system in
a way that is consistent with the use of the system’s physical counterpart.
In order to demonstrate the usefulness of the framework, several simulated components,
including an Atmel AT90S8515 microcontroller, have been developed. Structured testing has
been used to demonstrate that these components function correctly. In addition,
documentation in the form of tutorials and an instructional video has been developed to assist
those seeking to use or extend the simulator.
3
James McGill - 40793625
Embedded Systems Simulator
The framework and components developed compile and run on multiple operating systems,
including Windows XP, Mac OS X and Linux. The full source code for the software
developed is available on a CD-ROM which accompanies this document.
1.3 Report Outline
The remainder of this document is used to discuss the theory behind, and implementation of,
the embedded systems simulator. Chapters 2 and 3 provide a review of the academic literature
relevant to the development of the simulator, as well as a review of the prior art in this field.
Chapter 4 outlines the specific goals and requirements put in place before the development of
the simulator, Chapters 5 and 6 present the methods used to implement the simulator
framework and several component plug-ins, and Chapter 7 outlines the steps used to test the
simulator and plug-in components, and evaluates the success of the project. Chapter 8
proposes a number of possible extensions to the work completed thus far, presenting possible
future avenues for research in this area. A detailed summary of the project’s goals,
implementation, and outcomes is included in Chapter 9.
4
James McGill - 40793625
Embedded Systems Simulator
5
James McGill - 40793625
Embedded Systems Simulator
2.0 Literature review and background information
In order to ensure that the simulator is able to perform as efficiently as possible, this thesis has
built upon the prior work and research of many people. An examination of this literature has
served as a key component in the evaluation of alternative implementation methods. The most
relevant literature and background information relating to this thesis is presented in the
following sections.
2.1 Discrete event and embedded systems simulation
Discrete event simulation, a simulation method in which the model for the system being
simulated is updated only at discrete intervals of time [6], is one of the most common
methods for simulating digital systems [7]. This technique lends itself particularly well to
functional simulations of synchronous systems because of the discrete nature of clock driven
events, but can also be used to approximately model continuous systems [6].
Simulation of digital systems can either achieve functional accuracy, in which the each
simulated component behaves as a black box and only the inputs and outputs are simulated
correctly, or can simulate the system at the gate level, in which the exact behaviour of each
component, including the timing of internal events, is simulated accurately [8,9]. Although
hardware can be used to achieve real time low level simulation and verification of digital
systems, simulating the same level of detail in software incurs significant time penalties,
making real time simulation impossible [10]. However, for simple systems, the timing
information extracted from functional simulation may approximate that expected from low
level simulations, allowing faster simulation with a similar level of accuracy [8]. When
primarily investigating the results of hardware and software interacting in co-simulation, as is
the goal of this thesis, describing each component at a functional level, rather than a gate
6
James McGill - 40793625
Embedded Systems Simulator
level, is expected to give the greatest chance of the simulator being able to perform at realtime speeds [10].
In order to achieve faster simulation times, a number of techniques have been proposed which
reduce unnecessary computations during the simulation of embedded systems. In their paper
Muhr and Holler [11] identify that, even in functional simulation, simulation speed decreases
significantly as the clock speed of the system under examination increases. In order to achieve
near real-time simulations of digital systems with high clock speeds they propose a model by
which the future state of part of the system can be interpolated for periods of time over which
the inputs remain stable, and the effects of a change on the output remains constant [11].
Gauthier and Jerraya [10] suggest a similar method for improving performance through data
suppression, in which the state of various subsystems in a microcontroller are not updated
during the simulation if transitions to future simulator states can be shown to occur
independently of this value.
Simulation of an embedded system may also be performed using a stochastic model which
defines the probability of transitioning to a specific state [12]. While suitable for modelling
the expected performance of a system, this method cannot be used to develop a consistent and
reliable model of a system’s behaviour.
2.2 Event set data structures
An event set is an abstract data structure used in discrete event simulation to maintain a list of
events to run, ordered by their scheduled time of execution [13]. The event set
implementation plays a key role in determining the speed of the simulator, with event set
manipulation expected to take up to 40% of the simulation processing time in most cases [14].
7
James McGill - 40793625
Embedded Systems Simulator
The simplest implementation of an event set is a linear linked list of events, which can
enqueue an item in O(n) time and dequeue it in O(1) [14]. Owing to the simplicity of this
algorithm, link lists demonstrate the best performance of all event set algorithms when the
event set never grows beyond 20 items [14]. More complex algorithms, such as Calender
Queues [15] and MLists [16], are able to make use of multiple data structures in order to
address the need for faster simulation event set operations. Both are expected to achieve O(1)
amortized execution times by taking advantage of the discrete nature of events in discrete
event simulations, and therefore bucketing scheduled execution times. Unfortunately, the
overhead required to perform this means that these implementations only perform well on
large sets of events.
2.3 Development tools
When attempting to undertake any software development project, it is first necessary to
understand the capabilities and limitations of the available development tools.
In order to ensure that the simulator can be used on multiple platforms, thought must be given
to the choice of programming language and libraries. While writing the simulator instructions
in an assembly language may allow it to achieve greater speed [17] it would do so at the
expense of portability. Languages such as Java and C# overcome this problem by compiling
to intermediate byte code which can be executed on any platform with a suitable virtual
machine. Unfortunately, as noted by Vogels [18] this comes at the expense of performance,
with execution times for common high performance computing tasks varying erratically in
Java and C# and rarely approaching those available in compiled languages such as C and
C++. The performance of these languages has also been shown to vary depending on the
quality of the virtual machine implementation, making it unlikely that a simulator written in
8
James McGill - 40793625
Embedded Systems Simulator
either of these languages would be able to sustain high simulation speeds on multiple
platforms.
Kilgore [19] and Thompson and Billawala [20] note that the entities involved in a discrete
event simulation are best represented in object-oriented languages in order to provide for
maintainability and to allow for future developers to extend their functionality. This,
combined with the findings of Phillips and Phillips [17] and Vogels [18], suggests that a
simulator will achieve the greatest balance of performance and maintainability if developed in
a compiled object-oriented language such as C++.
An understanding of the system being simulated is also required before development begins.
Documentation of the behaviour of the AT90S8515 AVR microcontroller, selected as a
suitable target for simulation, will be extracted from the datasheet provided by Atmel [21]. In
order to verify the functionality of this component, its behaviour will be compared to the same
processor running as part of the Atmel AVR Project Board used by the University of
Queensland to teach embedded systems (Figure 1) [22]. The expected behaviour of additional
components will be determined by examining their behaviour and datasheets.
Figure 1: CSSE1000 project board
9
James McGill - 40793625
Embedded Systems Simulator
2.4 Testing methodologies
Verification of the solution developed will form an integral part of this thesis. By employing
structured testing methodologies, accurate claims can be made regarding the correctness of
the simulator and components developed, and their suitability for use by developers. Of the
various testing methodologies examined, black box testing and system testing are expected to
be the most useful.
Black box testing is a testing methodology which examines only the expected functionality of
a system, ignoring specific implementation details [23]. This makes this method ideal for
testing functional implementations of simulator components. Black box testing can also make
use of automatically generated test inputs to help identify misunderstood or missing
requirements [24]. Testing the software at the software component level [25] allows errors in
individual modules to be detected, while employing a level of testing complexity that is
achievable within the timeframe of this thesis.
System testing, in which the program is tested as a single complete entity, examines the
software at a higher level. This ensures that the individual components of the program are
able to be integrated in order to produce a stable and correct solution [25].
Automation of these testing processes leads to a reduction in the effort required to perform
tests, making it easier to frequently test for, and locate, errors [23,25]. This allows the tests to
be used to identify regression errors as they are introduced. However, as noted by Goodliffe
[25] manual testing strategies are still required to evaluate the usability of the software.
10
James McGill - 40793625
Embedded Systems Simulator
2.5 Past theses
In their treatment of this same thesis topic, Kehl, Nixon and Reynolds [26,27,28] each
successfully employed discrete event simulation to functionally simulate the AT90S8515
microcontroller at speeds above 4MHz, thus demonstrating the feasibility of this method.
Although the use of C by Kehl [27] and Nixon [28] would have increased efficiency, it led to
difficulties maintaining and extending the simulator. In comparison the use of Java by
Reynolds [26], while simplifying extensibility, limited the performance of the simulator,
requiring compromises in the accuracy of the simulation in order to achieve real-time speeds.
The outcomes and limitations of these implementations are expected to play a large role in
guiding the design and implementation of this thesis.
11
James McGill - 40793625
Embedded Systems Simulator
3.0 Prior art
Given the complexity of modern embedded systems, and the need for embedded devices to be
developed both quickly and reliably, it is unsurprising to find that a number of
implementations of embedded systems simulators already exist.
The following section
presents an inspection and analysis of the most relevant of these products, with a focus on
those capable of simulating Atmel AVR microcontrollers. This provides a useful survey of
simulation methods and feature sets, which are able to serve as an important source of
inspiration.
3.1 AVR Simulator IDE
AVR Simulator IDE [5] is an entry-level commercial Atmel AVR simulator developed by
Oshon Software and licensed for €29 (approximately $40 AUD). The product is able to
simulate a wide variety of Atmel chips, although it is currently unable to simulate the more
recent additions to the AVR line.
AVR Simulator IDE is also able to provide functional simulation of the interaction between
an AVR microcontroller and a wide range of analogue and digital peripherals, including
UART, I2C EEPROMs and analogue function generators. The main IDE acts as an ActiveX
server, allowing the functionality of the program to be extended by 3rd part components.
Oshon Software also develop Microchip PIC and Intel 8051 simulators with similar interfaces
and feature sets, suggesting that the base code was designed to be extensible with regards to
processor instruction sets and functionality, and highlighting the advantages of such
extensibility.
12
James McGill - 40793625
Embedded Systems Simulator
Unfortunately, AVR Simulator IDE is unable to achieve real time execution speeds, with
execution using the simulator being four orders of magnitude slower than execution on the
chip itself. This makes debugging of most components extremely time consuming, and
prevents developers from easily interacting with the system.
The interface (Figure 2) is difficult to navigate, and appears to be targeted at experienced
developers. Interpreting the information contained within internal and external data stores
such as EEPROM and SRAM requires manual translation from hexadecimal values.
Figure 2: AVR Simulator IDE with EEPROM and LCD peripherals enabled.
3.2 Proteus VSM
Proteus VSM [4] is a commercial product which allows software verification of both circuit
and software functionality through all stages of the design of an embedded system. The
product makes use of SPICE mixed-mode simulation, combined with functional models of a
13
James McGill - 40793625
Embedded Systems Simulator
number of microcontrollers, to accurately simulate the interaction between external
components and microcontrollers in real time. The use of SPICE mixed-mode simulation
allows Proteus VSM to accurately model the steady state and transient analogue and digital
behaviour of any embedded system. Proteus VSM also provides high-level language
debugging facilities for microcontroller code, and is packaged with thousands of peripheral
implementations.
The product demonstrates the potential for real time functional simulation, and also provides
an excellent example of the value inherent in accurate real time simulation of peripherals as it
provides the ability to observe the behaviour of components, such as LCDs (Figure 3), by
visual inspection, rather than code or register analysis.
Individual licenses for Proteus VSM, however, cost in excess of $600 AUD, which makes it
unlikely that the product would be adopted for use by students or hobbyists. Additionally, as
Proteus VSM is closed source, developers cannot extend the functionality of the simulator.
This places a significant limit on the types of embedded systems which can be simulated.
Figure 3: Real time simulation of a graphical LCD in Proteus VSM
14
James McGill - 40793625
Embedded Systems Simulator
3.3 Atmel AVR Studio
Atmel AVR Studio 4 [3] is an Integrated Development Environment for Windows, provided
by Atmel to facilitate the use of their range of 8 bit microcontroller devices. AVR Studio
provides a project management system for code development, and integrates with a variety of
compilers.
AVR Studio also provides debugging functionality which includes a cycle accurate simulation
of a number of microcontrollers. Unfortunately, the program is unable to achieve real time
simulation, although real time debugging is available with the use of external hardware
devices [29]. The simulator also lacks any built-in peripheral implementations, making it
difficult to determine the behaviour of software in the context of a larger system.
By combining the debugger with an Integrated Development Environment, AVR Studio
allows embedded Atmel AVR software to be debugged on a standard PC. The interface also
allows the internal state of all memory locations to be read, and provides a significant amount
of meta-data for each location (Figure 4).
AVR Studio can be extended to incorporate descriptions of additional microcontrollers by
editing XML files; however the files must conform to a strict schema and are therefore unable
to represent microcontrollers with features beyond those represented by the current line of
Atmel AVRs. It also provides a plug-in system which could be used to integrate additional
peripherals; however their operation will be limited by the speed of the simulator. The
development of these peripherals is also strictly controlled by Atmel, and as such very few
have been developed to date.
15
James McGill - 40793625
Embedded Systems Simulator
Figure 4: Expanded register view from AVR Studio.
3.4 miSim DE
miSim DE [30] is a Java based simulator which is able to support real time simulation of a
PIC microcontroller, with several peripherals, at speeds exceeding 4 MIPS. This product
demonstrates the ability to write a high performance simulator with many of the features
specified in the requirements of this thesis, with a high level Object Oriented language.
Peripherals can be added to the system by utilizing a publicly available Java API. This
flexibility has been used by third-party developers to extend the functionality of the system by
developing additional simulator components. The simulator also supports debugging, as well
as assembly and disassembly of PIC programs. miSim DE, however, is limited to use with
PIC microcontrollers, and is unable to simulate systems with other microcontrollers, no
microcontroller or more than one microcontroller.
Although the project used to be open source, the source code to the latest release has not been
made publicly available. The source code of older versions, however, may serve as a useful
insight into existing microcontroller simulator methods.
16
James McGill - 40793625
Embedded Systems Simulator
17
James McGill - 40793625
Embedded Systems Simulator
4.0 Goals and project requirements
The primary goal of this thesis is to produce an implementation of an extensible embedded
systems simulator which is able to be used by developers to easily interact with a simulated
embedded system. As a demonstration of the functionality of the system, project developed as
part of the Introduction to Computer Systems course (CSSE1000) at the University of
Queensland will be executed using the simulator. The product presented at the end of this
thesis should therefore be capable of a cycle correct functional simulation of the full
instruction and register set of the Atmel AT90S8515 microcontroller, as well as several other
electrical components which are used in this course. The simulated versions of these
components should be able to be connected together to form a complete embedded system.
In order to provide feedback to the user that is representative of the manner in which the
actual system would perform, the simulator should support simulation of simple embedded
systems at real-time speeds. The simulator must also be able to provide a graphical
representation of each component in the system, which is updated frequently enough to
convey changes in the state of the components, and to maintain responsiveness. In addition to
providing representations of simple digital signals, the simulator must also provide
representations of open drain (tri-state) drivers and weak signals, as they are used to
implement common embedded systems communication protocols such as the 1-Wire Interface
[31].
4.1 Software architecture requirements
The final implementation should provide a system which allows both synchronous and
asynchronous external components to be easily developed, independently of the core
simulator and of each other, and to interact with other components during simulation. These
18
James McGill - 40793625
Embedded Systems Simulator
components should be available in a format that is easy to distribute, and each component
should be able to be used in multiple simulation projects.
4.2 Required components
By the completion of the thesis, a number of peripheral components must be developed in
order to demonstrate the functionality of the simulator. These components were selected
based on those available to students in CSSE1000, allowing the projects developed in this
subject to be used to test the simulator. Specifically, the following peripherals will be
implemented:

AT90S8515: The AT90S8515 is an 8 bit microcontroller produced by Atmel, which
is capable of running at 8 MIPS and which incorporates a number of integrated
peripherals [21]. The implementation should include the full instruction set of the
AT90S8515, as well as the simulation of its internal peripherals such as timers,
counters, PWM, persistent storage via EEPROM and interrupts.

External RS-232 Transceiver: A component which emulates the function of an
external RS-232 transceiver, able to receive and transmit data using the RS-232
communications standard [32]. The component should be able to detect errors in
transmission, including incorrect baud rates. The component should also be able to
communicate with applications outside the simulator, to simulate the interactions
between an embedded system and an external device, such as a PC.
19
James McGill - 40793625

Embedded Systems Simulator
LED Matrix: A 15 x 8 matrix of single colour common cathode LEDs as used by
CSSE1000 [33]. This component should incorporate the behaviour of the additional
circuits used to drive the matrix, such as the 3 to 8 binary decoder.

Speaker: A simple monotone speaker, capable of producing audible tones based on
the frequency at which its two inputs are being toggled between digital states.
4.3 Required documentation
In order to facilitate the use and future development of this system, it will be necessary to
document the solution developed. Documentation of the design decisions used in developing
the product will form a part of the final report. Documentation will also be written for those
using the simulator, and those who wish to extend it by developing additional components.
The source code which makes up the simulator core will be thoroughly commented to ensure
that it can be maintained.
4.4 Performance and portability requirements
The final product must be able to perform real-time simulations of a digital system composed
of a 4MHz Atmel microcontroller and several other components, on a 2.4GHz PC running
Windows XP. The product should also be able to be compiled and run under other
environments, such as Mac OS X and Linux. This will impose restrictions on the use of
software libraries that are only available for a single operating systems, but will allow the
program to be accessed by a greater number of users.
20
James McGill - 40793625
Embedded Systems Simulator
4.5 Additional work
An additional and optional extension to the project will be the incorporation of debugging
functionality for the AT90S8515 component. This will allow software being executed on the
Atmel to be debugged in the context of the hardware environment in which it is run.
4.6 Elements considered to be outside scope
During the development cycle of a single project, it is likely that the composition of any
software will change much more frequently than the hardware on which it is being deployed.
The development of a schematic editor is therefore considered outside the scope of the
project. Changes to hardware specifications will be made by manually editing project files.
Accurate simulation of analogue components, or of the effects of capacitance, resistance and
inductance on digital logic, is also considered to be outside the scope of the project.
21
James McGill - 40793625
Embedded Systems Simulator
5.0 Implementation of the simulation framework
The simulation framework has been designed to be simple and fast, so that components can be
simulated at real-time speeds. Care has been taken to avoid complicating the simulation
framework in order to support specific components, instead ensuring that components can
extend the simulator’s behaviour with very few limitations. The remainder of this chapter
details the architecture and implementation of this framework, and highlights the key design
decisions which have made this speed and flexibility possible.
5.1 Architectural overview
Simulations are performed based on the logic contained within three classes of objects;
Components, Events and Pins. Components define the logic required to simulate a specific
digital device, such as a microcontroller or logic gate, Events are used to schedule logic to
occur at a particular time in the simulation, and Pins are used to enable Components to
interact with each other. The implementations of these classes are discussed in Sections 5.2 –
5.4. The actions of these classes are co-ordinated by a discrete event simulation algorithm,
described in Section 5.5. Simulations can be distributed and repeated by loading their details
from XML files which implement the simulation project schema, as discussed in Section 5.11.
To allow developers to independently define the behaviour of additional devices, Components
are loaded dynamically from a cross-platform C++ plug-in. The design challenges which were
overcome in order to allow these libraries to be written once, and compiled on multiple
operating systems, are examined in Section 5.9.
An overview of this architecture is presented in Figure 5.
22
James McGill - 40793625
Embedded Systems Simulator
Connection
Pin
..
.
..
.
Component
Pin
Component
Pin
Pin
Plug-in
Plug-in
Plug-in boundary
Event
Event
Event
Event
Graphical User
Interface
Event
Event list
Repeated
Event List
Discrete Event Simulator
Figure 5: Overview of simulator architecture
5.2 Components
The logic required to simulate and describe a digital device is implemented by extending the
abstract Component interface. In addition to defining the required structure of a Component
object, the Component class provides an API, which can be used to manage interaction with
the simulator framework, Pins, and component meta-data. Components are expected to
facilitate functional, rather than gate level, simulation of an embedded device. This allows the
behaviour of a device to be abstracted, reducing computational complexity.
23
James McGill - 40793625
Embedded Systems Simulator
Components are invoked directly by the simulator framework on initialization, when the
simulation is started, paused or stopped, and in response to user interaction (such as clicking
on the GUI). As these events occur infrequently, the majority of a Component’s execution is
expected to be invoked indirectly by Event objects, in response to a scheduled event being
executed, or by Pin objects in response to a change in an input value.
5.2.1 Providing a graphical representation of a components state
Component objects provide logic to render a graphical representation of a component’s
current state, using the Cairo graphics library [34]. A number of rendering options, including
the Gimp Drawing Kit (GDK) [35], Cairo, and using pre-rendered graphics, were examined.
Cairo was chosen as it provides a cross platform method of drawing complex vector and raster
graphics onto a variety of image surfaces, including the GUI. The Cairo API is richer than
that offered by GDK [36], and unlike pre-rendered graphics, allows the component
representation to be dynamically adjusted in response to changes in state.
The graphical representation of each Component is redrawn only in response to a change in
the components state, ensuring that the least amount of processing time possible is used to
maintain an accurate graphical representation of the system.
5.3 Events
Components are able to schedule logic to be executed at a specific time by implementing
concrete versions of the Event interface. Events are executed in a monotonically increasing
order based on the time at which they are scheduled, which ensures that simulations are stable
and deterministic. Ordering of events is performed by a discrete event simulation algorithm,
discussed further in Section 5.5.
24
James McGill - 40793625
Embedded Systems Simulator
5.4 Pins
Within a simulation project, as in a physical circuit, components are able to interact by
modifying the values on their output pins, and responding to changes in the values of their
input pins. The values of pins, and the connections between them, are managed by Pin
objects, each of which is expected to be a member of a single Component.
To ensure consistency, components must interpret the values of pins according to the protocol
outlined in Table 1.
Value / range
Meaning
0
Strong logical 0
1
Strong logical 1
2
Tristate (Disconnected)
3
Weak logical 0 (Pull down)
4
Weak logical 1 (Pull up)
Table 1: Pin value protocol.
Adhering to this protocol, and ensuring that each Component’s behaviour is consistent with
that of the physical device which it represents, allows components developed by different
parties to interact correctly. A decision was made not to allow arbitrary values on pins, which
could be used to pass messages between components, as it prevents component re-use.
The protocol allows for the representation of strong, weak and tri-state drivers, in order to
allow communication using open drain protocols such as OWI [31], and allows pins to be
configured as inputs, outputs or both. When a pin is driven by multiple signals, the net pin
value is automatically resolved by the simulator.
25
James McGill - 40793625
Embedded Systems Simulator
Each Pin’s value is stored as 16-bit value, allowing the protocol to be extended in the future.
This could be used, for example, to allow simple analogue devices to be simulated.
Each Pin implements both a Concrete Subject and Concrete Observer from the Observer
design pattern [37], which is used to update the value of a Pin when the value on a Pin to
which it is connected changes. If the value of a Pin changes in response to an update message,
a second update message will not be issued. This increases the speed of the simulation by
preventing cyclic notification (Figure 6) but requires that transitive connections be avoided
(Figure 7). This is achieved as a result of using electrical nets to specify connections in the
simulator project format.
Pin A
Value: 0  1
aVasd asd as
a
Notification: Value = 1
Notification: Value = 1
Pin B
Value: 0  1
aVasd asd as
a
Figure 6: Cyclic notification problem.
The two components will continue to notify each other indefinitely unless terminated.
Val
Pin A
Val
Pin B
Pin A
Pin B
Pin C
Pin C
(a)
(b)
Figure 7: Transitive pin connections.
The transitive connection between Pin B and Pin C in (a) must be explicitly defined, as in (b),
for correct simulation.
26
James McGill - 40793625
Embedded Systems Simulator
Concrete Pin objects are able to implement custom logic which is executed in response to a
change in value. This is used in the AT90S8515 component to implement external interrupts
and in digital logic gates to re-evaluate their output in response to external stimulus.
5.5 Discrete event simulation
Simulations are co-ordinated using a discrete event simulation algorithm, which models the
system by executing the logic contained within Event objects in a strict time order. This
algorithm was selected over alternatives, such as statistical simulation, as it can be used to
produce deterministic simulations, allowing the behaviour of the system to be accurately
evaluated. The implementation of the event set, used to order events within the simulator
algorithm, builds upon the work of Goh and Thng [16] on the use of multiple lists to improve
event set performance.
The majority of events are stored in a priority queue, ordered by the simulator time at which
they are to be executed, and are added and removed as required. As it is expected that the
simulator will often be used to simulate synchronous components, a separate event set is
provided for events which are repeated regularly (Figure 5). Events added to the repeated
event set need only be added once, and are then executed at regular intervals based on their
clocking speeds. Use of this technique reduces the significant overhead required to reschedule an event each time a synchronous device is clocked while retaining the flexibility
and range of a single event list. Empirical testing has shown that the use of a separate queue
for synchronous events accounts for a 150% – 200% speedup in simulations involving the
AT90S8515 microcontroller. An important property of this solution is that it is able to support
multiple synchronous components by polling the regular event list at an interval equal to the
Greatest Common Divisor (GCD) of the repeating periods of the components in the list. This
27
James McGill - 40793625
Embedded Systems Simulator
solution incurs very little overhead when a large GCD can be found, but deteriorates as the
GCD approaches 1.
The inner loop of the simulator is responsible for interlacing events from the two event sets,
and ensures that events are always executed in the correct order.
5.5.1 Enqueuing events
Events are scheduled by passing concrete instances of the Event interface to the simulator
core using the simulator API. This is expected to occur on initialization, in response to the
execution of an event, or as a result of the change in the value of a pin. The type of event
queue to which the Event object is to be added – repeated (synchronous) or normal – is
specified by the API call.
5.5.2 Simulator timestamp
Each event is scheduled with a resolution of one deca-picosecond, stored as a 64 bit unsigned
integer which measures the simulation time elapsed since the start of the simulation. This
allows simulations between ten picoseconds and 5.85 years to be performed. A resolution of
10 picoseconds allows a synchronous component to be clocked at 100 GHz, while still
allowing the reliability of a long running (5.85 year) embedded system to be examined.
Although both a higher resolution and longer simulation times would be desirable, the
associated decrease in performance and increase in complexity required to store the simulator
as a user-defined data type was considered too great a cost.
The simulator timestamp can also be used by Component and Pin objects to verify the timing
characteristics of digital devices, such as setup and hold times.
28
James McGill - 40793625
Embedded Systems Simulator
5.5.3 Memory management
To avoid the computational expense of allocating and freeing the memory used to store an
Event, Event objects are designed to be allocated once and re-used often. The simulator is
specifically designed to allow an Event to be re-scheduled, even while being executed, which
allows simulations to be performed which require no explicit memory management during
execution.
5.6 Real-time execution
A simulation is considered to be executed at real-time if the current value of the simulator
timestamp is constrained to be equal to the amount of wall clock time that has elapsed since
the simulation began. This constraint can only be met if it is possible to carry out the
simulation faster than real-time; however the simulation algorithm is guaranteed to produce
correct and stable simulations regardless of CPU speed. By removing the real-time constraint,
low activity simulations can be carried out at higher speeds, providing an efficient method for
testing the long term reliability of an embedded system [25].
As the simulator is not designed to run on a real-time operating system, small fluctuations in
speed have been deemed acceptable.
5.7 Error reporting
The simulator API provides a mechanism for Components to report errors, such as invalid
inputs or timing violations. These errors are aggregated and logged during the simulation, and
can be viewed from a log file, or from the graphical user interface once the simulation is
complete. This offers a significant advantage over traditional methods of debugging
29
James McGill - 40793625
Embedded Systems Simulator
embedded systems, as Components can automatically detect and report common errors and
timing violations.
5.8 Graphical user interface
A Graphical User Interface (GUI) is used to allow users to control the simulation, and to
display the current state of each component (Figure 8). The use of graphical representations of
components allows users to interact with components in a way that is consistent with a
physical device; for example, an LED can be observed to be lit or unlit, and a switch can be
pressed using a computer mouse. The GUI is created using the GTKmm C++ bindings to the
Gnome ToolKit libraries [38]. This library was selected over other cross platform alternatives
such as wxWidgets [39] and Qt [40] as it is open source, actively maintained, and was found
to be the easiest to use.
The GUI uses the Model-View-Controller pattern [37] to allow the simulator to be controlled,
and its current state represented in the GUI, while allowing re-use of the simulator logic with
alternate user interfaces. Components may also spawn additional GUI windows, allowing the
representation of additional information that is not easily included on the main user interface.
To ensure that the GUI remains responsive, but does not consume too many resources, it is
executed on its own, lower priority, thread.
30
James McGill - 40793625
Embedded Systems Simulator
(a)
(b)
Figure 8: Simulator graphical user interface.
Showing the simulator log (a) and displaying the current state of 8 LEDs and 8 switches (b).
5.9 Cross platform plug-in architecture
The simulator makes use of a cross platform plug-in architecture in order to achieve the goal
of allowing additional components to be developed and distributed independently of each
other, and of the core framework.
The plug-in framework implemented is based on the work of Sayfan [41] and has been
extended to provide explicit operating system versioning, fast messaging across the plug-in
boundary by using explicit function calls in favour of message passing, and faster runtimes by
focusing on dynamic loading of C++ objects, and discarding support for C objects and static
compilation in released components. Each plug-in provides a concrete implementation of a
Component, as well as supporting Pin and Event objects.
31
James McGill - 40793625
Embedded Systems Simulator
Plug-in libraries are expected to be stored in a single folder, and are enumerated when the
simulator is initialized. This provides a simple method of redistributing and installing
components. The Gnome Module library[38] is used to load the dynamic libraries and execute
their exposed C methods independently of the host operating system and library format. As
Unix-like operating systems provide no direct support for exporting C++ class definitions as
part of a dynamic library, the C++ Component objects used are created and destroyed using a
C API, which can be safely exported on all target operating systems.
The simulator uses the definition of the Component interface to interpret the structure of the
object returned by the C API. The simulator and plug-in must therefore have a common
definition of the Application Binary Interface (ABI) for a Component. A common ABI is
unlikely if the simulator and plug-in are compiled with different compilers, or different
versions of the same compiler. Furthermore, changes to the Component class structure will
necessitate recompilation of all plug-ins. While undesirable, this is expected to happen very
rarely as the component API is now finalized.
To allow the plug-in to be compiled independently from the simulator framework, it must not
depend on aspects of that framework. Each component therefore only depends directly on a
small library which defines the Component, Event and Pin classes. Components communicate
with the core simulator framework using a C API which is passed as a set of function pointers
to each plug-in upon instantiation. The use of function pointers allows the component to be
compiled with only the definitions of the API function prototypes, without depending on their
implementations.
32
James McGill - 40793625
Embedded Systems Simulator
5.10 Automatic plug-in documentation generation
As documentation is a key goal of this thesis, the Component interface was carefully designed
so that the implementer of a class extending Component must provide enough information to
fully document that classes use as a simulated component. This information has been used to
automatically generate navigable HTML documentation for each component (Figure 9) which
is expected to benefit the authors of simulator projects.
Switch
A simple switch, with an active high output.
Properties
Name
Description
Default value
type Type of switch: Push or Toggle
Toggle
Pins
Name Index
Output
0
Figure 9: Documentation automatically produced for the switch component.
5.11 Persistence of simulation properties using simulation projects
A simulation project is an XML file format used to store the information required to enable a
system to be simulated. The use of simulation projects ensures that the system to be simulated
can be easily shared; as all the information required to reproduce a simulation, given a
suitable set of plug-ins, is encapsulated within a single file. The project stores the names and
33
James McGill - 40793625
Embedded Systems Simulator
properties of the components involved in the simulation, the connections between these
components, and the position of each component on the user interface.
Initially projects were stored in a custom serialization format, however this proved to be error
prone, and difficult to maintain. XML [42] is now used as the basis for the simulation project
format as it is a well understood serialization language, with support for parsing, writing and
verification available in multiple programming languages. This support ensures that
additional tools which would interact with the format, such as an interactive editor, can easily
be developed if required. XML is also human readable and editable, allowing projects to be
developed using only a text editor, an important consideration as developing an interactive
project editor is outside the scope of this thesis. As the size of projects is not expected to be a
concern, the verbosity of XML was determined to be an acceptable trade-off. Other structured
formats, such as JSON [43] and Yaml [44] were considered, but were found to lack mature
C++ language support.
The simulator project format is fully described by the XML schema in Appendix A.
5.11.1 Loading simulation projects
Simulation projects are loaded using an instance of the XmlParser class, which uses the cross
platform TinyXML [45] library to parse the XML project file. The TinyXML library provides
good error detection and robustness when parsing invalid documents, with less
implementation overhead than other XML libraries examined.
34
James McGill - 40793625
Embedded Systems Simulator
35
James McGill - 40793625
Embedded Systems Simulator
6.0 Implementation of plug-in components
A significant amount of the work undertaken during this thesis has involved the development
of plug-in components. These components have been developed in order to verify the
functionality of the simulator, and with a particular focus on making it useful to students
enrolled in the Introduction to Computer Systems course at The University of Queensland.
The remainder of this chapter provides a summary of the components implemented, and the
key design decisions made during their implementation.
6.1 Atmel AT90S8515 8-bit microcontroller
To demonstrate that the simulator is able to simulate complex synchronous devices at high
speeds, a plug-in has been developed which implements the functionality of the Atmel
AT90S8515 8-bit microcontroller. The simulated device is able to execute binary files, which
have been compiled for the AT90S8515, without modification. The simulated device also
implements many of the peripherals found on the real device, such as timers, counters,
interrupts, EEPROM and USART.
6.1.1 Common AVR functionality
The AT90S8515 takes advantage of object-oriented design to partition the implementation
into elements which are specific to the AT90S8515, elements which are common between all
Atmel AVR (AVR) microcontrollers (AVRCore) and elements which are common to a family
of AVR microcontrollers (AVRPeripheral). Composition of these classes allows
implementations of additional microcontrollers in the AVR range to be developed with
minimal effort (Figure 10).
36
James McGill - 40793625
Embedded Systems Simulator
1
1
AVR Core
1
1..N
AVR
Peripheral
AT90S8515
Composition
Figure 10: AT90S8515 class architecture
As all AVR microcontrollers implement some subset of the Atmel AVR instruction set [46],
the interpretation and execution of instructions is performed by the AVRCore. The AVRCore
also provides an API which can be invoked by a specific AVR implementation, in this case
the AT90S8515, to access registers and memory, detect interrupt conditions and to provide a
graphical user interface and debugging capabilities.
6.1.2 Instructions
Programs written for Atmel AVR microcontrollers are compiled to 16 and 32 bit binary
opcodes. To enable compiled programs to be executed, a set of AvrInstruction classes, have
been developed to implement the functionality of each instruction. AvrInstruction classes also
provide meta-data to facilitate disassembly and debugging.
Each AvrInstruction class is able to partially disassemble an AVR binary file, using a Factory
method [37] to create an instance of the AvrInstruction object for every instance of that
instruction in the binary file. As all AvrInstruction objects are instantiated before a simulation
begins, pre-processing can be used to perform the processing required to identify an
instruction, extract operands from the instructions op-code (Figure 11), and to interpret these
operands. Pre-parsing the binary input, rather than decoding instructions as they are run,
37
James McGill - 40793625
Embedded Systems Simulator
produces faster simulation speeds by reducing the overhead incurred while executing each
instruction.
Once resolved, AvrInstructions are stored in an array, allowing them to be indexed using the
current value of the microcontrollers program counter. Instructions which occupy more than
one 16-bit word are allocated multiple slots in the array in order to preserve addressing.
0010
11rd
dddd
rrrr
Figure 11: Demonstration of operands within an opcode (MOV opcode)
The 5 bit values for the source (r) and destination (d) register are interlaced, complicating
extraction.
6.1.3 Registers and data storage
The hardware functions of AVR microcontrollers are controlled by manipulating the values of
8 bit Input/Output (I/O) registers, while working registers and SRAM are provided for volatile
data storage. The AVRCore class provides an API which segments the various types of
memory by address (Figure 12), allowing instructions to read from and write to memory in a
consistent manner.
Each I/O register is a concrete implementation of the AvrMemory interface, allowing each to
implement custom logic in response to data being written or read. This is used to implement
the hardware control functionality of I/O registers, such as copying data written to a PORT
register to the 8 Pin objects which represent the pins of that port.
38
James McGill - 40793625
Embedded Systems Simulator
Working registers and SRAM (excluding mirrored I/O register locations) are simply used to
provide storage. An array of octets is used to provide a low level, and therefore efficient,
method for storing and accessing this data. Instructions which are known to only access
working registers can achieve faster execution speeds by bypassing the memory API and
accessing these locations directly.
32 General Purpose Working Registers
$0000 - $0001F
64 I/O Registers
$00020 - $0005F
Internal SRAM (8 x 512)
$0060 - $025F
External SRAM (8 x 64K)
$0260 - $FFFF
Figure 12: AVR address segments for an AT90S8515.
The size of each segment is passed to the AVRCore upon initialization.
6.1.4 Automatic generation of skeleton classes
To reduce the time required to implement AvrInstruction and AvMemory objects, python
programs have been written which produce skeleton C++ classes from Django [47] templates
(Appendix B) for each instruction and register implemented by a selected AVR device. The
information required to produce each class is automatically extracted from Atmel datasheets.
The skeleton classes contain instruction and register meta-data, used for debugging, as well as
the pre-processing and disassembly code for each AvrInstruction object. The use of these
39
James McGill - 40793625
Embedded Systems Simulator
programs is estimated to have reduced development time by several weeks and to have
significantly reduced the number of errors that would have occurred if manually
implementing the classes.
6.1.5 Interrupts
Hardware interrupts are used by AVR microcontrollers to provide an immediate response to a
hardware condition by causing execution to jump to a specific address. The AVRCore
component is designed to isolate the implementers of additional AVR microcontrollers from
the complexity of detecting interrupt conditions, and ensures that interrupts are executed at
the correct time, in the correct order, and with the correct cycle delay.
An interrupt is triggered if the global interrupt flag in the status register is set, and both the
interrupt’s flag and enable bits are set (Figure 13). The AVRCore takes advantage of this
architecture, and only evaluates an interrupt when the value of one of the registers that it is
linked to is changed. In order for an I/O register to be registered with the AVRCore as an
interrupt status or mask register, it must inherit from the AvrInterruptRegister interface, which
provides the functionality needed to allow the interrupt manager to act as an observer of the
register.
If multiple interrupts are triggered simultaneously, their priority is used to ensure that they are
executed in the correct order. It remains the responsibility of the microcontroller
specialization to set interrupt flag bits at the appropriate time, for example to signify a timer
overflow.
40
James McGill - 40793625
Embedded Systems Simulator
I
T
H
S
V
N
Z
C
Global status register (SREG)
Flag
Status register
Interrupt triggered
Enable
Corresponding mask register
Figure 13: Conditions required for an interrupt to be triggered.
6.1.6 Cycle correct execution
The AVRCore is designed to produce cycle correct simulations, which ensures that execution
of every instruction consumes the correct number of CPU cycles. During testing, it was
discovered that delaying a certain number of cycles after each instruction was insufficient, as
on the device itself the result updates to memory locations are performed on the final cycle.
This has been demonstrated to lead to errors in simulation when an instruction modifies a
location in the same cycle as an internal peripheral. The AvrInstruction interface therefore
requires that all instructions be able to calculate the number of cycles that they will use prior
to execution, even when that number can vary.
6.1.7 Status register
As part of the execution of an instruction, it is likely that the microcontroller’s global status
register will need to be updated. This register information about the result of the most recently
performed arithmetic operation, such as whether a negative result was produced [21]. These
conditions are primarily used to evaluate the result of branching instructions. The
41
James McGill - 40793625
Embedded Systems Simulator
AvrInstruction class structure separates the logic required to update the status register from
the logic required to execute the remainder of the instruction. This design, inspired by the
work of Gauthier and Jerraya [10], allows computation of the status register value to be
delayed until the value is required by a branching instruction. This ability is not currently
used, but is expected to reduce the average number of computations required to execute an
AVR instruction if enabled.
6.1.8 Graphical user interface and debugging functionality
In addition to simulating the behaviour of an AVR, the AVRCore also provides debugging and
introspection functionality in order to make testing software using the simulator easier than
testing on the physical device. A graphical user interface is used to show program
disassembly, and provides the ability for users to set breakpoints, step through code and to
observe the value of any register or memory location (Figure 14).
Breakpoints are stored as a property of each AvrInstruction instance, allowing O(1) detection
of breakpoint conditions and allowing a breakpoint to be set on every line. Watched variables
are updated only when execution is paused or stopped, and therefore have no impact on the
simulation speed. The meta-data included in AvrMemory objects is used to allow registers to
be watched by name (e.g. SREG) in addition to by address (e.g. 63).
The AvrCore is also able to parse LSS and LST files, which provide a simple mapping
between the original source code (in assembly or C) and the compiled binary. This is used to
display comments, as shown in Figure 14, and to provide a mapping between lines of code
and compiled instructions.
42
James McGill - 40793625
Embedded Systems Simulator
Figure 14: The AVRCore debugging window.
6.1.9 Internal AVR peripherals
A large amount of the functionality offered by a specific family of AVR microcontrollers is
performed by internal peripherals, such as Timers/Counters and USART. To ensure that these
features can be re-used by implementations of other devices in the same family, peripherals
are implemented by inheriting from the AvrPeripheral interface. Each peripheral can register
concrete implementations of AvrMemory objects with the AVRCore, and can implement logic
to be executed on each clock cycle. In addition to promoting code re-use, this provides a
simple way to partition the complex functionality of a microcontroller.
Concrete AVRPeripheral objects have been developed that implement the complete
functionality of the 8 bit Timer/Counter, 16 bit Timer/Counter with PWM, external interrupts
43
James McGill - 40793625
Embedded Systems Simulator
and EEPROM peripherals of the AT90S family of AVR microcontrollers. A cycle and pin
correct USART peripheral has also been developed, however support for 9-bit transfers is not
yet implemented. All interrupts associated with these peripherals have also been implemented,
using the interrupt functionality provided by the AVRCore.
6.1.10 EEPROM Peripheral
In addition to allowing the runtime storage of data, the EEPROM peripheral is able to
serialize data to and from Intel Hex files. Use of this format allows the EEPROM state to be
transferred between the compiler, simulator and physical devices as required. The peripheral
also uses the ability to execute logic on each clock cycle in order to accurately implement the
complex EEPROM timing requirements.
6.1.11 AT90S8515 Implementation
The advantage in the architecture used to implement simulated AVR components (Figure 10)
is that very little additional work is required to implement a specific microcontroller in the
AVR range, including the AT90S8515. The only significant tasks performed by the
AT90S8515 component are to initialize a instance of the AVRCore object with the correct
memory boundaries, define each of the interrupts, provide implementations of any registers
not associated with an AVRPeripheral object and instantiate and register Pin objects for each
pin on the device. The remainder of the AT90S8515’s functionality is provided by
compositing the peripheral objects described above. Implementing additional microcontrollers
in the AVR range is expected to be equally simple.
44
James McGill - 40793625
Embedded Systems Simulator
6.2 TCP/IP based RS-232 Transceiver
To provide a method for external systems to communicate with devices under simulation, a
component has been developed which is able to transfer data between a TCP/IP connection
and simulated devices which implement the RS-232 protocol. This allows developers to
simulate the behaviour of a serial connection to a PC by providing a connection between the
simulator and any program with TCP/IP support. Consideration was given to using a software
serial null-modem implementation to allow the simulator to communicate with any program
with serial, rather than TCP/IP, support; however this was found to be too complex to
implement on multiple operating systems.
The component uses the simulator timestamp to calculate the baud rate at which data is
arriving on the component’s serial receive pin, and to compare it to the expected baud rate. If
there is a baud rate mismatch, the component uses the simulator error API to report it. This
provides a simple mechanism to detect and debug a common problem that can be difficult to
identify on a physical device.
45
James McGill - 40793625
Embedded Systems Simulator
(a)
(b)
Figure 15: Detection of incorrect baud rates during simulation.
Error notification (a), and the reporting of that error in the simulator log (b).
6.3 Speaker
A speaker component has been developed in order to verify the PWM implementations within
the Timer/Counter peripheral, and for use in the Introduction to Computer Systems subject at
the University of Queensland.
The component plays audible notes based on the frequency at which the difference between
the logical signals on its two pins changes. The audible note is produced by quantizing the
frequency to the nearest Musical Instrument Digital Interface (MIDI) note, using the formula
presented in Figure 16, and by playing that note using the cross platform PortMidi MIDI
library [48]. MIDI was selected as it is able to be implemented cross platform, and, unlike
sampled formats such as WAV, allows notes to be produced at a single frequency with little
overhead. The use of a CPU timer to drive a PC speaker was also considered, however the
46
James McGill - 40793625
Embedded Systems Simulator
output of a CPU timer, unlike MIDI, cannot be re-routed to headphones, muted, or used on
computers without motherboard speakers.
𝑀𝐼𝐷𝐼 𝑁𝑜𝑡𝑒 𝐼𝐷 = 57 + 12 𝑙𝑜𝑔2(
𝑓
)
440
Figure 16: Formula for conversion between frequency (Hz) and MIDI Note ID
6.4 Additional components
In addition to the components discussed above, the following simulated components have
been implemented and demonstrated to work:

LED – A single colour Light Emitting Diode which can either be lit, or unlit.

Toggle switch – A switch which can be toggled on or off using a computer mouse.

T flip flop – A self clocking T flip flop, used to demonstrate the ability to safely chain
components which update simultaneously.

Back-lit Momentary switch – A back-lit switch which is automatically released after a
period of 2 seconds. This component was developed to demonstrate the various
features offered by the Component API.

Seven segment display – A seven segment display with an integrated Binary-coded
decimal to seven segment decoder.

LED Matrix – An N x M LED Matrix driven by N column signals and log2(M) row
signals via a multiplexer.

LCD - A two-line, 80 character LCD (Figure 17) which implements the HD-44780
LCD controller instruction set (except custom graphics). This component has an
47
James McGill - 40793625
Embedded Systems Simulator
integrated pull up-resistor on the enable line, which has been used to demonstrate the
ability to simulate open-drain communication protocols.
Figure 17: Simulation of an 80 character LCD, driven by an AT90S8515 microcontroller.
48
James McGill - 40793625
Embedded Systems Simulator
49
James McGill - 40793625
Embedded Systems Simulator
7.0 Verification of solution
By comparing the solution developed to the requirements outlined in Chapter 4, the
correctness and completeness of the simulator can be established, and a measure of its
suitability for distribution developed. This chapter details the methods that were used to test
the capabilities of the simulator and includes a discussion of the results of these tests in the
context of the goals of the thesis. The management of the project is also examined to evaluate
the extent to which it contributed to the outcomes of the project.
7.1 Testing methodologies
The software and associated plug-ins have been carefully verified using both manual and
automated testing. This has allowed accurate results regarding the simulators capabilities to be
derived.
7.1.1 Testing of the complete system
During the development of the simulator, testing against a small set of simulator projects was
used to identify regression bugs in the complete system and to provide an indication of the
simulator’s features, correctness and completeness. The projects were primarily drawn from a
set of practical exercises employed by the Introduction to Computer Systems subject at the
University of Queensland, and had visual and easily verifiable outputs. This form of testing
was also useful in identifying usability issues in the user interface. To ensure consistency in
testing, a detailed testing plan was produced for each test, an example of which is included in
Appendix C. Appendix D provides an overview of the tests which were created to test specific
features of the simulator framework, as well as to test the behaviour of the plug-ins
developed.
50
James McGill - 40793625
Embedded Systems Simulator
System testing was initially performed manually; however this was both time consuming and
repetitive. To reduce the effort required to test the solution, a python framework for
automated testing of the simulator GUI has been developed using the AutoIt Windows COM
library [49]. The framework provides a simple API which facilitates interaction with the user
interface, as well as the ability to test the state of the simulator by comparing the GUI (as an
image) to an expected state. Any differences identified are highlighted and saved for review
(Figure 18), allowing unsupervised testing.
Actual
Expected
Figure 18: Simulator error, as identified by the automated project testing framework.
The framework has been used to implement each of the tests outlined in Appendix C. In
addition to reducing testing effort, automated testing has allowed a single project to be
simulated hundreds of times within a few hours. This was an important factor in allowing
concurrency errors, which occurred infrequently, to be identified and remedied.
51
James McGill - 40793625
Embedded Systems Simulator
Unstructured manual tests have also been performed, in order to identify errors that manual
tests may routinely miss. These tests primarily focused on the system’s ability to cope with
unexpected states, such as performing simulations with invalid inputs.
7.1.2 System benchmark
In addition to structured testing of the complete system, specific testing was carried out at the
conclusion of the project in order to obtain accurate measurements of performance. An
implementation of Tetris, developed for the AT90S8515 by a student as part of the
Introduction to Computer Systems course at The University of Queensland is used as a
performance benchmark.
The program is designed to be executed on a 4MHz AT90S8515 microcontroller, in a system
consisting of the microcontroller, a 15 x 8 LED display, a piezoelectric speaker and a serial
connection to a PC terminal (Figure 19). The number and complexity of these plug-ins is
consistent with the project goal of achieving real-time simulations in a system with a single
microcontroller and several other components.
The particular implementation of Tetris chosen was selected as it uses all of the internal
peripherals developed for the simulated AT90S8515 component. The compare match and
PWM capabilities of both timers are used to play music and to refresh an LED matrix, while
USART is used to refresh a terminal display at regular intervals. EEPROM is used to store
and load high scores, and to load music data. This has been determined to be a realistic
example of a complex microcontroller application, and therefore suitable for use as a
benchmark.
52
James McGill - 40793625
Embedded Systems Simulator
Figure 20 shows the benchmark system being run on the simulator, connected via TCP/IP to
Hyper Terminal to simulate an Atmel to PC serial connection. The results of executing this
benchmark are presented in Section 7.2.2.
Figure 19: Hardware used by the Tetris benchmark.
Figure 20: Simulation of the Tetris benchmark.
53
James McGill - 40793625
Embedded Systems Simulator
7.1.3 Automated testing of the Atmel AT90S8515 plug-in
An automated framework has been developed to provide a more accurate indication of the
AT90S8515 plug-in’s correctness than can be determined using manual or system testing.
Although manual testing of a microcontroller can be used to identify that it is not operating
correctly, it provides no mechanism for accurately locating the source of the error. It is also
possible for a program being executed on the simulated microcontroller to eventually produce
the correct set of outputs without following the same execution path that it would on the
physical device. The framework developed overcomes these issues, allowing errors in the
implementation of the plug-in, and their effects, to be identified with an accuracy of a single
execution step.
The framework loads an implementation of an AVR microcontroller as a simulator plug-in
and executes a compiled AVR binary on the component. After each execution step, the state
of the simulated microcontroller, defined by the current values of every working register, I/O
register, SRAM register and the current value of the program counter, is compared to an
expected state. Any divergence in state can be identified immediately, allowing not only the
step at which the error occurred to be identified, but also the exact effect of the error on the
microcontroller’s state. Figure 21 shows the output of the framework after identifying an error
in the execution of the NEG instruction.
54
James McGill - 40793625
Embedded Systems Simulator
…
[AvrCore::core_clock] Executing 0x0B: NEG 0x10
[AvrTestRunner::validate_] Reg (10): Expected: 0, found: ff at step 11
[AvrTestRunner::validate_] I (3f): Expected: 2, found: 35 at step 11
[AvrTestRunner::run] Finished executing test: Test CSSE1000 Prac 4.
[AvrTestRunner::run] 2 errors from 20 steps.
[main] 0 / 1 TESTS PASSED.
Figure 21: Output from the AVR Testing Framework.
In order to run the tests, the expected state of the microcontroller at each stage of execution
must be known. This information can be captured from the physical device using the JTAG or
DebugWire debugging protocols. For older microcontrollers, where no such protocol is
available, a software simulator, such as AVR Studio, can be used to produce an appropriate
set of reference states. To facilitate this, a python script has been written to automatically
capture the state of a program being executed in AVR Studio (Appendix F). The state is
stored as a set of Intel Hex files, which are parsed by the simulator.
The limited amount of information available about AVR microcontrollers means that a
number of assumptions must be made during the implementation of the simulator plug-in. The
ability of this black box testing method to empirically test these assumptions, by comparing
the components state to an implementation which is known to be correct, is one of its greater
strengths.
The testing framework is also able to execute a simple scripting language, allowing the testing
procedure to be modified to support the testing of partial implementations, and against a set of
inputs which are known to contain errors. The commands available in the scripting language
55
James McGill - 40793625
Embedded Systems Simulator
are described in Appendix E. Automated tests have been developed to test the implementation
of the AVR 8-bit instructions available to the AT90S8515, as well as hardware features of the
device such as the Timer/Counter 0, USART, EEPROM and interrupt peripherals.
7.2 Results
The testing methodologies discussed in Section 7.1 have been used to derive accurate
measures of the software’s completeness, stability and performance. These results are
presented in the following sections.
7.2.1 Manual testing of components and simulator framework
As of the time of submission, all system tests pass completely. As part of this testing, the
simulations have also been verified to convey the state of the system under simulation in a
way that is perceptually similar to real devices, and to run at speeds which are not
perceptually different from the speed at which the real devices would run. No problems have
been identified with the usability of the graphical user interface.
7.2.2 Performance
The speed of simulation has been shown, as expected, to vary significantly based on the
components involved in the simulation. Profiling of the benchmark application shows that the
underlying simulator framework accounts for less than 20% of the discrete event algorithm’s
execution time, with the remainder being a function of the complexity of the components
being simulated. When real-time simulation is disabled, a system consisting of only an
AT90S8515 component is able to run at 350 – 400% of real time on a 2.4 GHz PC running
Windows XP. In comparison, the Tetris benchmark, running on a 4 MHz AT90S8515, runs at
an average of 300% of real-time on the same CPU. The relatively small decrease in
56
James McGill - 40793625
Embedded Systems Simulator
performance compared to an AT90S8515 only system is consistent with the complexity of the
AT90S8515 plug-in when compared to other plug-ins.
When real-time simulation is enabled, the simulation speed is constrained to approximately
100% of real time. Figure 22 plots the difference between simulation time and real-time (wall
clock time) over a period of 150 milliseconds, measured while running the benchmark
application. On Windows XP, the error between simulator time and real-time oscillates
between ±2ms with a mean of 0ms. Mac OS X is shown to have a much smaller error, with
the error oscillating between 0ms and 1ms. Figure 23 demonstrates that this error is
approximately stable over the lifetime of a simulation, although a small increase in error is
observed at 3 seconds, after which the system rapidly stabilises. These observations are
consistent with measures taken while simulating other systems.
Error (simulator time - real-time) when simulating the Tetris benchmark system
5
Windows XP
Mac OS X 10.5
4
Error (ms)
3
2
1
0
-1
-2
-3
-4
-5
0
50
100
Simulator time elapsed (ms)
Figure 22: Error between simulation time and wall clock time over 150mS.
57
150
James McGill - 40793625
20
Embedded Systems Simulator
Error (simulator time - real-time) when simulating the Tetris benchmark system
Windows XP
Error (ms)
10
0
-10
-20
0
1000
2000
3000
4000
5000
6000
7000
8000
9000
Simulator time elapsed (ms)
Figure 23: Error between simulation time and wall clock time over 9 seconds
7.2.3 Stability
Real-time simulation speeds are not expected to be achievable for all systems; however the
simulator framework guarantees that simulations will remain stable regardless. Manual testing
has been used to verify this assertion, by inserting artificial delays to lower simulation speeds
to less than 1% of real-time. Manual testing has been used to verify that all tested projects
(Appendix D) function correctly at this speed.
7.2.4 AT90S8515
At the time of submission, the AT90S8515 plug-in passes all tests in the automatic testing
suite. Instruction coverage has been measured (Figure 24), demonstrating that every
implemented instruction is called and tested at least once by the testing suite, and that many
instructions are tested several hundred times. The cycle accuracy of each instruction has also
been verified by monitoring the value of Timer/Counter 0, configured to increment once each
CPU cycle, while running each instruction.
58
James McGill - 40793625
Embedded Systems Simulator
Hardware features such as Timer/Counter 1 cannot be tested using the automatic framework,
as correct values for their state during program executions could be not be obtained. These
features have been tested using a combination of manual testing, and indirectly by sharing
code with features which can be tested (such as Timer/Counter 0).
Instruction coverage histogram
80
70
Frequency
60
50
40
30
20
10
0
-50
0
50
100 150 200 250 300 350 400 450 500 +
Instruction coverage (number of times executed)
Figure 24: Frequency distribution of total instruction coverage (calls) over all automatic
tests.
7.3 Functionality and deliverables
In addition to being used to examine the abilities of the simulator framework, manual testing
has been used to verify that the simulator meets the functional requirements identified in
Chapter 4. The non-software deliverables developed, such as documentation, have also been
examined in the context of these goals.
59
James McGill - 40793625
Embedded Systems Simulator
7.3.1 Required components
All required components, outlined in Section 4.2, have been implemented and demonstrated
to function correctly using both manual and automated testing. In addition, a number of
additional components have been implemented, as detailed in Section 6.4. These additional
components significantly extend the usefulness of the simulator. The optional goal of
implementing an AT90S8515 graphical debugging environment has also been achieved
(Section 6.1.8).
7.3.2 Maintainability
Care has been taken to ensure that the code base is able to be maintained in the future, without
requiring the input of the author. Documentation, in the form of comments, is used throughout
the code to explain important implementation choices and complicated segments of code.
Additionally, all code written conforms to a strict style guide and uses clear names for
variables and functions.
Unfortunately, some elements of the code base, particularly plug-in components, have few
comments. These components will need to be documented before they can be expected to be
maintained.
7.3.3 Documentation
The development of documentation, in order to facilitate the use and future development of
the simulator formed an important goal of this thesis. A significant amount of time has
therefore been spent ensuring that sufficient documentation is available for both end users and
developers. This document is expected to be the starting point for developers hoping to extend
the simulator framework or implement additional AVR components. In addition, a detailed
60
James McGill - 40793625
Embedded Systems Simulator
tutorial has been written which outlines the steps required to implement the momentary
pushbutton plug-in [50] and to compile the plug-in on multiple operating systems [51]. A
video demonstrating the use of the simulator has been developed, and is intended to be
distributed with the application.
7.3.4 Portability
The simulator and plug-ins have been compiled and run on multiple operating systems
(Figure 25) and have been demonstrated to simulate the benchmark system at sufficient
speeds (Figure 26). All manual tests have been carried out on Windows XP, Mac OS X 10.5
and Ubuntu Linux 8.10, and demonstrated to pass.
(a)
(b)
Figure 25: Simulator running on Ubuntu Linux (a) and Mac OS X 10.5 (b).
61
James McGill - 40793625
Embedded Systems Simulator
The Scons [52] cross-platform build system can be used to compile the simulator and plug-ins
on Mac, Linux and Windows. In addition, Visual Studio and XCode projects have been
developed to allow IDE based debugging on Windows and Mac OS X respectively.
Percentage of real-time speed achieved by benchmark (2.4 GHz CPU)
Mac OS X 10.5
Windows XP
Ubuntu Linux
0
50
100
150
200
250
300
350
Figure 26: Comparison of simulator speed on multiple operating systems.
7.4 Discussion
The solution presented has been shown to meet and exceed the goals set at the start of the
project. The simulation framework is both fast enough to allow real-time simulation of
embedded systems (Section 7.2.2), and flexible enough to allow additional components to be
developed and distributed independently (Section 5.9). This flexibility has been used to
develop all of the components identified as being required for testing and verification (Section
7.3.1). The simulator also provides a simple graphical user interface to allow interaction with
the system under simulation (Section 5.8) and which is able to display the current state of
each component. The framework developed is also capable of representing interactions
between multiple components using multiple signal classes, including open-drain and weak
drivers, as demonstrated by the LCD component (Section 6.4). The stability, completeness
and correctness of these features have been demonstrated by methodical manual and
automated testing.
62
James McGill - 40793625
Embedded Systems Simulator
The use of a cross-platform plug-in architecture, and careful choices of support libraries,
allow the simulator to be used by developers on multiple operating systems (Section 7.3.4).
This is expected to significantly increase the number of developers who are able to use the
simulator, and could therefore also be expected to increase the potential pool of plug-in
developers. The variation in maximum benchmark simulation speeds observed across the
three operating systems tested (Figure 26) is attributed primarily to the optimization
capabilities of the different compilers used, as well as the underlying speeds of services
provided by the operating systems such as graphics rendering and networking. The difference
in simulation speed error between Windows and Mac OS X (Figure 22) is similarly attributed
to the services offered by the two operating systems, with Unix-like systems providing a
higher resolution timer than Windows.
The simulation of the 4MHz Atmel benchmark system (on a 2.4 GHz PC) at 300% of realtime, while maintaining an interactive graphical display, demonstrates that the framework is
able to easily exceed the performance goals originally proposed. This result also suggests that
the simulator framework should be able to simulate synchronous components of a similar
complexity at clock speeds of up to 12MHz. As PC specifications increase, it is expected that
the simulator will be able to achieve even higher levels of performance. This speed has been
achieved by a combination of a well thought out software architecture, and choice of
programming language, and has therefore been achieved without compromising the
simulator’s flexibility or accuracy.
In addition to fast simulation speeds, the goal of perceptually real-time simulation has been
demonstrated as a result of manual testing, and is supported by the measurements presented in
63
James McGill - 40793625
Embedded Systems Simulator
Section 7.2.2. The small variations between simulator and wall clock times are unlikely to be
noticeable, and further work to decrease this variation is therefore unnecessary.
As each implemented AVR instruction is executed at least once by the automatic testing
framework, it can be concluded that every instruction implemented can correctly process at
least one set of inputs, and that every instruction consumes the correct number of CPU cycles.
Given the simplicity of most instructions, it can be assumed that most instructions should
correctly handle any input, however further testing would be appropriate. If programs are
found which cannot be simulated correctly, the automated testing framework can be used to
efficiently isolate and correct the error.
The documentation produced, combined with the quality of commenting and use of a
consistent programming style throughout the code, are expected to enable this software to be
maintained and extended in the future. However, although automatic testing has formed an
important component in evaluating the correctness of the overall solution, there has been very
little progress made on automatic unit testing of individual elements of the code base. This is
primarily a result of the experimental nature of the work, with the architecture of the system
changing frequently, and the limited time frame in which it was developed. The lack of unit
tests may make extending the simulator framework difficult, and is the primary area in which
this thesis fails to excel.
Overall, a solution has been presented which is both complete, with respect to the goals
outlined in Chapter 4.0, and which has been shown to be correct in all aspects tested. The
simulator is expected to be distributed to students enrolled in The University of Queensland’s
Introduction to Computer Systems course, demonstrating its usefulness. It is hoped that future
64
James McGill - 40793625
Embedded Systems Simulator
work in developing additional components will eventually make the simulator accessible and
useful to a much wider range of developers.
7.5 Reflection of project management
Time management throughout the project was maintained by constant comparison to the
detailed project plan developed as part of the progress report delivered earlier in the project
(Appendix G). Throughout the project, progress has consistently been on track with the stated
plan, primarily been a result of significant effort and dedication on behalf of the author. This
has allowed a solution which meets all of the stated goals to be delivered on time.
Based on the results of previous attempts at similar topics and feedback from past thesis
students, a large amount of time had been allocated to debugging the implementation of the
AT90S8515 plug-in. The development of the automated testing framework, however,
significantly reduced the time required to develop a working simulation of this component. As
a result, a large amount of additional time was available in which to improve the graphical
user interface, and to implement debugging functionality and additional components. This
additional time was also used to perform further testing and debugging, resulting in a more
stable software package.
Owing to concerns regarding the performance of the final solution, a large amount of time
was spent micro-optimizing code during the earlier stages of development. Optimising the
code base required a great deal of time and effort, often resulting in large changes to the
simulator architecture. The results of these optimizations, however, have been largely
obscured by later changes to the code base, and are now considered unnecessary. If
65
James McGill - 40793625
Embedded Systems Simulator
attempting a similar project, the author would concentrate on achieving speed increases
through design and algorithm choices, rather than by code optimization.
Overall, the author is extremely satisfied with the quality of the solution developed, and is
confident that this has primarily been the result of good planning, successful time
management, great personal effort, and a well thought out design.
66
James McGill - 40793625
Embedded Systems Simulator
67
James McGill - 40793625
Embedded Systems Simulator
8.0 Future work
Although the simulator developed meets and exceeds all goals, there are still a number of
additional features which could be developed to make the program even more useful to
embedded systems developers, and which may suggest future areas in which to conduct
research.
8.1 Project editor
A graphical editor which was able to facilitate adding components to a project, positioning
components within the user interface, and connecting pins on components, would be
beneficial to users of the simulator. Although projects are assumed to be edited much less
frequently than they are run, editing XML by hand is both time consuming and error prone.
8.2 Improved debugging capabilities
The debugging functionality currently integrated with the AT90S8515 component is
extremely useful; however it lacks features made available by other debuggers. In particular,
the debugger is unable to map C variables to memory locations, or to step through C
statements. By incorporating the ability to load information contained within the DWARF
[53] debugging format, produced as an output of the AVR compilation process, this
functionality could be added to future AVR plug-ins.
8.3 Automated testing framework
The automatic testing developed thus far is aimed primarily at verifying the accuracy of the
simulator software and plug-ins developed, and relies on the graphical representations of
components remaining stable. There is scope, therefore, for a framework which can be used to
verify that the functionality of an embedded system remains accurate as changes are made to
68
James McGill - 40793625
Embedded Systems Simulator
the embedded software, or circuit design, and which does not depend on the graphical state of
the system. Such a system could easily be developed by re-using the ability to send events to
components to simulate user interaction, and by adding the ability to interrogate the current
state of a component.
8.4 Development of additional components
It is likely that developers will require a significant base of components to be implemented
before they consider using the simulator framework. There is therefore significant work left to
be done in implementing additional AVR microcontrollers, microcontrollers from other
families, and additional embedded devices.
8.5 Improved separation of simulator state from graphical state
In order to ensure that the simulator was able to meet the performance requirements outlined
in Chapter 4.0, a decision was made to keep the code used to provide graphical
representations of Component objects state integrated with the code used to evaluate that
state. It is now clear that a Model-View component architecture which strictly separated state
(the Model) from the graphical representation of that state (the View) would be desirable.
This would allow views to be re-used among multiple components, and would also allow textonly simulations as a potential speed up. The ability to interrogate a model would also
facilitate the development of the automated testing framework outlined in Section 8.3.
69
James McGill - 40793625
Embedded Systems Simulator
9.0 Conclusion
The narrow focus on functionality with embedded digital systems has, in the past, made it
hard for developers to evaluate the behaviour of a system without access to specialized
hardware. This barrier has been partially removed by the development of PC based
simulators, which employ simulation algorithms to provide a model of the state of the digital
system over time. An examination of the existing offerings in this field identified that there
did not currently exist an offering which was both affordable by novice developers and
students, and which was flexible and extensible enough to allow any digital embedded system
to be simulated. A proposal was therefore put forward by James McGill and Dr. Peter Sutton
to develop a fast, extensible simulator for embedded systems.
The result of this proposal, presented in this document, is a cross-platform software
framework and application for the simulation of digital embedded systems. The software
developed uses an extensible software architecture to allow simulated versions of embedded
devices to be developed and distributed independently. A discrete event simulation algorithm
is used to provide an accurate model of the system’s state, and provides a framework to allow
components to interact via simulated electrical connections. Events within the simulation
algorithm are partitioned into multiple event sets, providing a speed increase by allowing
synchronous events to be represented efficiently. The simulator was shown to be able to
utilise real-time simulation speeds, when possible, and a graphical user interface, to allow
users to interact with a simulated system in a way that is consistent with use of a real device.
In order to demonstrate the functionality of the simulator, a number of simulated components
have been developed as plug-ins. In addition to an 8-bit AT90S8515 microcontroller,
character LCD, speaker and LED matrix, a component was developed to interface the RS232
70
James McGill - 40793625
Embedded Systems Simulator
communication protocol to a TCP/IP socket, demonstrating the ability for the simulator to
interact with both users and external systems. Systematic manual and automatic testing has
shown that these plug-ins are able to provide accurate simulations of the real digital
components which they represent. To provide a more accurate measure of the
microcontroller’s correctness, an automated testing framework was developed which uses
comparisons with data extract from a physical or simulated device to isolate and identify
implementation errors. The black box nature of the framework also made it particularly
valuable in identifying incorrect assumptions about the devices expected behaviour. This
framework was used to refine the implementation of the plug-in, and to demonstrate that the
basic functionality of the full AT90S8515 instruction set implemented is correct.
As an additional measure of verification, a submission to the University of Queensland
Introduction to Computer Systems subject was chosen for use as a performance benchmark.
This benchmark was simulated accurately, and at speeds that indicate that real time simulation
of a 12 MHz microcontroller in a simple digital system should be achievable on a 2.4 GHz
PC. When simulation speeds were constrained to real-time, the magnitude of the error
between simulator time and real-time was observed to be 2ms on average, which is consistent
with manual observations and with the goal of achieving real-time simulation. These results
were found to be relatively consistent on Windows XP, Linux and Mac OS X, although the
maximum achievable benchmark simulation speed varied between 220% and 300% of 4MHz.
A critical examination of these results in the context of the goals of the project revealed that
the end results meets and exceeds the goals of performance and functionality originally
proposed. The submission is also complete with respect to the proposed documentation, level
of maintainability, and the desired software architecture. Unfortunately, the code written thus
71
James McGill - 40793625
Embedded Systems Simulator
far lacks unit testing, primarily as a result of the short time-frame in which it was developed.
This may impact the ability for additional developers to stably extend the core offering. A
number of areas have also been identified in which the simulator could be improved,
suggesting possible future avenues for research into this area.
Overall, a solution has been presented which is both complete, with respect to the goals
outlined, and which is expected to be useful to those interested in the development of
embedded systems.
72
James McGill - 40793625
Embedded Systems Simulator
List of References
[1]
P. Koopman, "Undergraduate embedded system education at Carnegie Mellon," ACM
Transactions on Embedded Computing Systems, vol. 4, no. 3, pp. 500-528, Aug. 2005.
[2]
J. A. Fisher, P. Farabos, and C. Young, Embedded Computing; A VLIW approach to
architecture, compilers and tools. San Fransisco, CA: Elsevier, 2005.
[3]
Atmel. (2008, Jul.) AVR Studio 4. [NotOnline].
http://www.atmel.com/dyn/Products/tools_card.asp?tool_id=2725
[4]
Labcenter Electronics. (2008, Sep.) Proteus VSM. [NotOnline].
http://www.labcenter.co.uk/products/vsm_overview.cfm
[5]
Oshon Software. (2008, Aug.) Avr Simulator IDE. [NotOnline].
http://www.oshonsoft.com/avr.html
[6]
T. J. Schriber and D. T. Brunner, "Inside simulation software: inside discrete-event
simulation software: how it works and why it matters," in Proceedings of the 33nd
conference on Winter simulation, Alrington, 2001, pp. 158-168.
[7]
P. M. Maurer, "The Inversion Algorithm for digital simulation," in Proceedings of the
1994 IEEE/ACM international conference on Computer-aided design, San Jose, 1994,
pp. 258-261.
[8]
B. Franke, "Fast cycle-approximate instruction set simulation," in Proceedings of the
11th international workshop on Software & compilers for embedded systems, Munich,
2008, pp. 69-78.
[9]
S. A. Szygenda and A. A. Lekkos, "Integrated techniques for functional and gate-level
digital logic simulation," in Proceedings of the 10th workshop on Design automation,
Piscataway, 1973, pp. 159-172.
[10] L. Gauthier and A. Jerraya, "Cycle-true simulation of the S10 microcontroller including
the core and the peripherals.," in Proceedings of the 11th IEEE International Workshop
on Rapid System Prototyping, Washington, 2000, pp. 60-65.
[11] H. Muhr and R. Holler, "Accelerating RTL Simulation by Several Orders of Magnitude
Using Clock Suppression," in Embedded Computer Systems: Architectures, Modeling
and Simulation, 2006. IC-SAMOS 2006. International, 2006, pp. 123-128.
[12] L. Eeckhout, S. Nussubaum, and K. De Bosschere, "Statistical simulation: adding
efficiency to the computer designer's toolbox," IEEE Micro, vol. 23, no. 5, pp. 26-38,
Sep. 2003.
[13] D. Jones, "An empirical comparison of priority-queue and event-set implementations,"
Communications of the ACM, vol. 29, no. 4, pp. 300-311, Apr. 1986.
73
James McGill - 40793625
Embedded Systems Simulator
[14] J. Comfort, "The simulation of a microprocessor based event set processor," in
Proceedings of the 14th annual symposium on Simulation, Tampa, 1981, pp. 17-33.
[15] R. Brown, "Calendar queues: a fast 0(1) priority queue implementation for the
simulation event set problem," Communications of the ACM, vol. 31, no. 10, pp. 12201227, Oct. 1988.
[16] R. Goh and I. Thng, "MLIST: An efficient pending event set structure for discrete event
simulation.," International Journal of Simulation, vol. 4, no. 5-6, pp. 66-77, Jun. 2004.
[17] P. Phillips and G. Phillips, "No Source Code? No Problem," ACM Queue, vol. 1, no. 6,
pp. 50-57, Sep. 2003.
[18] W. Vogels, "HPC.NET - are CLI-based Virtual Machines Suitable for High
Performance Computing?," in Proceedings of the 2003 ACM/IEEE conference on
Supercomputing, Washington, 2003, p. 36.
[19] R. A. Kilgore, "Object-oriented simulation with SML and Silk in Java and .Net," in
Proceedings of the 35th conference on Winter simulation: driving innovation, New
Orleans, 2003, pp. 218-224.
[20] E. W. Thompson and N. Billawala, "The software engineering technique of data hiding
as applied to multi-level model implementation of logical devices in digital simulation,"
in Proceedings of the 12th conference on Design automation, Piscataway, 1975, pp.
192-201.
[21] Atmel. (2008, Sep.) AT90S8515. [NotOnline].
http://www.atmel.com/dyn/resources/prod_documents/doc0841.pdf
[22] University of Queensland. (2008, Sep.) AVR Project Board Schematic. [NotOnline].
http://www.itee.uq.edu.au/~csse1000/pracs/Atmel_AVR_Resources/AVR_Project_Boa
rd.pdf
[23] H. Freeman, "Software testing," Instrumentation & Measurement Magazine, IEEE, vol.
5, no. 3, pp. 48-50, Sep. 2002.
[24] S. McConnell, Code Complete, 2nd ed., D. Musgrave, Ed. Redmond, America:
Microsoft Press, 2004.
[25] P. Goodliffe, Code Craft, 1st ed., E. Campbell, Ed. San Fransisco, America: No Starch
Press, 2007.
[26] N. Reynolds, "Embedded Systems Simulator," University of Queensland Bachelor of
Engineering Honours Thesis, 2007.
[27] J. Kehl, "Embedded System Simulator," University of Queensland Bachelor of
Engineering Honours Thesis , 2004.
74
James McGill - 40793625
Embedded Systems Simulator
[28] D. Nixon, "Embedded System Simulator," University of Queensland Bachelor of
Engineering Honours Thesis, 2004.
[29] Atmel. (2006, Jul.) AVR JTAG ICE MKII. [NotOnline].
http://www.atmel.com/dyn/Products/tools_card.asp?tool_id=3353
[30] Feersum Technology. (2008, Sep.) miSIim DE. [NotOnline].
http://www.feertech.com/misim/
[31] Dallas Semiconductor. (2008, Aug.) DS1821 Programmable Digital Thermostat and
Thermometer. [NotOnline]. http://datasheets.maxim-ic.com/en/ds/DS1821.pdf
[32] Dallas Semiconductor. (2001, Mar.) Application Note 83: Fundamentals of RS-232
Serial Communications. [NotOnline]. http://www.maximic.com/appnotes.cfm/an_pk/83
[33] The University of Queensland. (2007, Oct.) LED Display Board . [NotOnline].
http://www.itee.uq.edu.au/~csse1000/assessment/project/LED_Display_Board.html
[34] Cairo Graphics. (2009, Apr.) Cairo Graphics. [NotOnline]. http://cairographics.org/
[35] Gnome. (2009, Jun.) GDK Reference Manual. [NotOnline].
http://library.gnome.org/devel/gdk/
[36] Gnome. (2009, Jun.) Graphical Interfaces. [NotOnline].
http://library.gnome.org/devel/platform-overview/stable/graphics.html.en
[37] E. Gamma, R. Helm, R. Johnson, and J. Vlissides, Design Patterns: Elements of
Reusable Object-Oriented Software, 1st ed., B. Kernighan, Ed. Massachusetts, United
States of America: Addison-Wesley, 2007.
[38] GTK. (2009, Apr.) gtkmm: The C++ Interfaces for GTK and Gnome. [NotOnline].
http://www.gtkmm.org/
[39] wxWidgets. (2009, Jun.) wxWidgets. [NotOnline]. http://www.wxwidgets.org/
[40] Nokia. (2009, Jun.) Qt. [NotOnline]. http://www.qtsoftware.com/products/
[41] G. Sayfan. (2007, Nov.) Dr Dobb's Portal. [NotOnline].
http://www.ddj.com/cpp/204202899
[42] World Wide Web Consortium. (2009, Jun.) XML. [NotOnline].
http://www.w3.org/XML/
[43] Internet Engineering Task Force. (2009, Jun.) RFC 4627. [NotOnline].
http://www.ietf.org/rfc/rfc4627.txt?number=4627
[44] C. C. Evans. (2009, Jun.) The Official YAML Website. [NotOnline]. http://yaml.org
75
James McGill - 40793625
Embedded Systems Simulator
[45] L. Thompson. (2009, Mar.) TinyXML Library. [NotOnline].
http://www.grinninglizard.com/tinyxml/
[46] Atmel. (2009, Apr.) AVR 8-bit Instruction Set. [NotOnline].
www.atmel.com/dyn/resources/prod_documents/doc0856.pdf
[47] A. Holovaty and J. Kaplan-Moss, The Definitive Guide to Django, 1st ed., J. Gilmore,
Ed. New York, United States of America: Apress, 2008.
[48] Port Media. (2009, Apr.) Port Media APIs. [NotOnline].
http://portmedia.sourceforge.net/
[49] J. Bennett. (2009, Jun.) AutoIt Scripting Language. [NotOnline].
http://www.autoitscript.com/autoit3/
[50] J. McGill. (2009, Apr.) ESS Component Tutorial. [NotOnline].
http://code.google.com/p/plex-svn/wiki/ComponentTutorial
[51] J. McGill. (2009, Apr.) ESS Compilation Tutorial. [NotOnline].
http://code.google.com/p/plex-svn/wiki/ComponentTutorial
[52] Scons. (2009, Apr.) Scons build system. [NotOnline]. http://www.scons.org/
[53] SGI. (2008, Sep.) libdwarf Homepage. [NotOnline].
http://reality.sgiweb.org/davea/dwarf.html
76
James McGill - 40793625
Embedded Systems Simulator
Appendix A: XML Schema for simulation project files
<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
<xsd:element name='name' type='xsd:string'>
</xsd:element>
<xsd:element name='author' type='xsd:string'>
</xsd:element>
<xsd:element name='property'>
<xsd:complexType>
<xsd:attribute name='key' type='xsd:string' use='required'/>
<xsd:attribute name='value' type='xsd:string' use='required'/>
</xsd:complexType>
</xsd:element>
<xsd:element name='component'>
<xsd:complexType>
<xsd:sequence minOccurs='0'>
<xsd:element ref='property'/>
</xsd:sequence>
<xsd:attribute name='name' type='xsd:string' use='required'/>
<xsd:attribute name='type' type='xsd:string' use='required'/>
<xsd:attribute name='x' type='xsd:integer' use='required'/>
<xsd:attribute name='y' type='xsd:integer' use='required'/>
</xsd:complexType>
</xsd:element>
<xsd:element name='components'>
<xsd:complexType>
<xsd:sequence minOccurs='1' maxOccurs='unbounded'>
<xsd:element ref='component'/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name='pin'>
<xsd:complexType>
<xsd:attribute name='component' type='xsd:string' use='required'/>
<xsd:attribute name='pin' type='xsd:string' use='required'/>
</xsd:complexType>
</xsd:element>
<xsd:element name='connection'>
<xsd:complexType>
<xsd:sequence minOccurs='2' maxOccurs='unbounded'>
<xsd:element ref='pin'/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name='connections'>
<xsd:complexType>
<xsd:sequence minOccurs='1' maxOccurs='unbounded'>
<xsd:element ref='connection'/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
77
James McGill - 40793625
Embedded Systems Simulator
<xsd:element name='project'>
<xsd:complexType>
<xsd:sequence>
<xsd:element ref='name'/>
<xsd:element ref='author'/>
<xsd:element ref='components'/>
<xsd:element ref='connections'/>
<xsd:element ref='layout'/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
78
James McGill - 40793625
Embedded Systems Simulator
Appendix B: Django templates for AvrInstruction and AvrMemory skeleton classes
#ifndef _AVR_{{ mnemonic }}_
#define _AVR_{{ mnemonic }}_
#include "common/types.h"
#include "common/binary-utils.h"
#include "atmel/avr-instruction.h"
class AvrCore;
class AvrMemory;
class {{ class }} : public AvrInstruction {
public:
{{ class }}(AvrCore *core) : AvrInstruction(core) {}
/// Run the instruction.
void execute();
/// Initialize the instruction using the actual FLASH memory value.
void init(uint32 instruction);
/// Assembly representatin of the instruction.
const string assemblyString() const;
/// Description of the instruction.
const string description() const;
/// A 32 bit mask which can be used to isolate the instruction
identifier.
uint32 mask_32() const;
/// A 32 bit representation of the instruction.
uint32 instruction_value_32() const;
/// Update the status register.
unsigned int updateStatusRegister();
// The size of the instruction in bytes.
unsigned int size();
// Factory method to create an instance of this type.
AvrInstruction *create(AvrCore *core);
private:
{% if destination_register %}
// Destination register.
AvrMemory *destination_register_;
// Constant register offset, added to the register value.
static const signed int destination_register_offset_ = {{
destination_register_offset }};
// The address of the destination register.
int destination_register_index_;
// The bit positions in the instruction in which the destination register
// is stored.
static const int destination_register_bit_positions_[{{
destination_register_length }}];
79
James McGill - 40793625
Embedded Systems Simulator
{% endif %}
{% if 16_bit_register %}
// Destination register low - used for 16 bit operations.
AvrMemory *destination_register_low_;
// Destination register high - used for 16 bit operations.
AvrMemory *destination_register_high_;
// The address of the low byte of the 16 bit register.
int destination_register_low_index_;
// The address of the high byte of the 16 bit register.
int destination_register_high_index_;
// Constant register offset, added to the register value.
static const signed int wide_register_offset_ = {{ 16_bit_register_offset
}};
// The bit positions in the instruction in which the 16 bit register to
use
// is identified.
static const int wide_register_bit_positions_[{{ 16_bit_register_length
}}];
{% endif %}
{% if source_register %}
// Source register.
AvrMemory *source_register_;
// Constant register offset, added to the register value.
static const signed int source_register_offset_ = {{
source_register_offset }};
// The address of the source register.
int source_register_index_;
// The bit positions in the instruction in which the source register is
// stored.
static const int source_register_bit_positions_[{{ source_register_length
}}];
{% endif %}
{% if io_register %}
// IO register.
AvrMemory *io_register_;
// The address of the IO register.
int io_register_index_;
// The bit positions in the instruction in which the destination register
// is stored.
static const int io_register_bit_positions_[{{ io_register_length }}];
{% endif %}
{% if constant_data %}
// Constant data from the instruction.
unsigned int constant_data_;
// The bit positions in the instruction in which the constant data is
stored.
80
James McGill - 40793625
Embedded Systems Simulator
static const int constant_data_bit_positions_[{{ constant_data_length
}}];
{% endif %}
{% if constant_address %}
// Constant relative address.
signed int constant_address_;
// Maximum value of the constant address, used to convert to an n-bit
signed value.
static const signed int constant_address_max_ = {{ constant_address_max
}};
// Constant address offset, added to the address value.
static const signed int constant_address_offset_ = {{
constant_address_offset }};
// The bit positions in the instruction in which the constant address is
// stored.
Static const int constant_address_bit_positions_[{{
constant_address_length }}];
{% endif %}
{% if bit_number %}
// Bit number in IO or Status register.
unsigned int bit_number_;
// The bit positions in the instruction in which the bit number is
stored.
static const int bit_number_bit_positions_[{{ bit_number_length }}];
{% endif %}
{% if displacement %}
// Displacement for direct addressing.
unsigned int displacement_;
// The bit positions in the instruction in which the displacement is
stored.
static const int displacement_bit_positions_[{{ displacement_length }}];
{% endif %}
};
#endif
Django template to generate an Instruction header file.
81
James McGill - 40793625
Embedded Systems Simulator
/**
* Avr {{ mnemonic }} Instruction
* {{ description }}
*
* Operation:
* {{ operation }}
*
* Opcode:
* {{ opcode }}
*
* Status Register effects:
* {{ sreg_flags }}
*
* Clock cycles:
* {{ clock_cycles }}
*
* Implementation status:
* Incomplete.
*/
#include
#include
#include
#include
#include
#include
"{{ mnemonic|lower }}.h"
"atmel/avr-core.h"
"atmel/avr-memory.h"
"common/binary-utils.h"
<exception>
<sstream>
{# Decleration of static variables #}
{% if destination_register %}
const int {{ class }}::destination_register_bit_positions_[{{
destination_register_length }}] = {
{{ destination_register_bit_positions_string }}
};
{% endif %}
{% if 16_bit_register %}
const int {{ class }}::wide_register_bit_positions_[{{
16_bit_register_length }}]= {
{{ 16_bit_register_bit_positions_string }}
};
{% endif %}
{% if source_register %}
const int {{ class }}::source_register_bit_positions_[{{
source_register_length }}] = {
{{ source_register_bit_positions_string }}
};
{% endif %}
{% if constant_data %}
const int {{ class }}::constant_data_bit_positions_[{{ constant_data_length
}}] = {
{{ constant_data_bit_positions_string }}
};
{% endif %}
{% if constant_address %}
const int {{ class }}::constant_address_bit_positions_[{{
constant_address_length }}] = {
{{ constant_address_bit_positions_string }}
};
82
James McGill - 40793625
Embedded Systems Simulator
{% endif %}
{% if io_register %}
const int {{ class }}::io_register_bit_positions_[{{ io_register_length }}]
= {
{{ io_register_bit_positions_string }}
};
{% endif %}
{% if bit_number %}
const int {{ class }}::bit_number_bit_positions_[{{ bit_number_length }}] =
{
{{ bit_number_bit_positions_string }}
};
{% endif %}
{% if displacement %}
const int {{ class }}::displacement_bit_positions_[ {{displacement_length
}}] = {
{{ displacement_bit_positions_string }}
};
{% endif %}
{# Functions #}
void {{ class }}::init(uint32 instruction) {
{% if destination_register %}
// Extract the destination register index from the instruction, and get a
// pointer to that register.
destination_register_index_ = BinaryUtils::extractSparseValue(
instruction, destination_register_bit_positions_);
destination_register_index_ += destination_register_offset_;
destination_register_ = avr_core_->getWorkingRegister(
destination_register_index_);
{% endif %}
{% if source_register %}
// Extract the source register index from the instruction, and get a
// pointer to that register.
source_register_index_ = BinaryUtils::extractSparseValue(instruction,
source_register_bit_positions_);
source_register_index_ += source_register_offset_;
source_register_ = avr_core_->getWorkingRegister(source_register_index_);
{% endif %}
{% if io_register %}
// Extract the IO register index from the instruction, and get a
// pointer to that register.
io_register_index_ = BinaryUtils::extractSparseValue(
instruction, io_register_bit_positions_);
io_register_ = avr_core_->memoryByAddress(io_register_index_);
{% endif %}
{% if constant_data %}
// Extract the constant value from the instruction.
constant_data_ = BinaryUtils::extractSparseValue(instruction,
constant_data_bit_positions_);
{% endif %}
83
James McGill - 40793625
Embedded Systems Simulator
{% if constant_address %}
// Extract the constant address (or relative address) from the
instruction.
constant_address_ = static_cast<signed
int>(BinaryUtils::extractSparseValue(
instruction, constant_address_bit_positions_));
// Wrap around for signed values.
if (constant_address_ > constant_address_max_) {
constant_address_ = (constant_address_ - (constant_address_max_ + 1) +
constant_address_offset_);
}
// TODO: This might need to be resolved to a memory address.
{% endif %}
{% if bit_number %}
// Extract the bit number from the instruction.
bit_number_ = BinaryUtils::extractSparseValue(instruction,
bit_number_bit_positions_);
{% endif %}
{% if displacement %}
// Extract the address displacement from the instruction.
displacement_ = BinaryUtils::extractSparseValue(instruction,
displacement_bit_positions_);
{% endif %}
{% if 16_bit_register %}
// 16 bit registers must be handled as a special case as they do not map
// nicely.
int wide_register_index = BinaryUtils::extractSparseValue(
instruction, wide_register_bit_positions_);
// 16 bit registers increment in lots of 2, so double the extracted
value.
wide_register_index = (wide_register_index * 2);
destination_register_low_index_ =
wide_register_index + wide_register_offset_;
destination_register_high_index_ =
destination_register_low_index_ + 1;
destination_register_low_ = avr_core_->getWorkingRegister(
destination_register_low_index_);
destination_register_high_ = avr_core_->getWorkingRegister(
destination_register_low_index_);
{% endif %}
}
void {{ class }}::execute() {
throw std::runtime_error("Instruction {{ mnemonic }} is not
implemented");
}
const string {{ class }}::assemblyString() const {
std::ostringstream output;
output << "{{ mnemonic }}" {% for operand in display_operands %}
{% ifequal forloop.counter0 0 %}<< " " {% else %}<< ", " {% endifequal
%}<< hex << "0x" << {{ operand }}{% endfor %};
84
James McGill - 40793625
Embedded Systems Simulator
return output.str();
}
const string {{ class }}::description() const {
return "{{ mnemonic }} {{ operands }} : {{ description }}";
}
uint32 {{ class }}::mask_32() const {
return {{ masmailk_32 }};
}
uint32 {{ class }}::instruction_value_32() const {
return {{ instruction_32 }};
}
unsigned int {{ class }}::updateStatusRegister() {
throw std::runtime_error("Instruction {{ mnemonic }} SREG effects not
implemented");
}
unsigned int {{ class }}::size() {
return {{ size }};
}
AvrInstruction *{{ class }}::create(AvrCore *core) {
return new {{ class }}(core);
}
Django template to generate an Instruction implementation (cpp) file.
85
James McGill - 40793625
Embedded Systems Simulator
/**
* @author James McGill (jmcgill@plexer.net)
*
* @fileoverview An AvrMemory object is used to encapculate the special
* functionality and metadata associated with a register in an AVR
* microcontroller.
*
* This file is initially automatically generated from the AVR Part
* Description XML file and is later edited by hand to implement the
* registers functionality.
*/
#include "common/log.h"
#include "common/types.h"
#include "AtmelCore/avr-memory.h"
class AvrCore;
class {{ class }} : public AvrMemory {
public:
// An instance of the core is passed in during construction to allow O(1)
// access.
{{ class }}(AvrCore *core) : AvrMemory(core) {}
// Initiailize the memory object, including finding links to other
// registers.
bool init();
// Return the shortname name of the register.
const string &name();
// Return a short description of the registers purpose.
const string &description();
// Return the IO memory location (offset into SRAM).
int io_memory_location();
// Return the register memory location.
int register_memory_location();
// Return a mask which can be used to isolate which bits can be read
// from.
int read_mask();
// Return a mask which can be used to isolate which bits can be written
// to.
int write_mask();
// Return the initial state which the register should be initialized to.
int initial_value();
// Get the shorthand name for a bit, based on the index (from 0).
const string bit_nameByIndex(int index);
// If the register needs to do something special when read from or
// written to
// then uncomment the following block of code.
/*
// Handler for reading data from a byte of memory.
unsigned char read();
86
James McGill - 40793625
Embedded Systems Simulator
// Handler for writing data to a byte of memory.
void write(unsigned char data);
*/
private:
// Shorthand name for each bit in this register, as defined by the Atmel
// datasheets.
const static string bit_names_[8];
// Each register has two locations - one in IO space and one in register
// space. Each maps to the same real memory location.
const static int io_memory_location_ = {{ io_addr }};
const static int register_memory_location_ = {{ mem_addr }};
// Shorthand name for the register, as recorded in the datasheet.
const static string name_;
// A simple description of the register.
const static string description_;
// Mask used to prevent data being written to read only bits.
const static int write_mask_ = {{ write_mask }};
// Mask used to prevent data being read from write only bits.
const static int read_mask_ = {{ read_mask }};
// The value of this register upon initialization / reset.
const static int initial_value_ = {{ initial_value }};
{% if partner_register %}
// The name of the partner register.
const static string partner_register_name_;
// The IO memory address of the partner register.
const static int partner_register_io_address_ = {{ partner_io_address }};
// Pointer to the register paired with
register.
AvrMemory *partner_register_; {% endif %}
};
this
one
to
make
Django template to generate an AvrMemory header (h) file.
87
a
16
bit
James McGill - 40793625
Embedded Systems Simulator
/**
* @author James McGill (jmcgill@plexer.net)
*/
#include "{{ name|lower }}.h"
#include "AtmelCore/avr-memory.h"
#include "AtmelCore/avr-core.h"
/*
unsigned char {{ class }}::read() {
}
Void {{ class }}::write(unsigned char data) {
}
*/
bool {{ class }}::init() {
{% if partner_register %}
partner_register_ =
core_->memoryByAddress(partner_register_io_address_);
{% endif %}
return true;
}
const string &{{ class }}::name() {
return name_;
}
const string &{{ class }}::description() {
return description_;
}
int {{ class }}::io_memory_location() {
return io_memory_location_;
}
int {{ class }}::register_memory_location() {
return register_memory_location_;
}
int {{ class }}::read_mask() {
return read_mask_;
}
int {{ class }}::write_mask() {
return write_mask_;
}
int {{ class }}::initial_value() {
return initial_value_;
}
const string {{ class }}::bit_nameByIndex(int index) {
return bit_names_[index];
}
const string {{ class }}::bit_names_[8] = { {% for bit in bits %}
"{{ bit.name }}"{% endfor %}
};
const string {{ class }}::name_ = "{{ name }}";
88
James McGill - 40793625
Embedded Systems Simulator
const string {{ class }}::description_ =
"{{ description }}";
{% if partner_register %}
const string partner_register_name_ = "{{ partner_register_name }}";
{% endif %}
Django template to generate an AvrMemory implementation (cpp) file.
89
James McGill - 40793625
Embedded Systems Simulator
Appendix C: Manual testing plan
ESS MANUAL TESTING PLAN ID: 1
Purpose: Verify that CSSE1000 Prac 4 simulates correctly.
Project description: Two’s complement negation of 8 switch inputs is output to 8 LEDs.
Simulation project: projects/pracs/prac4.smx
Expected appearance:
Testing procedure:
NOTE: LEDs and Switches are numbered from 1 to 8, left to right.
Passed?
Action
Expected output
Start simulation
1. All LEDs are off (outline only)
2. All Switches are off (outline only)

Click switches 1, 3 and 5
with the left mouse button.
1. Clicked switches are filled.
2. LEDs 1, 2, 4, 6, 7, 8 turn on.

Click the same switches with
the left mouse button.
1. Clicked switch turns off.
2. All LEDs turn off.

90
James McGill - 40793625
Embedded Systems Simulator
Appendix D: Summary of manual tests
Test name
Test purpose
Test summary
Key aspects tested
Prac 4
Verify that CSSE1000 Prac 4
Output the two's complement of 8 switches
LED, Switch, AVR PORT, PIN and DDR
simulates correctly.
to 8 LEDs.
Registers.
Verify that CSSE1000 Prac
Output the two's complement of 8 switches
LED, Switch, AVR PORT, PIN and DDR
5-1 simulates correctly.
to 8 LEDs.
Registers.
Verify that CSSE1000 Prac
Output the index of the active switch to a
Seven Segment, Switch, AVR PORT, PIN
5-2 simulates correctly.
seven segment display.
and DDR Registers, Conditional logic
Verify that CSSE1000 Prac
Output the index of the active switch to a
Seven Segment, Switch, AVR PORT, PIN
5-3 simulates correctly.
seven segment display.
and DDR Registers, Conditional logic
Verify that CSSE1000 Prac
Output the two’s complement of 8 switches
LED, Switch, AVR PORT, PIN and DDR
6-1 simulates correctly.
to 8 LEDs.
Registers. C Code.
Verify that CSSE1000 Prac
Output the index of the active switch to a
Seven Segment, Switch, AVR PORT, PIN
6-2 simulates correctly.
seven segment display.
and DDR Registers. C Code. Conditional
Prac 5-1
Prac 5-2
Prac 5-3
Prac 6-1
Prac 6-2
logic.
91
James McGill - 40793625
Embedded Systems Simulator
Test name
Test purpose
Test summary
Key aspects tested
Prac 6-3
Verify that CSSE1000 Prac
Output the index of the active switch to a
Seven Segment, Switch, AVR PORT, PIN
6-3 simulates correctly.
seven segment display.
and DDR Registers. C Code. Conditional
logic.
Prac 7-1
Prac 7-2
Prac 7-3
Prac 8-1
Verify that CSSE1000 Prac
Drive a speaker at 1KHz with a software
Speaker, Timers/Counter 1, Simulator
7-1 simulates correctly.
timer.
timestamps.
Verify that CSSE1000 Prac
Drive a speaker at 1KHz using the 16 bit
Speaker, Timer/Counter 1, CTC and PWM.
7-2 simulates correctly.
AT90S8515 Timer/Counter 1 in CTC mode.
Verify that CSSE1000 Prac
Drive a speaker at 1KHz using the 16 bit
Speaker, Timer/Counter 1,CTC and PWM.
7-3 simulates correctly.
AT90S8515 Timer/Counter 1 in CTC mode.
C Code.
Verify that CSSE1000 Prac
Drive a speaker at 1KHz using the 16 bit
Speaker, Timer/Counter 1, PWM and CTC,
8-1 simulates correctly.
AT90S8515 Timer/Counter 1 in CTC Mode.
External interrupts.
Mute speaker in response to an edge
triggered interrupt.
Prac 8-2
Verify that CSSE1000 Prac
Drive a speaker at 1KHz using the 16 bit
Speaker, Timer/Counter 1, Timer/Counter 0,
8-2 simulates correctly.
AT90S8515 Timer/Counter 1 in CTC Mode
PWM and CTC, External interrupts.
for at most 1.5 seconds. Restart the speaker
in response to an edge triggered interrupt.
92
James McGill - 40793625
Embedded Systems Simulator
Test name
Test purpose
Test summary
Key aspects tested
Prac 8-3
Verify that CSSE1000 Prac
USART echo with digits 1 - 9 translated to
USART, RS232 to TCP/IP, Baud rate
8-3 simulates correctly.
words (one – nine).
detection, USART Interrupts
Verify that pin values are
3 flip flops are chained together and all
Flip flop component, simulator timestamps,
buffered when components
clocked at 1Hz.
simulator stability, real-time simulation.
Verify that EEPROM can be
Phrase is read from EEPROM, displayed on
USART, EEPROM
read from and written to.
USART, encoded using an inverting code,
T Flip Flops
are updated simultaneously.
EEPROM
and written back to EEPROM.
Momentary
Verify that asynchronous
A pushbutton is released exactly two
Real time simulation of asynchronous
switch.
components can be simulated
seconds after it is pressed.
components.
Timer/Counter 0, Seven Segment component
in real-time.
Seven
Verify that the seven segment
Cycle through all 16 digits at 1 Hz using the
Segment
component works.
AT90S8515 Timer/Counter 0.
Verify that the LCD
Display two lines of text and scroll them off
LCD, real-time simulation, Timer/Counter 0,
component works
the screen. Contains one (purposeful) timing
Error reporting.
Display
LCD
error.
93
James McGill - 40793625
Embedded Systems Simulator
Test name
Test purpose
Test summary
Key aspects tested
Tetris
Verify that Tetris runs
Run a feature-rich Tetris game submission
USART, Interrupts, Speaker,
correctly and at the correct
from a past student, selected as the system
Timers/Counters, Performance, C Code.
speed.
benchmark.
Verify that Snake runs
Run a feature-rich Snake game submission
USART, Interrupts, Speaker, Performance, C
correctly and at the correct
of my own.
Code.
Verify that Asteroids runs
Run a feature-rich Asteroids game
USART, Interrupts, Speaker,
correctly and at the correct
submission from a past student.
Timers/Counters, Performance, C Code.
Snake
speed.
Asteroids
speed.
94
James McGill - 40793625
Embedded Systems Simulator
Appendix E: Automated testing command language
description (string description)
The description instruction appends a string to the textual description of the tests
purpose.
steps (int number_of_steps)
The steps instruction sets the number of execution steps to test. The results of any
previous calls to the function are overwritten.
stepsize (int step_size)
The stepsize instruction sets the number of steps to execute between performing a
comparison. This allows larger tests to be executed quickly, with only limited impact
on accuracy, as most errors are likely to persist for several execution steps or
eventually lead to following an incorrect code branch. The results of any previous
calls to the function are overwritten.
repair (int step, string memory_type, int address, int new_value)
The repair instruction replaces the expected value of an address at a given step. This is
used to correct errors in the output of AVR Studio’s software simulations, which are
known to handle 16 bit registers incorrectly.
ignore (int start_step, int end_step, string memory_type, int start_address, int end_address)
The ignore instruction set an address range which will not be tested during a range of
execution steps. This facilitates testing partial implementations of the microcontroller
by allowing unimplemented address ranges to be ignored.
95
James McGill - 40793625
Embedded Systems Simulator
Appendix F: Python script to save simulator state from AVR Studio
#
#
#
#
#
#
#
#
#
#
#
#
@author James McGill (jmcgill@plexer.net)
Extract a golden file from an AVR Studio project using the debugger.
Dependancies:
AutoIt COM Library (http://www.autoitscript.com/AutoIt)
PyWin32 (http://python.net/crew/mhammond/win32/Downloads.htm)
Steps for use:
1. Load the project in AVR Studio
2. Start debugging, and enter the disassembly view.
3. Reset the simulator, and clear the state of SRAM.
4. Start this script.
from win32com.client import Dispatch
import time
import os
memory_types = ("Data", "I", "Reg")
def saveAllMemories(Auto, path, step):
global memory_types
for memory_type in memory_types:
# Keep sending key press until window opens, as sometimes it gets
missed.
try_again = 0
while try_again is 0:
Auto.Send("!d")
Auto.Send("u")
# Will return 0 if it times out.
try_again = Auto.WinWaitActive("Up", "", 1)
# Open the save memory dialog box
Auto.ControlClick("Up", "", "[ID:1103]")
Auto.ControlSend("Up", "", "[ID:1103]", memory_type + "{ENTER}")
Auto.ControlClick("Up", "", "[ID:1123]")
# Enter the path to save the file to
while len(Auto.ControlGetText("Up", "", "[ID:1123]")) is not 0:
Auto.ControlSend("Up", "", "[ID:1123]", "{END}{BACKSPACE}")
Auto.ControlSend("Up", "", "[ID:1123]", os.path.join(path, memory_type,
str(step) + ".txt"))
# Save the file
Auto.ControlClick("Up", "", "[ID:1186]")
Auto.WinClose("Up")
def createBaseDirectories_(path):
global memory_types
for memory_type in memory_types:
os.mkdir(os.path.join(path, memory_type))
def main(path, num_steps):
print 'Running main function'
Auto = Dispatch("AutoItX3.Control")
Auto.WinActivate("AVR Studio")
Auto.WinWaitActive("AVR Studio")
createBaseDirectories_(path)
96
James McGill - 40793625
Embedded Systems Simulator
for i in range(0, num_steps):
print "Running step", i, "of", num_steps
saveAllMemories(Auto, path, i)
Auto.Send("{F11}")
if __name__=='__main__':
main("c:\\project001", 20000)
97
James McGill - 40793625
Embedded Systems Simulator
Appendix G: Project progress plan
98
James McGill - 40793625
Embedded Systems Simulator
Progress plan (Gantt chart) for Semester 1, 2009
99
James McGill - 40793625
Embedded Systems Simulator
Progress plan (Gantt chart) for Semester 2, 2009
100
Download