#! /usr/bin/env python ############################################################################### # # simulavr - A simulator for the Atmel AVR family of microcontrollers. # Copyright (C) 2001, 2002 Theodore A. Roth # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### # # $Id: base_test.py,v 1.6 2002/04/05 01:05:48 troth Exp $ # import array, struct from registers import Reg, Addr """This module provides base classes for regression test cases. """ class TestFail: def __init__(self, reason): self.reason = reason def __repr__(self): return self.reason class opcode_test: """Base Class for testing opcodes. """ def __init__(self,target): self.target = target def __repr__(self): return self.__name__ def mem_byte_write(self, addr, val): self.target.write_sram(addr, 1, [val]) def mem_byte_read(self, addr): return self.target.read_sram(addr, 1)[0] def prog_word_write(self, addr, val): self.target.write_flash(addr, 2, self.common_build_opcode(val)) def run(self): """Execute the test. If the test fails, an exception will be raised. """ self.common_setup() # setup the test self.target.step() # execute the opcode test self.common_analyze_results() # do the analysis def common_setup(self): """Perform common setup operations. All access to target for setup should be done here. This could be over-ridden by a more specific base class if needed. """ # Fetch all registers (might be able to get away with just creating an # array of zero'd out registers instead of going to target. self.setup_regs = self.target.read_regs() # Run the test case setup and insert opcode into target. raw_opcode = self.setup() opcode = self.common_build_opcode(raw_opcode) self.target.write_flash(self.setup_regs[Reg.PC], len(opcode), opcode) # The test case should modify setup_regs as necessary so here we make sure # the target gets those changes self.target.write_regs(self.setup_regs) def common_build_opcode(self, raw_opcode): """Build up the opcode array for a 16 bit opcode. """ return array.array( 'B', struct.pack('> 16) & 0xffff, (raw_opcode & 0xffff)) ) class opcode_stack_mixin: """Mixin Class for testing opcodes which perform stack operations. """ # Assume an at90s8515 device with end of ram 0x025f (32 + 64 + 512 - 1). # Use 0x0250 so we can pop things off and not go past end of ram. SP_val = 0x0250 def common_setup(self): """Initialize the stack and then call the base class common_setup. """ self.target.write_reg(Reg.SP, self.SP_val) opcode_test.common_setup(self) def setup_write_to_current_stack(self, val): # Since a push is a post-decrement operation and pop is pre-increment, # we need to use SP+1 here. # Also, note that this should only be used in setup. self.target.write_sram(self.SP_val+1, 1, [val]) def setup_word_to_stack(self, val): # used by RET, RETI setup, since they pop at least a word self.target.write_sram(self.SP_val+1, 2, [(val & 0xff00)>>8, val & 0xff]) def analyze_read_from_current_stack(self): return self.target.read_sram(self.SP_val, 1)[0] class opcode_32_test(opcode_32_mixin, opcode_test): pass class opcode_stack_test(opcode_stack_mixin, opcode_test): pass class opcode_stack_32_test(opcode_32_mixin, opcode_stack_mixin, opcode_test): """Base Class for testing 32 bit opcodes with stack operations. """ pass