| #!/usr/bin/env python | |
| import argparse | |
| import IPython | |
| import logging | |
| import threading | |
| import os | |
| import socket | |
| import subprocess | |
| import sys | |
| import telnetlib | |
| import time | |
| ENVIRON = os.environ.copy() | |
| log = logging.getLogger() | |
| log_handle = logging.StreamHandler() | |
| log.addHandler(log_handle) | |
| log.setLevel(logging.INFO) | |
| parser = argparse.ArgumentParser( | |
| description="Start renode and connect to UART.") | |
| parser.add_argument('--script', dest='script_file', | |
| help='script file to run within renode', | |
| default="") | |
| parser.add_argument('-i', '--interactive', dest='interactive', | |
| help='enable interactive mode', default=False, | |
| action="store_true") | |
| parser.add_argument('-u', '--uart', dest='connect_uart', | |
| help='enable uart', default=False, | |
| action="store_true") | |
| parser.add_argument('--setup_uart', dest='setup_uart', | |
| help='setup uart', default=False, | |
| action="store_true") | |
| parser.add_argument('-U', '--uart_name', dest='uart_name', | |
| help='select uart', default="sysbus.uart") | |
| class RenodeMonitor(object): | |
| def __init__(self, host="127.0.0.1", port=1234): | |
| self.host = host | |
| self.port = port | |
| self.tn = None | |
| def connect(self): | |
| self.tn = telnetlib.Telnet(host=self.host, port=self.port) | |
| self.recieve_all() | |
| def recieve_all(self): | |
| while True: | |
| reply = self.tn.read_until("\n", timeout=.1) | |
| if reply: | |
| log.info(reply) | |
| else: | |
| break | |
| def send_command(self, command): | |
| log.info("Send command: %s", command) | |
| cmd = "\n%s\n" % command | |
| self.tn.write(cmd) | |
| self.recieve_all() | |
| def start(self): | |
| self.send_command("start") | |
| def execute_script(self, script_path): | |
| self.send_command("include @%s" % script_path) | |
| def setup_uart(self, uart_name="sysbus.uart"): | |
| log.info("Setup the uart %s", uart_name) | |
| self.send_command('emulation CreateServerSocketTerminal 3456 "term"') | |
| self.send_command("connector Connect %s term" % uart_name) | |
| time.sleep(0.5) | |
| self.recieve_all() | |
| def quit(self): | |
| self.send_command("quit") | |
| class RenodeThread(threading.Thread): | |
| def __init__(self, script=""): | |
| super(RenodeThread, self).__init__() | |
| self.script = script | |
| self.proc = None | |
| self.connect() | |
| self.monitor = RenodeMonitor() | |
| time.sleep(2.0) | |
| self.monitor.connect() | |
| if script: | |
| self.monitor.execute_script(script) | |
| def connect(self): | |
| cmd = ["mono", | |
| "%s/host/renode/Renode.exe" % ENVIRON['OUT'], | |
| "--disable-xwt"] | |
| log.info("Runnning renode command '%s'", " ".join(cmd)) | |
| self.proc = subprocess.Popen(cmd, env=ENVIRON, | |
| stdout=subprocess.PIPE, | |
| stderr=subprocess.STDOUT) | |
| def run(self): | |
| while True: | |
| output = self.proc.stdout.readline() | |
| if output: | |
| log.info(output) | |
| if self.proc.poll() is not None: | |
| break | |
| log.info("Waiting on renode to exit.") | |
| self.proc.wait() | |
| log.info("Renode has exited.") | |
| def kill(self): | |
| if self.proc: | |
| if self.proc.returncode is None: | |
| self.proc.kill() | |
| def main(): | |
| args = parser.parse_args() | |
| print(args) | |
| renode = RenodeThread(args.script_file) | |
| renode.start() | |
| if args.connect_uart or args.setup_uart: | |
| renode.monitor.setup_uart(uart_name=args.uart_name) | |
| time.sleep(0.5) | |
| renode.monitor.start() | |
| if args.connect_uart: | |
| log.info("\n\nConnect to UART\n\n") | |
| tn = telnetlib.Telnet('localhost', 3456) | |
| tn.close() | |
| tn.open('localhost', 3456) | |
| try: | |
| tn.interact() | |
| except KeyboardInterrupt: | |
| renode.kill() | |
| if args.interactive: | |
| IPython.embed() | |
| renode.kill() | |
| if __name__ == "__main__": | |
| main() |