mirror of
https://git.yoctoproject.org/meta-arm
synced 2026-04-20 11:29:54 +00:00
At the moment, when using the --console flag, if telnet is shut down cleanly (i.e. by typing "quit" at the prompt instead of Ctrl+C), runfvp still waits on the FVP to exit of its own accord, so hangs. Move the fvp.run() call so that when telnet quits, it immediately proceeds to shut down the FVP. Issue-Id: SCM-4954 Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com> Change-Id: I2169c99586a1eebc2c6ab4b2e15fb0c769fc81a8 Signed-off-by: Jon Mason <jon.mason@arm.com>
105 lines
3.6 KiB
Python
Executable File
105 lines
3.6 KiB
Python
Executable File
#! /usr/bin/env python3
|
|
|
|
import asyncio
|
|
import os
|
|
import pathlib
|
|
import signal
|
|
import sys
|
|
|
|
import logging
|
|
logger = logging.getLogger("RunFVP")
|
|
|
|
# Add meta-arm/lib/ to path
|
|
libdir = pathlib.Path(__file__).parents[1] / "meta-arm" / "lib"
|
|
sys.path.insert(0, str(libdir))
|
|
|
|
from fvp import terminal, runner, conffile
|
|
|
|
def parse_args(arguments):
|
|
import argparse
|
|
terminals = terminal.terminals
|
|
|
|
parser = argparse.ArgumentParser(description="Run images in a FVP")
|
|
parser.add_argument("config", nargs="?", help="Machine name or path to .fvpconf file")
|
|
group = parser.add_mutually_exclusive_group()
|
|
group.add_argument("-t", "--terminals", choices=terminals.all_terminals(), default=terminals.preferred_terminal(), help="Automatically start terminals (default: %(default)s)")
|
|
group.add_argument("-c", "--console", action="store_true", help="Attach the first uart to stdin/stdout")
|
|
parser.add_argument("--verbose", action="store_true", help="Output verbose logging")
|
|
parser.usage = f"{parser.format_usage().strip()} -- [ arguments passed to FVP ]"
|
|
# TODO option for telnet vs netcat
|
|
|
|
# If the arguments contains -- then everything after it should be passed to the FVP binary directly.
|
|
if "--" in arguments:
|
|
i = arguments.index("--")
|
|
fvp_args = arguments[i+1:]
|
|
arguments = arguments[:i]
|
|
else:
|
|
fvp_args = []
|
|
|
|
args = parser.parse_args(args=arguments)
|
|
logging.basicConfig(level=args.verbose and logging.DEBUG or logging.WARNING)
|
|
|
|
# If we're hooking up the console, don't start any terminals
|
|
if args.console:
|
|
args.terminals = "none"
|
|
|
|
logger.debug(f"Parsed arguments: {vars(args)}")
|
|
logger.debug(f"FVP arguments: {fvp_args}")
|
|
return args, fvp_args
|
|
|
|
|
|
async def start_fvp(args, config, extra_args):
|
|
fvp = runner.FVPRunner(logger)
|
|
try:
|
|
await fvp.start(config, extra_args, args.terminals)
|
|
|
|
if args.console:
|
|
fvp.add_line_callback(lambda line: logger.debug(f"FVP output: {line}"))
|
|
expected_terminal = config["consoles"]["default"]
|
|
if not expected_terminal:
|
|
logger.error("--console used but FVP_CONSOLE not set in machine configuration")
|
|
return 1
|
|
telnet = await fvp.create_telnet(expected_terminal)
|
|
await telnet.wait()
|
|
logger.debug(f"Telnet quit, cancelling tasks")
|
|
else:
|
|
fvp.add_line_callback(lambda line: print(line))
|
|
await fvp.run()
|
|
|
|
finally:
|
|
await fvp.stop()
|
|
|
|
def runfvp(cli_args):
|
|
args, extra_args = parse_args(cli_args)
|
|
if args.config and pathlib.Path(args.config).exists():
|
|
config_file = args.config
|
|
else:
|
|
config_file = conffile.find(args.config)
|
|
logger.debug(f"Loading {config_file}")
|
|
config = conffile.load(config_file)
|
|
|
|
try:
|
|
# When we can assume Py3.7+, this can simply be asyncio.run()
|
|
loop = asyncio.get_event_loop()
|
|
return loop.run_until_complete(start_fvp(args, config, extra_args))
|
|
except asyncio.CancelledError:
|
|
# This means telnet exited, which isn't an error
|
|
return 0
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
# Set the process group so that it's possible to kill runfvp and
|
|
# everything it spawns easily.
|
|
# Ignore permission errors happening when spawned from an other process
|
|
# for example run from except
|
|
try:
|
|
os.setpgid(0, 0)
|
|
except PermissionError:
|
|
pass
|
|
if sys.stdin.isatty():
|
|
signal.signal(signal.SIGTTOU, signal.SIG_IGN)
|
|
os.tcsetpgrp(sys.stdin.fileno(), os.getpgrp())
|
|
sys.exit(runfvp(sys.argv[1:]))
|
|
except KeyboardInterrupt:
|
|
pass
|