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 February 2016 James McGill - 40793625 Embedded Systems Simulator ii James McGill - 40793625 Embedded Systems Simulator 9 February 2016 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 my many friends who made the evaluation of this thesis possible by giving me access to their Atmel AVR related 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 leverage the debugging capabilities of a PC. This thesis presents the implementation of a cross-platform framework for performing simulations of digital systems composed of multiple components. Components are loaded from dynamic libraries, allowing extensions to the system to be developed independently. This flexibility has been utilized to develop additional components, including an implementation of theAT90S8515 8-bit AVR microcontroller. The simulator has been demonstrated to correctly perform real-time hardware/software cosimulation of a system composed of an AT90S8515 microcontroller (clocked at 12MHz) 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 Timers/Counters, Interrupt and USART peripherals, while structured manual testing has been used to verify the remainder of the projects functionality. vii James McGill - 40793625 Embedded Systems Simulator Table of Contents Acknowledgements ................................................................................................................... vi Abstract .................................................................................................................................... vii Table of Contents .................................................................................................................... viii List of Figures ......................................................................................................................... xiii List of Tables ............................................................................................................................ xv 1.0 Introduction and motivation ................................................................................................. 1 1.1 Scope ................................................................................................................................ 1 1.2 Outcomes .......................................................................................................................... 2 1.3 Report Outline .................................................................................................................. 2 2.0 Literature review and background information .................................................................... 5 2.1 Discrete event and embedded systems simulation ........................................................... 5 2.2 Event set data structures ................................................................................................... 6 2.3 Development tools............................................................................................................ 7 2.4 Testing frameworks .......................................................................................................... 8 2.5 Past theses ........................................................................................................................ 9 3.0 Prior art ............................................................................................................................... 11 3.1 AVR Simulator IDE ....................................................................................................... 11 3.2 Proteus VSM .................................................................................................................. 12 3.3 Atmel AVR Studio ......................................................................................................... 14 3.4 miSim DE ....................................................................................................................... 15 4.0 Goals and project requirements .......................................................................................... 18 viii James McGill - 40793625 Embedded Systems Simulator 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 Outside scope ................................................................................................................. 21 5.0 Implementation of the simulation framework .................................................................... 22 1.1 Architectural overview ................................................................................................... 22 5.1.1 Components ............................................................................................................. 26 5.1.2 Events ...................................................................................................................... 27 5.1.3 Pins .......................................................................................................................... 27 5.2 Discrete event simulation ............................................................................................... 23 5.2.1 Enqueing events ...................................................................................................... 24 5.2.2 Memory management .............................................................................................. 25 5.2.3 Real time execution ................................................................................................. 25 5.3 Error checking ................................................................................................................ 29 5.4 Graphical User Interface ................................................................................................ 29 5.5 Cross platform plug-in architecture................................................................................ 31 5.5.1 The Plugin manager ................................................ Error! Bookmark not defined. 5.5.2 Implementation of cross platform plug-ins ............. Error! Bookmark not defined. 5.5.3 Automatic plug-in documentation generation ......................................................... 32 5.6 Persistence of simulation properties using simulation projects ..................................... 33 ix James McGill - 40793625 Embedded Systems Simulator 5.6.1 Loading simulation projects .................................................................................... 34 6.0 Implementation of plug-in components ............................................................................. 35 6.1 Atmel AT90S8515 8-bit microcontroller ....................................................................... 35 6.1.1 Common AVR functionality ................................................................................... 35 6.1.2 Instructions .............................................................................................................. 36 6.1.3 Parsing hex files ...................................................... Error! Bookmark not defined. 6.1.4 I/O Registers ........................................................................................................... 37 6.1.5 Data and working registers ...................................... Error! Bookmark not defined. 6.1.6 Interrupts ................................................................................................................. 39 6.1.7 Execution – cycle correctness and status register ................................................... 40 6.1.8 Graphical User Interface and debugging functionality ........................................... 41 6.1.9 Internal AVR peripherals ........................................................................................ 42 6.1.10 AT90S series Timers / Counters ........................... Error! Bookmark not defined. 6.1.11 AT90S series External Interrupts .......................... Error! Bookmark not defined. 6.1.12 AT90S Series EEPROM ....................................... Error! Bookmark not defined. 6.1.13 AT 90S Series USART ......................................... Error! Bookmark not defined. 6.1.14 AT90S8515 Implementation ................................................................................. 43 6.2 Automated testing of the Atmel AT90S8515 plug-in .................................................... 44 6.2.1 Automated Atmel testing framework implementation details ................................ 44 6.3 TCP/IP based Usart Terminal ........................................................................................ 45 6.4 Speaker ........................................................................................................................... 46 6.5 Additional components .................................................................................................. 47 x James McGill - 40793625 Embedded Systems Simulator 7.0 Verification of solution ...................................................................................................... 49 7.1 Completeness ................................................................................................................. 50 7.1.1 Required components .............................................................................................. 50 7.1.2 Performance ............................................................................................................ 51 7.1.3 Software architecture requirements / Extensibility ................................................. 53 7.1.4 Maintainability ........................................................................................................ 53 7.1.5 Documentation ........................................................................................................ 54 7.1.6 Portability ................................................................................................................ 54 7.1.7 System integration ................................................................................................... 55 7.2 Correctness ..................................................................................................................... 56 7.2.1 Manual testing of the simulator framework ............................................................ 49 7.2.2 Automatic testing of the AT90S8515 component ................................................... 56 7.2.3 Results of testing ..................................................................................................... 57 7.3 Reflection of authors performance and time management ............................................. 58 8.0 Future work ........................................................................................................................ 59 8.1 Project editor .................................................................................................................. 59 8.2 Improved debugging capabilities ................................................................................... 59 8.3 Automated testing framework ........................................................................................ 59 8.4 Development of additional components ......................................................................... 60 8.5 Improved separation of simulator state from graphical state ......................................... 60 9.0 Conclusion .......................................................................................................................... 61 List of References..................................................................................................................... 62 xi James McGill - 40793625 Embedded Systems Simulator Appendix A : XML Schema for simulation project files ......................................................... 68 Appendix B : Django templates for Instruction classes ........................................................... 70 Appendix C : Manual testing plan............................................................................................ 77 Appendix D : Summary of manual tests .................................................................................. 78 xii James McGill - 40793625 Embedded Systems Simulator List of Figures Figure 1: AVR Project board with LED Matrix and Speaker attachments ................................ 8 Figure 2: AVR Simulator IDE with EEPROM and LCD peripherals enabled. ....................... 12 Figure 3: Real time simulation of a graphical LCD in Proteus VSM ...................................... 13 Figure 4: Expanded register view from AVR Studio. .............................................................. 15 Figure 5: Overview of simulator architecture .......................................................................... 23 Figure 6: Cyclic notification problem. ..................................................................................... 28 Figure 7: Transitive pin connections. ....................................................................................... 29 Figure 8: The simulator GUI, displaying the current state of 8 LEDs and 8 switches. ........... 30 Figure 9: Documentation automatically produced for the switch component. ........................ 33 Figure 10: AT90S8515 class architecture ................................................................................ 36 Figure 11: Demonstration of interlaced operands (MOV opcode) .......................................... 37 Figure 12: AVR address segments for an AT90S8515. The size of each segment is passed to the AVR Core upon initialization, allowing it to be re-used for any AVR microcontroller. ... 38 Figure 13: Conditions required for an interrupt to be triggered. .............................................. 40 Figure 14: The AVR Core debugging window. The next instruction to be executed is highlighted in yellow. ............................................................................................................... 42 Figure 15: Output from the Avr Testing Framework, indicating an error in the implementation of the NEG instruction. ............................................................................................................ 45 Figure 16: Detection of incorrect baud rates during simulation, and a view of the simulator error log. ................................................................................................................................... 46 Figure 17: Simulation of an 80 character LCD being driven by an AT90S8515 microcontroller. ........................................................................................................................ 48 Figure 18: Comparison of user interface on Windows XP (a) and Mac OS X 10.5 (b). ......... 55 Figure 19: Comparison of simulator speed on Mac OS X, Windows XP and Ubuntu Linux. 55 xiii James McGill - 40793625 Embedded Systems Simulator Figure 20: CSSE1000 final project (Tetris) with advanced use of sound, USART (graphics) and EEPROM (high scores). ................................................................................................... 56 Figure 21: Frequency distribution of total instruction coverage (calls) over all automatic tests. .................................................................................................................................................. 57 xiv James McGill - 40793625 Embedded Systems Simulator List of Tables Table 1:Interpretation of valid pin values. ............................................................................... 27 xv James McGill - 40793625 Embedded Systems Simulator 1.0 Introduction and motivation Embedded systems computing is a broad field, encompassing the development of all systems developed to perform specific computing tasks [1]. The narrow focus on functionality within an 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 leverage the debugging facilities of a PC, such as a monitor and keyboard. While many programs capable of simulating 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[3]. The need for those new to the development of embedded systems to be able to easily develop and test systems without incurring a unreasonable level of expense led to the proposal by Dr Peter Sutton and Mr James McGill to develop an extensible embedded systems simulator. 1.1Scope The proposed software is intended to support fast and accurate simulation of systems composed of multiple digital components, while remaining flexible enough to allow additional components to easily be developed. The state of the simulation is intended to be displayed using a graphical interface, providing simple method for developers to interact with the system under simulation. 1 James McGill - 40793625 Embedded Systems Simulator The simulation of analogue components, or of the parasitic effects on digital logic, such as capacitance and inductance, is considered outside the scope of the project. 1.2 Outcomes A simulation framework has been developed which is able to perform fast and accurate simulations of systems composed of multiple digital components. The framework allows additional components to be developed independently and dynamically loaded as required. The state of the system is represented using an extensible Graphical User Interface which, combined with real-time simulation speeds, allows users to interact with the system in a way that is consistent with the systems physical counterpart. In order to demonstrate the usefulness of the framework, several simulated components, including an Atmel AT90S8515 microcontroller, have been developed demonstrated to work. The framework and components developed to date compile and run on multiple operating systems, including Windows XP, Mac OS X and Linux. 1.3 Report Outline The remainder of this document discusses the theory behind, and implementation of, the embedded systems simulator. Chapters 2 and 3 provide a review of 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, while chapters 5 and 6 discuss the implementation of the simulator framework and several external components. Chapter 7 outlines the steps used to test the simulator and 2 James McGill - 40793625 Embedded Systems Simulator external components, and evaluates the success of the project. Finally, chapter 9 proposes a number of possible extensions to the work completed thus far. 3 James McGill - 40793625 Embedded Systems Simulator 4 James McGill - 40793625 Embedded Systems Simulator 2.0 Literature review and background information In order to ensure that the simulator being written is able to perform as efficiently as possible, this thesis has built upon the prior work and research of many people. An examination of the most relevant literature 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 [4], is one of the most common methods for simulating digital systems [5]. 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 [4]. Simulation of digital systems can either achieve functional accuracy, in which the system 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 the system, including the timing of internal events, is simulated accurately [6,7]. 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 [8]. 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 [6]. When primarily investigating the results of hardware and software interacting in co-simulation, as is the goal of this thesis, describing the system at a functional level, rather than a gate level, is expected to give the greatest chance of the simulator being able to perform at real-time speeds [8]. 5 James McGill - 40793625 Embedded Systems Simulator In order to achieve faster simulation times, a number of techniques have been proposed which reduce unnecessary computations during simulation. In their paper Muhr and Holler [9] 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 [9]. Gauthier and Jerraya [8] suggest a similar method for improving performance through data suppression, in which the state of various subsystems in a microcontroller, such as the status register, are not updated during the simulation if the future simulator states can be shown to be independent of this value. 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 [10]. 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 [11]. 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) [11]. 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 [11]. More complex algorithms which make use of data structures such as Calender Queues [12] and MLists [13] have also been developed specifically to address the need for faster simulation events set operations. Both are expected to have O(1) amortized execution times by leveraging the discrete nature of events in discrete event simulations, and therefore bucketing scheduled execution times. Unfortunately, the 6 James McGill - 40793625 Embedded Systems Simulator 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 [14] 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 [15] 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++. Performance also varied depending on the quality of the virtual machine implementation for a particular environment, making it unlikely that a simulator written in either of these languages would be able to sustain high simulation speeds on multiple platforms. Kilgore [16] and Thompson and Billawala [17] note that the entities involved in a discrete event simulation are best represented in Object Oriented languages such as C++ 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 [14] and Vogels [15], suggests that the simulator will achieve the greatest balance of performance and maintainability if developed in a compiled object oriented language such as C++. 7 James McGill - 40793625 Embedded Systems Simulator An understanding of the system being simulated is also required before development begins. Documentation of the behaviour of the AT90S8515 microcontroller, as the initial target for this system, will be extracted from the datasheet provided by Atmel [18]. In order to verify the functionality of the this component, its behaviour will be compared to the same processor running as part of the AVR Project Board used by the University of Queensland to teach embedded systems [19] ( Figure 1). The expected behaviour of additional components will be determined by examining their behaviour and datasheets. Figure 1: AVR Project board with LED Matrix and Speaker attachments 2.4 Testing frameworks 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 8 James McGill - 40793625 Embedded Systems Simulator various testing methodologies examined, black box component and regression testing is 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. 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 accurately test the usability of Graphical User Interfaces and to evaluate graphical displays. 2.5 Past theses In their treatment of this same thesis topic Kehl, Nixon and Reynolds [20,21,22], each successfully employed discrete event simulation to functionally simulate the AT90S8515 microcontroller at speeds above 4MHz, thus demonstrating the feasibility of this method. However, although the use of C by Kehl [25] and Nixon [22] would have increased efficiency, it makes maintaining and extending the simulator difficult. In comparison the use of Java by Reynolds [20], while simplifying extensibility, limited the performance of the 9 James McGill - 40793625 Embedded Systems Simulator simulator, requiring compromises in the accuracy of the simulation in order to achieve realtime speeds. 10 James McGill - 40793625 Embedded Systems Simulator 3.0 Prior art Given the complexity of modern software 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 some of the most relevant of these products. This provides a useful survey of simulation methods and feature sets, which are able to serve as an important source of inspiration for this thesis. 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 and a wide range of analog and digital peripherals, including UART, I2C EEPROMs and analog 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. 11 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 [24] is a professional 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 12 James McGill - 40793625 Embedded Systems Simulator models of a 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 provided 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. Figure 3: Real time simulation of a graphical LCD in Proteus VSM 13 James McGill - 40793625 Embedded Systems Simulator 3.3 Atmel AVR Studio Atmel AVR Studio 4 [25] 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 [26]. The simulator also lacks any built-in peripheral implementations, making functional verification of code difficult. By combining the debugger with an Integrated Code Development, AVR Studio allows systems to be debugged in the context of the code being executed. 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. 14 James McGill - 40793625 Embedded Systems Simulator Figure 4: Expanded register view from AVR Studio. 3.4 miSim DE miSim DE [27] 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 publically available Java based API. This flexibility has been used by many 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, limited to use with PIC microcontrollers, and is unable to simulate systems with other microcontrollers, no microcontroller or more than one microcontroller. 15 James McGill - 40793625 Embedded Systems Simulator 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 overarching 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, source code 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, which is used in this course. The final product must also be able to functionally simulate the interaction between this device and multiple external peripherals. 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 multiple components while still being able to run at an average speed of no less than 4MHz. At this speed, the simulator must also be able to update a Graphical User Interface frequently enough to convey small changes in the state of the peripherals, and to maintain responsiveness. The simulator must be able to support representations of open drain (tri-state) drivers and weak signals, as they are used to implement common embedded systems communication protocols such as OWI [31]. 4.1 Software architecture requirements The final implementation should provide system which allows external components to be easily developed, independently of the core simulator and of each other, and to interact with other components during simulation. These components should be available in a format that is easy to distribute. 18 James McGill - 40793625 Embedded Systems Simulator The simulator must allow the development of both synchronous and asynchronous digital devices using C++. 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, thus allowing the software 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 [18]. 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 USART: A component which emulates the function of an external USART transceiver, able to receive and transmit data using the RS232 communications standard [28]. The component should be able to detect errors in transmission, including incorrect baud rates. The USART component should also be able to communicate with applications outside the simulator, to simulate the interactions between an embedded systems and external devices. 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 circuitry 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 an input is 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, submitted as part of this thesis. Documentation will also be written for those using the simulator, and those hoping 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 2GHz 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 available only for 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 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 being run. 4.6 Outside scope During the development cycle of a single project, it is likely that the composition of the 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 XML project files. The simulation of analogue components, or of the parasitic effects on digital logic, such as capacitance and inductance, is also considered 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 simple 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 the framework can be extended 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. 1.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 AND 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 discussion in Sections 5.2.3 through 5.2.6. The actions of these classes are co-ordinated by a discrete event simulation algorithm (). Simulations can be distributed and repeated by loading their details from XML files which implement the simulation project format, as described in Section 5.7. To allow developers to independently create additional components, the definition of a component’s behaviour is 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, is examined in Section 5.5. 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 Event Event Event Event Graphical User Interface Event Event list Repeated Event List Discrete Event Simulator Figure 5: Overview of simulator architecture 5.1 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. The implementation of the event-set, used to order events within the simulator, uses multiple event-sets, building upon the work of Goh and Thng [13]. 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. 23 James McGill - 40793625 Embedded Systems Simulator As it is expected that the simulator will often be used to simulate synchronous components, a separate event queue is provided for events which are repeated regularly ( Figure 5). Events added to the repeated event queue 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 re-schedule an event each time a synchronous device is clocked. 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 with only small decreases in performance. The inner loop of the simulator is responsible for interlacing events from the two event queues, and ensures that they are always executed in the correct order. 5.1.1 Enqueing 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 or in response to Event execution or Pin value changes. The type of event queue to which the Event is to be added – regular (synchronous) or normal – is specified by the API call. 5.2Simulator 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 24 James McGill - 40793625 Embedded Systems Simulator allowing the reliability of a long running embedded system to be examined. Although 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 an abstract C++ data type was considered too great a cost. The simulator timestamp can be used by Component and Pin implementations as a means of verifying timing characteristics of digital devices, such as setup and hold times. 5.2.1 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 object to be re-scheduled, even while being executed, which allows simulations to be performed which require no explicit memory management during execution. 5.2.2 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 execute stably regardless of CPU speed. By removing the real-time constraint, low activity simulations can be sped up, providing an efficient method for soak testing an embedded system [25]. 25 James McGill - 40793625 Embedded Systems Simulator As the simulator is not designed to run on a real-time operating system, small fluctuations in speed have been deemed acceptable. 5.2.3 Components The logic required to simulate and describe a digital device is implemented by extending the abstract Component class. In addition to defining the required structure of a Component object, the Component class provides an API, which can be used to manager interaction with the simulator framework, Pin objects, and component meta-data. 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 Components 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 external stimuli from another Component. 5.2.4 Providing a graphical representation of a components state Component objects provide logic to render a graphical representation of a components current state, using the Cairo graphics library [34]. Cairo was chosen as it provides a cross platform method of drawing complex vector and raster graphics onto a variety of surfaces, including the user interface used to interact with the simulation, and a variety of image formats which could be used to produce documentation. Components are explicitly refreshed in response to state changes or GUI interaction, thus ensuring that the least amount of processing time possible is used to maintain an accurate graphical state. 26 James McGill - 40793625 Embedded Systems Simulator 5.2.5 Events Components are able to schedule logic to be executed at a specific time by implementing concrete versions of the abstract Event class. Events are executed in monotonic increasing order based on the time at which they are scheduled, which ensures that simulations are stable and deterministic. 5.2.6 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. The value of a Pin is stored as a 16 bit unsigned integer. 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) 32, 768 – 65, 535 Analog values Table 1:Interpretation of valid pin values. Adhering to this protocol, and ensuring that each Component behaves as it would as a physical device, allows components developed by different parties to interact correctly. A 27 James McGill - 40793625 Embedded Systems Simulator 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. The protocol also allows analogue values to be represented with 15 bit accuracy, allowing components to simulate interfaces to quantized analogue devices. Analogue values are easily detected by checking for a ‘1’ in the most significant bit of the Pin value. Each Pin implements both a Concrete Subject and Concrete Observer from the Observer design pattern [34], 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 method, 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 Notification: Value = 1 Pin B Value: 0 1 Notification: Value = 1 aVasd asd as aVasd asd as Figure 6: Cyclic notification problem. a a The two components will continue to notify each other indefinitely unless terminated. 28 Val Val James McGill - 40793625 Pin A Embedded Systems Simulator 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 resolved, as in (b), for correct simulation. 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.3 Error checking 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 embedded systems, as the components can automatically detect and report common errors and timing violations. 5.4 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 29 James McGill - 40793625 Embedded Systems Simulator 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 [36]. This library was selected as it cross platform, actively maintained and simple to use. The GUI uses the Model-View-Controller pattern [34] to allow the Simulator to be controlled, and its current state represented in the GUI, while allowing re-use of the Simulator logic with other . Components may also spawn additional GUI windows, which are managed by the Controller. This allows components to provide additional information that is not easily represented on the main user interface. To ensure that the GUI remains responsive, it is executed on a separate, lower priority thread to the simulator. The logic to render component graphics, however, is executed on the simulator thread to ensure that the graphical representation is able to be updated rapidly. (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). 30 James McGill - 40793625 Embedded Systems Simulator 5.5 Cross platform plug-in architecture The Embedded Systems 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 without requiring a centralized build process. The plug-in framework implemented is based on the work of Sayfan [29] 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 the Component class, as well as supporting Pin and Event objects. Plugin 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 is used to load the dynamic libraries and execute their exposed C methods independently of the host operating system and library format. As Unix 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 31 James McGill - 40793625 Embedded Systems Simulator 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 C API which is passed as a set of function pointers to each plug-in upon instantiation. This use of function pointers allows the component to be compiled with only the definitions of the API function prototypes, and without their implementations. 5.6Automatic plug-in documentation generation As documentation is a key goal of this thesis, the Component interface was carefully designed so that the developer of a component must provide enough information to fully document the component as part of the component implementation. This information has been used to automatically generate navigable HTML documentation for each component (Figure 9) and an index of all available components. 32 James McGill - 40793625 Embedded Systems Simulator 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.7 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 and project meta-data. 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 is encapsulated within a single file. The project stores the names and properties of the components involved in the simulation, the connections between these components and defines the order in which the components should be arranged on the GUI. XML is 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 33 James McGill - 40793625 Embedded Systems Simulator 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. The format is fully described by the XML schema in Appendix A. 5.7.1 Loading simulation projects Simulation projects are loaded using an instance of the XmlParser class, which uses the cross platform TinyXML [31] library to parse the XML project file. The TinyXml library provides good error detection and robustness when parsing invalid documents. 34 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 several 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 component 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 and Counters and USART. 6.1.1 Common AVR functionality The AT90S8515 takes advantage of the hierarchical nature of Object Oriented software to partition the implementation into elements which are specific to the AT90S8515, and elements which are common between all AVR microcontrollers (Figure 10). This will allow implementations of additional microcontrollers in the AVR range to be developed with minimal effort. 35 James McGill - 40793625 Embedded Systems Simulator Plug-in Component AVR Core AVR Peripheral .. . AT90S8515 AVR Peripheral Figure 10: AT90S8515 class architecture As all AVR microcontrollers implement some subset of the AVR Instruction Set [39], the interpretation and execution of instructions is performed by the AVR Core. The AVR Core 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 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 8-bit instruction. AvrInstruction classes also provide meta-data to facilitate disassembly and debugging. 36 James McGill - 40793625 Embedded Systems Simulator Each Instruction class is able to partially disassemble an AVR binary file, using a Factory [35] method to create an instance of the Instruction 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 extracting operands from an op-code (Figure 11), and to interpret these operands. Pre-parsing the binary input, and pre-processing each instruction, leads to faster simulation speeds by reducing the overhead incurred while executing each instruction. Once resolved, instructions are stored in an array, allowing them to be indexed using the current value of the Program Counter. Instructions which occupy more than one 16-bit instruction word are allocated multiple slots in the array in order to preserve indexing. 0010 11rd dddd rrrr Figure 11: Demonstration of interlaced operands (MOV opcode) 6.1.3 Registers and data storage The hardware functions of AVR microcontrollers are controlled by manipulating the values of 8 bit I/O registers, while working registers and SRAM are provided for volatile data storage. The AVR Core component provides an API, which uses address segmentation (Figure 12) to allow memory address to be read from and written to in a consistent manner. Each I/O register is a concrete implementation of the AvrRegister 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 PORT registers to the 8 Pin objects which represent the pins of that port. 37 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 (unsigned char’s) is used to provide an efficient method for storing 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 AVR Core upon initialization, allowing it to be reused for any AVR microcontroller. 6.1.4 Automatic generation of skeleton classes To reduce the time required to implement AvrInstruction and AvrRegister objects, python programs have been written which produce skeleton classes for each instruction and register implemented by a selected AVR device. 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 programs are estimated to have reduced development 38 James McGill - 40793625 Embedded Systems Simulator time by several weeks, and to have significantly reduced the number of errors involved parsing instruction op-codes. 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 an interrupt vector location. The AVR Core component is designed to isolate the implementers of additional components from the complexity of detecting interrupt conditions, and ensuring interrupts are executed at the correct time, in the correct order, and with a 3 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 AVR Core takes advantage of this architecture, and only evaluates an interrupt when the value of one of the registers it is linked to is changed. In order for an I/O register to be registered with the AVR Core as an interrupt status or mask register, it must inherit from AvrInterruptRegister, which provides the functionality needed to allow the interrupt manager to register as an observer of the register. If multiple interrupts are triggered simultaneously, their registered priority is used to ensure that they are executed in the correct order. It remains the responsibility of the specialization of the AVR Core to set interrupt flag bits at the appropriate time, for example to signify a timer overflow. 39 James McGill - 40793625 Embedded Systems Simulator I T H S V N Z C Status register Flag Status register Interrupt triggered Enable Corresponding mask register Figure 13: Conditions required for an interrupt to be triggered. 6.1.6 Execution – cycle correctness and status register The AVR Core is designed to produce cycle correct simulations, which includes ensuring that instructions are executed using the correct number of 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 is written to memory on the final cycle. This has been demonstrated to lead to errors in simulation when an instruction modifies a location at the same time 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. As part of the execution of an instruction, it is likely that the AVR Status Register will need to be updated. This register records certain conditions which may occur during an instructions execution, such as a negative result being produced, which is used by later branching instructions. The AvrInstruction class structure separates the logic required to update the status register from the logic required to execute the remainder of the instruction. This is 40 James McGill - 40793625 Embedded Systems Simulator designed to allow computation of the status register value to be delayed until the value is required by a branching instruction, reducing the number of unnecessary computations; however this ability is not currently used. 6.1.7 Graphical User Interface and debugging functionality In addition to simulating the behaviour of an AVR, the AVR Core 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 do not impact the simulation speed. The meta-data included in AvrRegister objects is used to allow registers to be watched by name (i.e. SREG) in addition to by address (i.e. 63). The Avr Core 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 the compiled instructions. 41 James McGill - 40793625 Embedded Systems Simulator Figure 14: The AVR Core debugging window. 6.1.8 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 communication modules (USART, SPI and TWI). To ensure that these features can be re-used by other implementations of AVR microcontrollers, peripherals are implemented by inheriting from the AvrPeripheral interface. Each peripheral can register concrete implementations of AvrRegister objects with the AVR Core, and can implement logic to be executed on each clock cycle. In addition to allowing re-use, this provides a simple way to partition the complex functionality of a microcontroller. 42 James McGill - 40793625 Embedded Systems Simulator Concrete AVRPeripheral objects have been developed that implement the complete functionality of the 8 Timer/Counter, 16 bit Timer/Counter with PWM, External interrupts 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 AVR Core. 6.1.9 EEPROM Peripheral In addition to emulating the runtime storage of data, the EEPROM peripheral is able to serialize data to and from Intel Hex files, providing the ability to transfer data between the compiler, simulator and physical device 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.10 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 the AVR Core 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. 43 James McGill - 40793625 Embedded Systems Simulator 6.2 Automated testing of the Atmel AT90S8515 plug-in 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 Atmel to eventually produce the correct set of outputs without following the same execution path that it would on the physical device. To overcome these issues, an automatic framework for testing plug-in implementations of AVR microcontrollers has been implemented. The framework allows errors in the implementation of the plug-in, and their effects, to be identified within an accuracy of a single execution step. 6.2.1 Automated Atmel testing framework implementation details The AVR microcontroller plug-in testing framework works by loading an implementation of an AVR microcontroller as a simulator plug-in and executing a compiled AVR hex file on the component. After each execution step, the state of the simulated microcontroller, defined by the current values of every working register, IO 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 state. In order to run the tests, the expected state of the microcontroller at each state of execution must be known. This information can be captured from the physical device using the JTAG or DebugWire ICE protocols. For older microcontrollers, where no ICE 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, using the AutoIt COM 44 James McGill - 40793625 Embedded Systems Simulator library, to automatically capture the state of a program being executed in AVR Studio. 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 implementation. The ability of this black box testing method to empirically test these assumptions, by comparing against an implementation which is known to be correct, is one of its greater strengths. This ability is demonstrated in Figure 15, which shows the output of the framework after executing an incorrect implementation of the NEG (Two’s compliment negation) instruction stored at address 0x0B. … [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 15: Output from the Avr Testing Framework, indicating an error in the implementation of the NEG instruction. 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 are described in 6.3 TCP/IP based Usart Terminal To provide a method for external systems to communicate with devices under simulation, a component has been developed which is able transfer data between a TCP/IP connection and 45 James McGill - 40793625 Embedded Systems Simulator simulated devices which implement the RS232 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 across multiple operating systems. The component uses the simulator timestamp to calculate the baud rate at which data is arriving on the components 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 AVR device. Figure 16: Detection of incorrect baud rates during simulation, and a view of the simulator error log. 6.4 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 Digital 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 MIDI note (Figure 17), and playing that note using the cross platform PortMidi MIDI library [40]. MIDI was selected as it is able to be implemented cross platform, 46 James McGill - 40793625 Embedded Systems Simulator allows notes to be produced at a single frequency with little overhead (unlike sampled formats such as WAV), and can be muted and used on devices without motherboard speakers. 𝑀𝐼𝐷𝐼 𝑁𝑜𝑡𝑒 𝐼𝐷 = 57 + 12 𝑙𝑜𝑔2( 𝑓 ) 440 Figure 17: Formula for conversion between frequency (Hz) and MIDI Note ID 6.5 Additional components In addition to the components discussed above, the following components have been implemented and demonstrated to work: Led – A single colour LED 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 BCD 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 with implementation of the HD-44780 LCD controller instruction set (except custom graphics). This component has an integrated 47 James McGill - 40793625 Embedded Systems Simulator pull up-resistor on the enable line, which has been used to demonstrate the ability to simulate open-drain communication protocols. (Figure 18) Figure 18: Simulation of an 80 character LCD being driven by an AT90S8515 microcontroller. 48 James McGill - 40793625 Embedded Systems Simulator 7.0 Verification of solution By examining the solution developed, the extent to which the simulator developed meets or exceeds the goals proposed earlier in the project (Section 4.0) can be established. From this, conclusions can be drawn regarding the effectiveness of the solution, and of the author’s time management and planning abilities. The remainder of this chapter discusses the completeness and correctness of the solution delivered, and reflects on the 7.1 Testing methadology The solution delivered, in the form of the simulator software and associated plug-ins, has been carefully verified using both manual testing, automated black box testing. 7.1.1 Manual testing of the simulator framework During the development of the simulator, manual testing against a small set of simulator projects was used to identify regression bugs in the simulation framework and to provide an indication of the simulators 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. To ensure consistency in testing, a detailed testing plan has been produced for each test, an example of which is included in Appendix C. Appendix D provides an overview of the manual tests developed, and outlines the broad range of simulator and component features which they are designed to test. In addition to structured manual testing throughout the development of the project, additional manual testing has been carried out at the conclusion of the project in order to obtain accurate measurements of performance, portability and suitability for future distribution. Except as 49 James McGill - 40793625 Embedded Systems Simulator otherwise mentioned, 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 has been used to evaluate performance. This particular implementation utilizes all peripherals developed for the simulated AT908515 component, The compare match and PWM capabilities of both timers are used continuously to play music and to refresh an LED matrix, while USART is used to refresh a terminal based display at regular intervals. This has been determined to provide a realistic representation of a ... The input to the simular is a compiled binary submitted by the student, which is executed without modification. ...l 7.2 Completeness Manual testing has shown that the simulator meets or exceeds all the goals set at the start of the project. The simulation framework is both fast enough to allow real-time simulation of complex digital systems (Section 7.2.2), and flexible enough to allow additional components to be developed and distributed independently (Section 7.2.3). The simulator also provides a simple user interface to allow interaction with the system under simulation and is capable of representing interactions between components using multiple signal classes, including opendrain and weak drivers. 7.2.1 Required components All required components, outlined in Section 4.2, have been implemented and demonstrated to work using manual testing. In addition, a number of additional components, detailed in Section 6.5, have been implemented and tested. These additional components extend the 50 James McGill - 40793625 Embedded Systems Simulator usefulness of the simulator, and are also used to test and demonstrate various aspects of the framework. The AT90S8515 component implements the complete subset of AVR instructions available to the AT90S8515 microcontroller, with the exception of those only required by hardware functions which were not implemented (WRD and SLEEP). Both Timer/Counter peripherals, EEPROM, USART and external interrupts have been implemented. The AT90S8515 plug-in also exceeds its original specifications by incorporating basic debugging capabilities. 7.2.2 Performance The speed of simulation varies significantly based on the components involved in the simulation, as the simulator framework accounts for only a small percentage (X%) of execution time. 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 GHz CPU. Tetris running on a 4 MHz AT90S8515 has been measured to run at an average of 300% of real-time on the same CPU. The relatively small decrease in performance compared to an Atmel only system is consistent with the complexity of the AT90S8515 component compared to other devices. When real-time simulation is enabled, the simulation speed is constrained to 100% of real time. Figure 19 plots the difference between simulation time and wall clock time over a period of 0.25 seconds, while running and interacting with Tetris. Simulation time lags wall clock time at initialization (time = 0) as all components are sent initialization events, and all signals in the system must be resolved to an initial value. The error converges to ±7mS within 50mS, which is maintained for the majority of the simulation Figure 20. The discontinuities 51 James McGill - 40793625 Embedded Systems Simulator observed 20mS intervals are delays imposed by the simulator to limit the simulation speed. A maximum deviation in simulator time from wall clock time of ±15mS has been observed over 30 seconds of simulation, with an average absolute deviation of 3.92mS. These observations are consistent with measures taken while simulating other systems. This error is not expected to be noticeable by users, as it is well below the perceptual threshold of humans. Error between simulation time and wall clock time 15 10 Error in mS 5 0 -5 -10 -15 0 50 100 150 200 250 Elapsed time in mS Figure 19: Error between simulation time and wall clock time over 250mS. Error between simulation time and wall clock time 15 10 Error in mS 5 0 -5 -10 -15 0 0.2 0.4 0.6 0.8 1 1.2 Time elapsed in mS 1.4 1.6 1.8 2 Figure 20: Error between simulation time and wall clock time over 22 seconds 52 2.2 x 10 4 James McGill - 40793625 Embedded Systems Simulator Manual testing of the systems has confirmed that the simulator is able to run at speeds which are not perceptually different from the speed of the physical system. This has primarily been verified by observing the speed of text scrolling on an LED Matrix, and by observing the timing of notes in the music played during Tetris. As real-time simulation requires simulations to be able to execute faster than real time, it is not expected to be possible to achieve real-time simulation speeds in systems with large numbers of synchronous components. Simulations are, however, guaranteed to execute events in the correct order. This has been verified by inserting artificial delays to delay simulation to below 1% of real time. At this speed, all manual tests are shown to function correctly, but at significantly reduced speeds. 7.2.3 Software architecture requirements / Extensibility The simulator is easily extended by developing additional plug-ins. This allows multiple authors to develop and distribute additional simulator components independently. It is not expected that the underlying simulator framework will need to be extended, as complex functionality (such as the Atmel debugging facilities) can be built into components without modifying the underlying framework. 7.2.4 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 (#Appendix reference) and uses 53 James McGill - 40793625 Embedded Systems Simulator clear names for variables and functions. Combined with the high level design outlined in this document, any experience programmer should have little difficulty maintaining or extending the functionality of the simulator framework. Unfortunately, some elements of the case base, particularly plug-in components, remain uncommented. These components will need to be documented before they can be expected to be maintained. 7.2.5 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. In addition to this document, which is expected to be the starting point for developers hoping to extend the simulator framework or implement additional AVR components, a detailed tutorial has beem 7.2.6 Portability The simulator framework, and all components developed thus far, benefit from careful design choices which allow them to be compiled and run on multiple operating systems with native speed (Figure 22) and a consistent look and feel (Figure 21). The simulator and all plug-ins developed have been compiled and executed on Windows XP, Mac OS X 10.5 and Ubuntu Linux 8.10. 54 James McGill - 40793625 Embedded Systems Simulator (a) (b) Figure 21: Comparison of user interface on Windows XP (a) and Mac OS X 10.5 (b). TODO Figure 22: Comparison of simulator speed on Mac OS X, Windows XP and Ubuntu Linux. The Scons (#reference) 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 GUI based debugging on Windows and Mac OS X respectively. 7.2.7 System integration The integrated functionality of the simulator is best demonstrated through simulation of the CSSE1000 final project, which was to implement Tetris using an LED Matrix. In addition to requiring multiple complex components (Speaker, LED Matrix, AVR and USART to TCP/IP), many submissions for this project use all available AVR hardware features (Timers/Counters, EEPROM, USART, PWM and interrupts). The simulator has been demonstrated to accurately simulate many different students’ submissions of this project. 55 James McGill - 40793625 Embedded Systems Simulator Figure 23: CSSE1000 final project (Tetris) with advanced use of sound, USART (graphics) and EEPROM (high scores). 7.3 Correctness The correctness of the simulator has been verified using a combination of manual and automated testing techniques. By using strict testing methodologies, accurate statements as to the state of the simulator framework and component implementations can be made. 7.3.1Automatic testing of the AT90S8515 component In addition to the use manual testing to test the simulator framework and simple components, automatic testing was employed to provide more accurate testing of the AT90S8515 component (Section 6.2). Tests were developed in order to specifically test the implementation of the AVR 8-bit instruction set, as well as hardware features such as Timer/Counter 0, USART, Interrupts, and PORT, PIN and DDR values. As can be seen in Figure 24, every AVR instruction is tested at least once by the automatic testing suite, and many instructions are executed tested several hundred times. In addition to 56 James McGill - 40793625 Embedded Systems Simulator confirming that each instruction is implemented correctly, 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. Unfortunately, some hardware features such as Timer/Counter 1 and EEPROM could be test using the automatic framework, as correct values for their state during program executions could be not be obtained. Where possible 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.2 Results of testing As of the time of submission, all manual and automatic tests pass. Based on these results, it can be concluded that the simulator is able to correctly simulate many different synchronous 57 James McGill - 40793625 Embedded Systems Simulator and asynchronous systems. As part of the manual 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. As each implemented AVR instruction is executed at least once, it can also be concluded that every instruction is implemented correctly enough to 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. Both Timer/Counter 0, Usart, and the AVR interrupt system have also been verified function correctly. While Timer/Counter 1, PWM and EEPROM functionality has not been verified, it has been demonstrated to work using manual tests, with no perceived errors. 7.4 Discussion 58 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. 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 extremely useful. Although projects are assumed to be edited much less frequently than they are run, editing XML 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 registers, or to step through code using C statements. By incorporating the ability to load information contained within the DWARF debugging format, produced as an output of the AVRT compilation process, this functionality could be added to future AVR plug-ins.. 8.3 Automated testing framework While a framework has been put in place to allow simulated AVR components to be automatically tested, manual testing is still required to test a digital system as a whole. A framework which could automatically test an entire system, and the response of that system to various inputs, would be extremely value. Such a system could easily be developed by 59 James McGill - 40793625 Embedded Systems Simulator leveraging the ability to send events to components to simulate user interaction, and by adding the ability for components to report their current state in a non-graphical manner. 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, such as Microchip PIC and Motorola Freescale, and additional digital logic. 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 Section 4.0, a decision was made to keep the code used to provide graphical representations of component 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 text-only simulations as a potential speed up. 60 James McGill - 40793625 Embedded Systems Simulator 9.0 Conclusion This document has outlined the motivations behind the development of an embedded systems simulator. The implementation of the simulator, as well as several simulated components, has been discussed in detail, and key design decisions have been highlighted and justified. By employing both manual and automatic testing, the simulator framework and components developed have been demonstrated to both meet and exceed the original goals of the project, and to correctly simulate synchronous and asynchronous digital systems, as well as demonstrating the ability for hardware/software co-simulation by simulation a substantial portion of the Atmel AT90S8515 microcontroller’s capabilities. Finally, the simulator has been shown to be useful in simulation the practical exercises and project used by the Introduction to Digital Systems course at the University of Queensland, thus demonstrating it is both usable and useful to those involved in developing of embedded systems. 61 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] P. Pop, P. Eles, Z. Peng, and T. Pop, "Analysis and optimization of distributed real-time embedded systems," ACM Transactions on Design Automation of Electronic Systems, vol. 11, no. 3, pp. 593-625, Jul. 2006. [4] 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. [5] 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. [6] 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. 62 James McGill - 40793625 Embedded Systems Simulator [7] 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. [8] 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. [9] 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. [10 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. [11 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. [12 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. 1220-1227, Oct. 1988. [13 R. Goh and I. Thng, "MLIST: An efficient pending event set structure for discrete event 63 James McGill - 40793625 ] Embedded Systems Simulator simulation.," International Journal of Simulation, vol. 4, no. 5-6, pp. 66-77, Jun. 2004. [14 P. Phillips and G. Phillips, "No Source Code? No Problem," ACM Queue, vol. 1, no. 6, ] pp. 50-57, Sep. 2003. [15 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. [16 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. [17 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. 192201. [18 Atmel. ] (2008, Sep.) AT90S8515. [Online]. http://www.atmel.com/dyn/resources/prod_documents/doc0841.pdf [19 U. o. Queensland. (2008, Sep.) AVR Project Board Schematic. [Online]. http://www.itee.uq.edu.au/~csse1000/pracs/Atmel_AVR_Resources/AVR_Project_Board 64 James McGill - 40793625 ] Embedded Systems Simulator .pdf [20 N. Reynolds, "Embedded Systems Simulator," University of Queensland Bachelor of ] Engineering Honours Thesis, 2007. [21 J. Kehl, "Embedded System Simulator," University of Queensland Bachelor of ] Engineering Honours Thesis , 2004. [22 D. Nixon, "Embedded System Simulator," University of Queensland Bachelor of ] Engineering Honours Thesis, 2004. [23 Oshon ] Avr Simulator IDE. [Online]. Electronics. (2008, Sep.) Proteus VSM. [Online]. (2008, Jul.) AVR Studio 4. [Online]. MKII. [Online]. http://www.atmel.com/dyn/Products/tools_card.asp?tool_id=2725 [26 Atmel. ] Aug.) http://www.labcenter.co.uk/products/vsm_overview.cfm [25 Atmel. ] (2008, http://www.oshonsoft.com/avr.html [24 Labcenter ] Software. (2006, Jul.) AVR JTAG ICE http://www.atmel.com/dyn/Products/tools_card.asp?tool_id=3353 65 James McGill - 40793625 [27 Feersum ] Embedded Systems Simulator Technology. (2008, Sep.) miSIim DE. [Online]. http://www.feertech.com/misim/ [28 Dallas Semiconductor. (2001, Mar.) Application Note 83: Fundamentals of RS-232 ] Serial Communications. [Online]. http://www.maxim-ic.com/appnotes.cfm/an_pk/83 [29 G. Sayfan. (2007, Nov.) Dr Dobb's Portal. [Online]. http://www.ddj.com/cpp/204202899 ] [30 Nulidex. ] Mar.) HTML Template C++ Library. [Online]. http://sourceforge.net/projects/htmltemplatec [31 L. ] (2009, Thompson. (2009, Mar.) TinyXML Library. [Online]. http://www.grinninglizard.com/tinyxml/ [32 D. J. Jackson and P. Capsi, "Embedded Systems Education: Future Directions, Initiatives ] and Cooperation," ACM SIGBED Review, vol. 2, no. 4, pp. 1-4, Oct. 2005. [33 J. A. Fisher, P. Farabos, and C. Young, Embedded Computing; A VLIW approach to ] architecture, compilers and tools. San Fransisco, CA, 2005. [34 M. Barr, Programming embedded systems in C and C++. Sebastopol, CA: O'Reilly, 66 James McGill - 40793625 ] Embedded Systems Simulator 1999. [35 C. E. Wick, "Teaching embedded computer systems with a Windows-based simulator," ] in Frontiers in Education Conference, Salt Lake City, 1996, pp. 242-245. [36 P. Pop, P. Eles, Z. Peng, and T. Pop, "Analysis and optimization of distributed real-time ] embedded systems," ACM Transactions on Design Automation of Electronic Systems (, vol. 11, no. 3, pp. 593-625, Jul. 2006. [37 Dallas Semiconductor. (2008, Aug.) DS1821 Programmable Digital Thermostat and ] Thermometer. [Online]. http://datasheets.maxim-ic.com/en/ds/DS1821.pdf [38 SGI. ] Sep.) libdwarf Homepage. [Online]. http://reality.sgiweb.org/davea/dwarf.html [39 Compuware. ] (2008, (2008, Sep.) DevPartner http://www.compuware.com/products/devpartner/studio.htm 67 Studio. [Online]. 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: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> <xsd:element name='component_reference'> <xsd:complexType> <xsd:attribute name='component' type='xsd:string' use='required'/> 68 James McGill - 40793625 Embedded Systems Simulator </xsd:complexType> </xsd:element> <xsd:element name='row'> <xsd:complexType> <xsd:sequence maxOccurs='unbounded'> <xsd:element ref='component_reference'/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name='layout'> <xsd:complexType> <xsd:sequence maxOccurs='unbounded'> <xsd:element ref='row'/> </xsd:sequence> </xsd:complexType> </xsd:element> <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> 69 James McGill - 40793625 Embedded Systems Simulator Appendix B: Django templates for Instruction 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 }}]; 70 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. 71 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. 72 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 }} }; 73 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 %} 74 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 %}; 75 James McGill - 40793625 Embedded Systems Simulator return output.str(); } const string {{ class }}::description() const { return "{{ mnemonic }} {{ operands }} : {{ description }}"; } uint32 {{ class }}::mask_32() const { return {{ mask_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. 76 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. 77 James McGill - 40793625 Embedded Systems Simulator Appendix D: Summary of manual tests Test name Prac 4 Prac 5-1 Test purpose Test summary Key aspects tested Verify that CSSE1000 Prac 4 Output two's complement of switches to LED, Switch, AVR PORT, PIN and DDR works. LEDs. Registers. Verify that CSSE1000 Prac Output two's complement of switches to LED, Switch, AVR PORT, PIN and DDR 5-1 works. LEDs. Registers. Verify that CSSE1000 Prac Prac 5-2 5-2 works. LED, Switch, AVR PORT, PIN and DDR Output index of active switch to LEDs. Verify that CSSE1000 Prac Prac 5-3 Prac 6-1 LED, Switch, AVR PORT, PIN and DDR 5-3 works. Output index of active switch to LEDs. Registers, Conditional logic Verify that CSSE1000 Prac Output two's complement of switches to LED, Switch, AVR PORT, PIN and DDR 6-1 works. LEDs. Registers. C Code. Verify that CSSE1000 Prac Prac 6-2 6-2 works. LED, Switch, AVR PORT, PIN and DDR Output index of active switch to LEDs. Verify that CSSE1000 Prac Prac 6-3 Registers, Conditional logic 6-3 works. Registers. C Code. Conditional logic. LED, Switch, AVR PORT, PIN and DDR Output index of active switch to LEDs. 78 Registers. C Code. Conditional logic. James McGill - 40793625 Test name Prac 7-1 Prac 7-2 Prac 7-3 Embedded Systems Simulator Test purpose Test summary Key aspects tested Verify that CSSE1000 Prac Drive a speaker at 1KHz with a software Speaker, Timers/Counter 1, Simulator 7-1 works. timer. timestamps. Verify that CSSE1000 Prac Drive a speaker at 1KHz using 16 bit 7-2 works. hardware timer. Speaker, Timer/Counter 1, PWM and CTC. Verify that CSSE1000 Prac Drive a speaker at 1KHz using 16 bit Speaker, Timer/Counter 1, PWM and CTC. 7-3 works. hardware timer. C Code. Drive a speaker at 1KHz using 16 bit Prac 8-1 Verify that CSSE1000 Prac hardware timer. Mute using edge triggered Speaker, Timer/Counter 1, PWM and CTC, 8-1 works. interrupts. External interrupts. Drive a speaker at 1KHz using 16 bit Prac 8-2 Prac 8-3 Verify that CSSE1000 Prac hardware timer for at most 1.5 seconds. Speaker, Timer/Counter 1, Timer/Counter 0, 8-2 works. Restart using edge triggered interrupts. PWM and CTC, External interrupts. Verify that CSSE1000 Prac USART echo with digits 1 - 9 translated to USART, RS232 to TCP/IP, Baud rate 8-3 works. words. detection, USART Interrupts buffered when components 3 flip flops are chained together and all Flip flop component, simulator timestamps, are updated together.. clocked at 1Hz. simulator stability, real-time simulation. Verify that pin values are T Flip Flops 79 James McGill - 40793625 Test name Test purpose Embedded Systems Simulator Test summary Key aspects tested Phrase is read from EEPROM, displayed on EEPROM Verify that EEPROM can be USART, cyphered, and written back to read from and written to. EEPROM. USART, EEPROM Verify that asynchronous Momentary components can be simulated Pushbutton is released 2 seconds after it is Real time simulation of asynchronous switch. in real-time. pressed. components. Cycle through all 16 digits at 1 Hz Timer/Counter 0, Seven Segment component Seven Segment Verify that the seven segment Display component works. Display two lines of text and scroll them off LCD Verify that the LCD the screen. Contains one (purposeful) timing LCD, real-time simulation, Timer/Counter 0, component works error. Error reporting. correctly and at the correct Run a feature-rich Tetris submission from a Usart, Interrupts, Speaker, Timers/Counters, speed. past student. Performance Verify that Tetris runs Tetris 80 James McGill - 40793625 Test name Test purpose Embedded Systems Simulator Test summary Key aspects tested Verify that Snake runs Snake correctly and at the correct Run a feature-rich Snake submission of my speed. own. USART, Interrupts, Speaker, Performance correctly and at the correct Run a feature-rich Asteroids submission USART, Interrupts, Speaker, speed. from a past student. Timers/Counters, Performance Verify that Asteroids runs Asteroids 81 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. 82