diff options
Diffstat (limited to 'scripts/avrsim.py')
-rwxr-xr-x | scripts/avrsim.py | 133 |
1 files changed, 99 insertions, 34 deletions
diff --git a/scripts/avrsim.py b/scripts/avrsim.py index e7f191e8..0dd86200 100755 --- a/scripts/avrsim.py +++ b/scripts/avrsim.py @@ -7,9 +7,10 @@ import sys, optparse, time, os, pty, fcntl, termios, errno import pysimulavr -SERIALBITS = 10 # 8N1 = 1 start, 8 data, 1 stop +SERIALBITS = 10 # 8N1 = 1 start, 8 data, 1 stop SIMULAVR_FREQ = 10**9 + # Class to read serial data from AVR serial transmit pin. class SerialRxPin(pysimulavr.PySimulationMember, pysimulavr.Pin): def __init__(self, baud, terminal): @@ -20,12 +21,14 @@ class SerialRxPin(pysimulavr.PySimulationMember, pysimulavr.Pin): self.delay = SIMULAVR_FREQ // baud self.current = 0 self.pos = -1 + def SetInState(self, pin): pysimulavr.Pin.SetInState(self, pin) self.state = pin.outState if self.pos < 0 and pin.outState == pin.LOW: self.pos = 0 self.sc.Add(self) + def DoStep(self, trueHwStep): ishigh = self.state == self.HIGH self.current |= ishigh << self.pos @@ -33,26 +36,28 @@ class SerialRxPin(pysimulavr.PySimulationMember, pysimulavr.Pin): if self.pos == 1: return int(self.delay * 1.5) if self.pos >= SERIALBITS: - data = bytearray([(self.current >> 1) & 0xff]) + data = bytearray([(self.current >> 1) & 0xFF]) self.terminal.write(data) self.pos = -1 self.current = 0 return -1 return self.delay + # Class to send serial data to AVR serial receive pin. class SerialTxPin(pysimulavr.PySimulationMember, pysimulavr.Pin): def __init__(self, baud, terminal): pysimulavr.Pin.__init__(self) pysimulavr.PySimulationMember.__init__(self) self.terminal = terminal - self.SetPin('H') + self.SetPin("H") self.sc = pysimulavr.SystemClock.Instance() self.delay = SIMULAVR_FREQ // baud self.current = 0 self.pos = 0 self.queue = bytearray() self.sc.Add(self) + def DoStep(self, trueHwStep): if not self.pos: if not self.queue: @@ -61,15 +66,16 @@ class SerialTxPin(pysimulavr.PySimulationMember, pysimulavr.Pin): return self.delay * 100 self.queue.extend(data) self.current = (self.queue.pop(0) << 1) | 0x200 - newstate = 'L' + newstate = "L" if self.current & (1 << self.pos): - newstate = 'H' + newstate = "H" self.SetPin(newstate) self.pos += 1 if self.pos >= SERIALBITS: self.pos = 0 return self.delay + # Support for creating VCD trace files class Tracing: def __init__(self, filename, signals): @@ -80,36 +86,42 @@ class Tracing: return self.dman = pysimulavr.DumpManager.Instance() self.dman.SetSingleDeviceApp() + def show_help(self): ostr = pysimulavr.ostringstream() self.dman.save(ostr) sys.stdout.write(ostr.str()) sys.exit(1) + def load_options(self): if self.dman is None: return - if self.signals.strip() == '?': + if self.signals.strip() == "?": self.show_help() - sigs = "\n".join(["+ " + s for s in self.signals.split(',')]) + sigs = "\n".join(["+ " + s for s in self.signals.split(",")]) self.dman.addDumpVCD(self.filename, sigs, "ns", False, False) + def start(self): if self.dman is not None: self.dman.start() + def finish(self): if self.dman is not None: self.dman.stopApplication() + # Pace the simulation scaled to real time class Pacing(pysimulavr.PySimulationMember): def __init__(self, rate): pysimulavr.PySimulationMember.__init__(self) self.sc = pysimulavr.SystemClock.Instance() - self.pacing_rate = 1. / (rate * SIMULAVR_FREQ) + self.pacing_rate = 1.0 / (rate * SIMULAVR_FREQ) self.next_check_clock = 0 self.rel_time = time.time() - self.best_offset = 0. + self.best_offset = 0.0 self.delay = SIMULAVR_FREQ // 10000 self.sc.Add(self) + def DoStep(self, trueHwStep): curtime = time.time() clock = self.sc.GetCurrentTime() @@ -118,19 +130,23 @@ class Pacing(pysimulavr.PySimulationMember): if offset > 0.000050: time.sleep(offset - 0.000040) if clock >= self.next_check_clock: - self.rel_time -= min(self.best_offset, 0.) + self.rel_time -= min(self.best_offset, 0.0) self.next_check_clock = clock + self.delay * 500 - self.best_offset = -999999999. + self.best_offset = -999999999.0 return self.delay + # Forward data from a terminal device to the serial port pins class TerminalIO: def __init__(self): self.fd = -1 + def run(self, fd): self.fd = fd + def write(self, data): os.write(self.fd, data) + def read(self): try: return os.read(self.fd, 64) @@ -139,6 +155,7 @@ class TerminalIO: pysimulavr.SystemClock.Instance().stop() return "" + # Support for creating a pseudo-tty for emulating a serial port def create_pty(ptyname): mfd, sfd = pty.openpty() @@ -147,16 +164,22 @@ def create_pty(ptyname): except os.error: pass os.symlink(os.ttyname(sfd), ptyname) - fcntl.fcntl(mfd, fcntl.F_SETFL - , fcntl.fcntl(mfd, fcntl.F_GETFL) | os.O_NONBLOCK) + fcntl.fcntl(mfd, fcntl.F_SETFL, fcntl.fcntl(mfd, fcntl.F_GETFL) | os.O_NONBLOCK) tcattr = termios.tcgetattr(mfd) tcattr[0] &= ~( - termios.IGNBRK | termios.BRKINT | termios.PARMRK | termios.ISTRIP | - termios.INLCR | termios.IGNCR | termios.ICRNL | termios.IXON) + termios.IGNBRK + | termios.BRKINT + | termios.PARMRK + | termios.ISTRIP + | termios.INLCR + | termios.IGNCR + | termios.ICRNL + | termios.IXON + ) tcattr[1] &= ~termios.OPOST tcattr[3] &= ~( - termios.ECHO | termios.ECHONL | termios.ICANON | termios.ISIG | - termios.IEXTEN) + termios.ECHO | termios.ECHONL | termios.ICANON | termios.ISIG | termios.IEXTEN + ) tcattr[2] &= ~(termios.CSIZE | termios.PARENB) tcattr[2] |= termios.CS8 tcattr[6][termios.VMIN] = 0 @@ -164,25 +187,66 @@ def create_pty(ptyname): termios.tcsetattr(mfd, termios.TCSAFLUSH, tcattr) return mfd + def main(): usage = "%prog [options] <program.elf>" opts = optparse.OptionParser(usage) - opts.add_option("-m", "--machine", type="string", dest="machine", - default="atmega644", help="type of AVR machine to simulate") - opts.add_option("-s", "--speed", type="int", dest="speed", default=16000000, - help="machine speed") - opts.add_option("-r", "--rate", type="float", dest="pacing_rate", - default=0., help="real-time pacing rate") - opts.add_option("-b", "--baud", type="int", dest="baud", default=250000, - help="baud rate of the emulated serial port") - opts.add_option("-t", "--trace", type="string", dest="trace", - help="signals to trace (? for help)") - opts.add_option("-p", "--port", type="string", dest="port", - default="/tmp/pseudoserial", - help="pseudo-tty device to create for serial port") + opts.add_option( + "-m", + "--machine", + type="string", + dest="machine", + default="atmega644", + help="type of AVR machine to simulate", + ) + opts.add_option( + "-s", + "--speed", + type="int", + dest="speed", + default=16000000, + help="machine speed", + ) + opts.add_option( + "-r", + "--rate", + type="float", + dest="pacing_rate", + default=0.0, + help="real-time pacing rate", + ) + opts.add_option( + "-b", + "--baud", + type="int", + dest="baud", + default=250000, + help="baud rate of the emulated serial port", + ) + opts.add_option( + "-t", + "--trace", + type="string", + dest="trace", + help="signals to trace (? for help)", + ) + opts.add_option( + "-p", + "--port", + type="string", + dest="port", + default="/tmp/pseudoserial", + help="pseudo-tty device to create for serial port", + ) deffile = os.path.splitext(os.path.basename(sys.argv[0]))[0] + ".vcd" - opts.add_option("-f", "--tracefile", type="string", dest="tracefile", - default=deffile, help="filename to write signal trace to") + opts.add_option( + "-f", + "--tracefile", + type="string", + dest="tracefile", + default=deffile, + help="filename to write signal trace to", + ) options, args = opts.parse_args() if len(args) != 1: opts.error("Incorrect number of arguments") @@ -236,10 +300,11 @@ def main(): try: io.run(fd) trace.start() - sc.RunTimeRange(0x7fff0000ffff0000) + sc.RunTimeRange(0x7FFF0000FFFF0000) trace.finish() finally: os.unlink(ptyname) -if __name__ == '__main__': + +if __name__ == "__main__": main() |