From 5317f76dec7de2c85c8b9268c9947920724117e9 Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Thu, 10 May 2018 00:58:03 -0400 Subject: [PATCH] scripts: west: introduce common runner configuration Continue better integration of the runner subpackage into west by moving the common runner configuration options into the command core. This allows commands like "west flash -h" to display help for common overrides like --kernel-hex. Adjustments needed to make this happen are: - Change the build system to separate common configuration values from runner-specific options and arguments - Prepare the runner core by defining a new RunnerConfig class that represents the common configuration, and accepting that from a new create() method, which replaces create_from_args(). - Convert all concrete runner classes to use the new style of argument parsing and initialization. - Group the command options appropriately for help output readability There's still a bit of tool-specific stuff in the common configuration (gdb and openocd configuration in particular); a more generic way to deal with that will be necessary to better support things like non-GDB debuggers, but that's out of scope of this patch. All the runner-specific options are still in the runner packge, which currently prevents them from being included in "west flash -h" etc. Fixing that is also out of scope of this patch. This has the ancillary benefit of getting rid of the legacy 'debug' argument to ZephyrBinaryRunner, which is no longer appropriate since verbose debug logging is handled by log.py in west. Signed-off-by: Marti Bolivar --- cmake/flash/CMakeLists.txt | 47 +++++--- scripts/meta/west/cmd/run_common.py | 139 +++++++++++++++++++----- scripts/meta/west/runner/arc.py | 30 +++-- scripts/meta/west/runner/bossac.py | 14 +-- scripts/meta/west/runner/core.py | 89 +++++++++------ scripts/meta/west/runner/dfu.py | 15 ++- scripts/meta/west/runner/esp32.py | 16 ++- scripts/meta/west/runner/intel_s1000.py | 29 ++--- scripts/meta/west/runner/jlink.py | 29 +++-- scripts/meta/west/runner/nios2.py | 20 ++-- scripts/meta/west/runner/nrfjprog.py | 11 +- scripts/meta/west/runner/openocd.py | 40 +++---- scripts/meta/west/runner/pyocd.py | 25 ++--- scripts/meta/west/runner/qemu.py | 19 ++-- scripts/meta/west/runner/xtensa.py | 15 ++- 15 files changed, 314 insertions(+), 224 deletions(-) diff --git a/cmake/flash/CMakeLists.txt b/cmake/flash/CMakeLists.txt index 7cf64dc22e0..0ccbf0480f0 100644 --- a/cmake/flash/CMakeLists.txt +++ b/cmake/flash/CMakeLists.txt @@ -3,20 +3,6 @@ assert_not(DEBUG_SCRIPT "DEBUG_SCRIPT has been removed; use BOARD_DEBUG_RUNNER") get_property(RUNNERS GLOBAL PROPERTY ZEPHYR_RUNNERS) -# These arguments are common to all runners. -set(RUNNER_ARGS_COMMON - # Required: - "--board-dir=${BOARD_DIR}" - "--kernel-elf=${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME}" - "--kernel-hex=${PROJECT_BINARY_DIR}/${KERNEL_HEX_NAME}" - "--kernel-bin=${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME}" - # Optional, but so often needed that they're provided by default: - # (TODO: revisit whether we really want these here) - "--gdb=${CMAKE_GDB}" - "--openocd=${OPENOCD}" - "--openocd-search=${OPENOCD_DEFAULT_PATH}" - ) - # Enable verbose output, if requested. if(CMAKE_VERBOSE_MAKEFILE) set(RUNNER_VERBOSE "--verbose") @@ -33,8 +19,37 @@ endif() # configuration if the board files change. if(RUNNERS) set(ZEPHYR_RUNNERS ${RUNNERS} CACHE INTERNAL "Available runners") - set(ZEPHYR_RUNNER_ARGS_COMMON ${RUNNER_ARGS_COMMON} CACHE STRING - "Common arguments to all runners" FORCE) + + # Runner configuration. This is provided to all runners, and is + # distinct from the free-form arguments provided by e.g. + # board_runner_args(). + # + # Always applicable: + set(ZEPHYR_RUNNER_CONFIG_BOARD_DIR "${BOARD_DIR}" + CACHE STRING "Board definition directory" FORCE) + set(ZEPHYR_RUNNER_CONFIG_KERNEL_ELF "${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME}" + CACHE STRING "Path to kernel image in ELF format" FORCE) + set(ZEPHYR_RUNNER_CONFIG_KERNEL_HEX "${PROJECT_BINARY_DIR}/${KERNEL_HEX_NAME}" + CACHE STRING "Path to kernel image in Intel Hex format" FORCE) + set(ZEPHYR_RUNNER_CONFIG_KERNEL_BIN "${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME}" + CACHE STRING "Path to kernel image as raw binary" FORCE) + # Not always applicable, but so often needed that they're provided + # by default: (TODO: clean this up) + if(DEFINED CMAKE_GDB) + set(ZEPHYR_RUNNER_CONFIG_GDB "${CMAKE_GDB}" + CACHE STRING "Path to GDB binary, if applicable" FORCE) + endif() + if(DEFINED OPENOCD) + set(ZEPHYR_RUNNER_CONFIG_OPENOCD "${OPENOCD}" + CACHE STRING "Path to openocd binary, if applicable" FORCE) + endif() + if(DEFINED OPENOCD_DEFAULT_PATH) + set(ZEPHYR_RUNNER_CONFIG_OPENOCD_SEARCH "${OPENOCD_DEFAULT_PATH}" + CACHE STRING "Path to add to openocd search path, if applicable" FORCE) + endif() + + # Runner-specific command line arguments obtained from the board's + # build scripts, the application's scripts, etc. foreach(runner ${RUNNERS}) string(MAKE_C_IDENTIFIER ${runner} runner_id) # E.g. args = BOARD_RUNNER_ARGS_openocd, BOARD_RUNNER_ARGS_dfu_util, etc. diff --git a/scripts/meta/west/cmd/run_common.py b/scripts/meta/west/cmd/run_common.py index 231aa7a82cb..d40278a4cb8 100644 --- a/scripts/meta/west/cmd/run_common.py +++ b/scripts/meta/west/cmd/run_common.py @@ -13,6 +13,7 @@ from textwrap import dedent from .. import cmake from .. import log from ..runner import get_runner_cls +from ..runner.core import RunnerConfig from . import CommandContextError @@ -22,24 +23,56 @@ def add_parser_common(parser_adder, command): formatter_class=argparse.RawDescriptionHelpFormatter, description=command.description) - parser.add_argument('-d', '--build-dir', - help='''Build directory to obtain runner information - from; default is the current working directory.''') - parser.add_argument('-c', '--cmake-cache', default=cmake.DEFAULT_CACHE, - help='''Path to CMake cache file containing runner - configuration (this is generated by the Zephyr - build system when compiling binaries); - default: {}. + group = parser.add_argument_group(title='General Options') + group.add_argument('-d', '--build-dir', + help='''Build directory to obtain runner information + from; default is the current working directory.''') + group.add_argument('-c', '--cmake-cache', default=cmake.DEFAULT_CACHE, + help='''Path to CMake cache file containing runner + configuration (this is generated by the Zephyr + build system when compiling binaries); + default: {}. - If this is a relative path, it is assumed relative to - the build directory. An absolute path can also be - given instead.'''.format(cmake.DEFAULT_CACHE)) - parser.add_argument('-r', '--runner', - help='''If given, overrides any cached {} - runner.'''.format(command.name)) - parser.add_argument('--skip-rebuild', action='store_true', - help='''If given, do not rebuild the application - before running {} commands.'''.format(command.name)) + If this is a relative path, it is assumed relative to + the build directory. An absolute path can also be + given instead.'''.format(cmake.DEFAULT_CACHE)) + group.add_argument('-r', '--runner', + help='''If given, overrides any cached {} + runner.'''.format(command.name)) + group.add_argument('--skip-rebuild', action='store_true', + help='''If given, do not rebuild the application + before running {} commands.'''.format(command.name)) + + group = parser.add_argument_group( + title='Configuration overrides', + description=dedent('''\ + These values usually come from the Zephyr build system itself + as stored in the CMake cache; providing these options + overrides those settings.''')) + + # Important: + # + # 1. The destination variables of these options must match + # the RunnerConfig slots. + # 2. The default values for all of these must be None. + # + # This is how we detect if the user provided them or not when + # overriding values from the cached configuration. + group.add_argument('--board-dir', + help='Zephyr board directory') + group.add_argument('--kernel-elf', + help='Path to kernel binary in .elf format') + group.add_argument('--kernel-hex', + help='Path to kernel binary in .hex format') + group.add_argument('--kernel-bin', + help='Path to kernel binary in .bin format') + group.add_argument('--gdb', + help='Path to GDB, if applicable') + group.add_argument('--openocd', + help='Path to OpenOCD, if applicable') + group.add_argument( + '--openocd-search', + help='Path to add to OpenOCD search path, if applicable') return parser @@ -57,6 +90,30 @@ def desc_common(command_name): '''.format(**{'command': command_name})) +def cached_runner_config(cache): + '''Parse the RunnerConfig from a CMake Cache.''' + board_dir = cache['ZEPHYR_RUNNER_CONFIG_BOARD_DIR'] + kernel_elf = cache['ZEPHYR_RUNNER_CONFIG_KERNEL_ELF'] + kernel_hex = cache['ZEPHYR_RUNNER_CONFIG_KERNEL_HEX'] + kernel_bin = cache['ZEPHYR_RUNNER_CONFIG_KERNEL_BIN'] + gdb = cache.get('ZEPHYR_RUNNER_CONFIG_GDB') + openocd = cache.get('ZEPHYR_RUNNER_CONFIG_OPENOCD') + openocd_search = cache.get('ZEPHYR_RUNNER_CONFIG_OPENOCD_SEARCH') + + return RunnerConfig(board_dir, kernel_elf, kernel_hex, kernel_bin, + gdb=gdb, openocd=openocd, + openocd_search=openocd_search) + + +def _override_config_from_namespace(cfg, namespace): + '''Override a RunnerConfig's contents with command-line values.''' + for var in cfg.__slots__: + if var in namespace: + val = getattr(namespace, var) + if val is not None: + setattr(cfg, var, val) + + def do_run_common(command, args, runner_args, cached_runner_var): command_name = command.name build_dir = args.build_dir or getcwd() @@ -79,6 +136,12 @@ def do_run_common(command, args, runner_args, cached_runner_var): # places. chdir(build_dir) + # Runner creation, phase 1. + # + # Get the default runner name from the cache, allowing a command + # line override. Get the ZephyrBinaryRunner class by name, and + # make sure it supports the command. + # TODO: build this by joining with build_dir once the above chdir # goes away. cache_file = args.cmake_cache @@ -104,22 +167,38 @@ def do_run_common(command, args, runner_args, cached_runner_var): log.die('Runner {} does not support command {}'.format( runner, command_name)) - cached_common_args = cache.get_list('ZEPHYR_RUNNER_ARGS_COMMON') + # Runner creation, phase 2. + # + # At this point, the common options above are already parsed in + # 'args', and unrecognized arguments are in 'runner_args'. + # + # - Pull the RunnerConfig out of the cache + # - Override cached values with applicable command-line options + + cfg = cached_runner_config(cache) + _override_config_from_namespace(cfg, args) + + # Runner creation, phase 3. + # + # - Pull out cached runner arguments, and append command-line + # values (which should override the cache) + # - Construct a runner-specific argument parser to handle cached + # values plus overrides given in runner_args + # - Parse arguments and create runner instance from final + # RunnerConfig and parsed arguments. + cached_runner_args = cache.get_list( 'ZEPHYR_RUNNER_ARGS_{}'.format(cmake.make_c_identifier(runner))) - # Construct the final command line arguments, create a - # runner-specific parser to handle them, and run the command. assert isinstance(runner_args, list), runner_args - final_runner_args = cached_common_args + cached_runner_args + runner_args - - # Having the runners themselves be the place where their argument - # parsing is handled is hackish; it's an artifact of the time - # before the runner package was part of west. - # - # TODO: refactor runner argument parsing higher up into west. + # If the user passed -- to force the parent argument parser to stop + # parsing, it will show up here, and needs to be filtered out. + runner_args = [arg for arg in runner_args if arg != '--'] + final_runner_args = cached_runner_args + runner_args parser = argparse.ArgumentParser(prog=runner) runner_cls.add_parser(parser) - parsed_args = parser.parse_args(args=final_runner_args) - parsed_args.verbose = args.verbose - runner = runner_cls.create_from_args(parsed_args) + parsed_args, unknown = parser.parse_known_args(args=final_runner_args) + if unknown: + raise CommandContextError('Runner', runner, + 'received unknown arguments', unknown) + runner = runner_cls.create(cfg, parsed_args) runner.run(command_name) diff --git a/scripts/meta/west/runner/arc.py b/scripts/meta/west/runner/arc.py index df1f607ea82..87b17a2421b 100644 --- a/scripts/meta/west/runner/arc.py +++ b/scripts/meta/west/runner/arc.py @@ -24,19 +24,16 @@ class EmStarterKitBinaryRunner(ZephyrBinaryRunner): # client to execute the application. # - def __init__(self, board_dir, elf, gdb, - openocd='openocd', search=None, + def __init__(self, cfg, tui=False, tcl_port=DEFAULT_ARC_TCL_PORT, telnet_port=DEFAULT_ARC_TELNET_PORT, - gdb_port=DEFAULT_ARC_GDB_PORT, debug=False): - super(EmStarterKitBinaryRunner, self).__init__(debug=debug) - self.board_dir = board_dir - self.elf = elf - self.gdb_cmd = [gdb] + (['-tui'] if tui else []) + gdb_port=DEFAULT_ARC_GDB_PORT): + super(EmStarterKitBinaryRunner, self).__init__(cfg) + self.gdb_cmd = [cfg.gdb] + (['-tui'] if tui else []) search_args = [] - if search is not None: - search_args = ['-s', search] - self.openocd_cmd = [openocd] + search_args + if cfg.openocd_search is not None: + search_args = ['-s', cfg.openocd_search] + self.openocd_cmd = [cfg.openocd or 'openocd'] + search_args self.tcl_port = tcl_port self.telnet_port = telnet_port self.gdb_port = gdb_port @@ -57,18 +54,17 @@ class EmStarterKitBinaryRunner(ZephyrBinaryRunner): help='openocd gdb port, defaults to 3333') @classmethod - def create_from_args(cls, args): - if args.gdb is None: + def create(cls, cfg, args): + if cfg.gdb is None: raise ValueError('--gdb not provided at command line') return EmStarterKitBinaryRunner( - args.board_dir, args.kernel_elf, args.gdb, - openocd=args.openocd, search=args.openocd_search, + cfg, tui=args.tui, tcl_port=args.tcl_port, telnet_port=args.telnet_port, - gdb_port=args.gdb_port, debug=args.verbose) + gdb_port=args.gdb_port) def do_run(self, command, **kwargs): - kwargs['openocd-cfg'] = path.join(self.board_dir, 'support', + kwargs['openocd-cfg'] = path.join(self.cfg.board_dir, 'support', 'openocd.cfg') if command in {'flash', 'debug'}: @@ -97,7 +93,7 @@ class EmStarterKitBinaryRunner(ZephyrBinaryRunner): ['-ex', 'target remote :{}'.format(self.gdb_port), '-ex', 'load'] + continue_arg + - [self.elf]) + [self.cfg.kernel_elf]) self.run_server_and_client(server_cmd, gdb_cmd) diff --git a/scripts/meta/west/runner/bossac.py b/scripts/meta/west/runner/bossac.py index a34be445656..3138803846f 100644 --- a/scripts/meta/west/runner/bossac.py +++ b/scripts/meta/west/runner/bossac.py @@ -14,10 +14,8 @@ DEFAULT_BOSSAC_PORT = '/dev/ttyACM0' class BossacBinaryRunner(ZephyrBinaryRunner): '''Runner front-end for bossac.''' - def __init__(self, bin_name, bossac='bossac', - port=DEFAULT_BOSSAC_PORT, debug=False): - super(BossacBinaryRunner, self).__init__(debug=debug) - self.bin_name = bin_name + def __init__(self, cfg, bossac='bossac', port=DEFAULT_BOSSAC_PORT): + super(BossacBinaryRunner, self).__init__(cfg) self.bossac = bossac self.port = port @@ -37,9 +35,9 @@ class BossacBinaryRunner(ZephyrBinaryRunner): help='serial port to use, default is /dev/ttyACM0') @classmethod - def create_from_args(command, args): - return BossacBinaryRunner(args.kernel_bin, bossac=args.bossac, - port=args.bossac_port, debug=args.verbose) + def create(cls, cfg, args): + return BossacBinaryRunner(cfg, bossac=args.bossac, + port=args.bossac_port) def do_run(self, command, **kwargs): if platform.system() != 'Linux': @@ -50,7 +48,7 @@ class BossacBinaryRunner(ZephyrBinaryRunner): 'ospeed', '1200', 'cs8', '-cstopb', 'ignpar', 'eol', '255', 'eof', '255'] cmd_flash = [self.bossac, '-p', self.port, '-R', '-e', '-w', '-v', - '-b', self.bin_name] + '-b', self.cfg.kernel_bin] self.check_call(cmd_stty) self.check_call(cmd_flash) diff --git a/scripts/meta/west/runner/core.py b/scripts/meta/west/runner/core.py index 8d199418f03..8cdff1f5f55 100644 --- a/scripts/meta/west/runner/core.py +++ b/scripts/meta/west/runner/core.py @@ -181,6 +181,48 @@ class RunnerCaps: self.commands, self.flash_addr) +class RunnerConfig: + '''Runner execution-time configuration. + + This is a common object shared by all runners. Individual runners + can register specific configuration options using their + do_add_parser() hooks. + + This class's __slots__ contains exactly the configuration variables. + ''' + + __slots__ = ['board_dir', 'kernel_elf', 'kernel_hex', 'kernel_bin', + 'gdb', 'openocd', 'openocd_search'] + + # TODO: revisit whether we can get rid of some of these. Having + # tool-specific configuration options here is a layering + # violation, but it's very convenient to have a single place to + # store the locations of tools (like gdb and openocd) that are + # needed by multiple ZephyrBinaryRunner subclasses. + def __init__(self, board_dir, kernel_elf, kernel_hex, kernel_bin, + gdb=None, openocd=None, openocd_search=None): + self.board_dir = board_dir + '''Zephyr board directory''' + + self.kernel_elf = kernel_elf + '''Path to kernel binary in .elf format''' + + self.kernel_hex = kernel_hex + '''Path to kernel binary in .hex format''' + + self.kernel_bin = kernel_bin + '''Path to kernel binary in .bin format''' + + self.gdb = gdb + ''''Path to GDB compatible with the target, may be None.''' + + self.openocd = openocd + '''Path to OpenOCD to use for this target, may be None.''' + + self.openocd_search = openocd_search + '''directory to add to OpenOCD search path, may be None.''' + + _YN_CHOICES = ['Y', 'y', 'N', 'n', 'yes', 'no', 'YES', 'NO'] @@ -246,7 +288,7 @@ class ZephyrBinaryRunner(abc.ABC): define their own argparse-based interface through the common add_parser() (and runner-specific do_add_parser() it delegates to), and provide a way to create instances of themselves from - parsed arguments via create_from_args(). + a RunnerConfig and parsed runner-specific arguments via create(). Runners use a variety of target-specific tools and configuration values, the user interface to which is abstracted by this @@ -254,8 +296,11 @@ class ZephyrBinaryRunner(abc.ABC): execute one of these commands in its constructor. The actual command execution is handled in the run() method.''' - def __init__(self, debug=False): - self.debug = debug + def __init__(self, cfg): + '''Initialize core runner state. + + `cfg` is a RunnerConfig instance.''' + self.cfg = cfg @staticmethod def get_runners(): @@ -289,42 +334,19 @@ class ZephyrBinaryRunner(abc.ABC): argparse module. For more details, refer to the documentation for argparse.ArgumentParser.add_subparsers(). - The standard (required) arguments are: + The lone common optional argument is: - * --board-dir - * --kernel-elf, --kernel-hex, --kernel-bin - - The standard optional arguments are: - - * --gdb - * --openocd, --openocd-search * --dt-flash (if the runner capabilities includes flash_addr) Runner-specific options are added through the do_add_parser() hook.''' - # Required options. - parser.add_argument('--board-dir', required=True, - help='Zephyr board directory') - parser.add_argument('--kernel-elf', required=True, - help='path to kernel binary in .elf format') - parser.add_argument('--kernel-hex', required=True, - help='path to kernel binary in .hex format') - parser.add_argument('--kernel-bin', required=True, - help='path to kernel binary in .bin format') - - # Optional options. + # Common options that depend on runner capabilities. if cls.capabilities().flash_addr: parser.add_argument('--dt-flash', default='n', choices=_YN_CHOICES, action=_DTFlashAction, - help='''If 'yes', use configuration - generated by device tree (DT) to compute flash + help='''If 'yes', use configuration generated + by device tree (DT) to compute flash addresses.''') - parser.add_argument('--gdb', default=None, - help='GDB compatible with the target') - parser.add_argument('--openocd', default='openocd', - help='OpenOCD to use') - parser.add_argument('--openocd-search', default=None, - help='directory to add to OpenOCD search path') # Runner-specific options. cls.do_add_parser(parser) @@ -336,11 +358,12 @@ class ZephyrBinaryRunner(abc.ABC): @classmethod @abc.abstractmethod - def create_from_args(cls, args): + def create(cls, cfg, args): '''Create an instance from command-line arguments. - These will have been parsed from the command line according to - the specification defined by add_parser().''' + - `cfg`: RunnerConfig instance (pass to superclass __init__) + - `args`: runner-specific argument namespace parsed from + execution environment, as specified by `add_parser()`.''' @classmethod def get_flash_address(cls, args, build_conf, default=0x0): diff --git a/scripts/meta/west/runner/dfu.py b/scripts/meta/west/runner/dfu.py index 202e9e36c06..78f2b970b31 100644 --- a/scripts/meta/west/runner/dfu.py +++ b/scripts/meta/west/runner/dfu.py @@ -19,9 +19,9 @@ DfuSeConfig = namedtuple('DfuSeConfig', ['address', 'options']) class DfuUtilBinaryRunner(ZephyrBinaryRunner): '''Runner front-end for dfu-util.''' - def __init__(self, pid, alt, img, exe='dfu-util', - dfuse_config=None, debug=False): - super(DfuUtilBinaryRunner, self).__init__(debug=debug) + def __init__(self, cfg, pid, alt, img, exe='dfu-util', + dfuse_config=None): + super(DfuUtilBinaryRunner, self).__init__(cfg) self.alt = alt self.img = img self.cmd = [exe, '-d,{}'.format(pid)] @@ -67,9 +67,9 @@ class DfuUtilBinaryRunner(ZephyrBinaryRunner): help='dfu-util executable; defaults to "dfu-util"') @classmethod - def create_from_args(cls, args): + def create(cls, cfg, args): if args.img is None: - args.img = args.kernel_bin + args.img = cfg.kernel_bin if args.dfuse: args.dt_flash = True # --dfuse implies --dt-flash. @@ -79,9 +79,8 @@ class DfuUtilBinaryRunner(ZephyrBinaryRunner): else: dcfg = None - return DfuUtilBinaryRunner(args.pid, args.alt, args.img, - exe=args.dfu_util, dfuse_config=dcfg, - debug=args.verbose) + return DfuUtilBinaryRunner(cfg, args.pid, args.alt, args.img, + exe=args.dfu_util, dfuse_config=dcfg) def find_device(self): cmd = list(self.cmd) + ['-l'] diff --git a/scripts/meta/west/runner/esp32.py b/scripts/meta/west/runner/esp32.py index 3e3c4f9011c..5b1a5aee6d4 100644 --- a/scripts/meta/west/runner/esp32.py +++ b/scripts/meta/west/runner/esp32.py @@ -13,11 +13,10 @@ from .core import ZephyrBinaryRunner, RunnerCaps class Esp32BinaryRunner(ZephyrBinaryRunner): '''Runner front-end for espidf.''' - def __init__(self, elf, device, baud=921600, flash_size='detect', - flash_freq='40m', flash_mode='dio', espidf='espidf', - debug=False): - super(Esp32BinaryRunner, self).__init__(debug=debug) - self.elf = elf + def __init__(self, cfg, device, baud=921600, flash_size='detect', + flash_freq='40m', flash_mode='dio', espidf='espidf'): + super(Esp32BinaryRunner, self).__init__(cfg) + self.elf = cfg.kernel_elf self.device = device self.baud = baud self.flash_size = flash_size @@ -56,7 +55,7 @@ class Esp32BinaryRunner(ZephyrBinaryRunner): it in [ESP_IDF_PATH]/components/esptool_py/esptool/esptool.py''') @classmethod - def create_from_args(command, args): + def create(cls, cfg, args): if args.esp_tool: espidf = args.esp_tool else: @@ -64,10 +63,9 @@ class Esp32BinaryRunner(ZephyrBinaryRunner): 'esptool', 'esptool.py') return Esp32BinaryRunner( - args.kernel_elf, args.esp_device, baud=args.esp_baud_rate, + cfg, args.esp_device, baud=args.esp_baud_rate, flash_size=args.esp_flash_size, flash_freq=args.esp_flash_freq, - flash_mode=args.esp_flash_mode, espidf=espidf, - debug=args.verbose) + flash_mode=args.esp_flash_mode, espidf=espidf) def do_run(self, command, **kwargs): bin_name = path.splitext(self.elf)[0] + path.extsep + 'bin' diff --git a/scripts/meta/west/runner/intel_s1000.py b/scripts/meta/west/runner/intel_s1000.py index 30c1940c6ee..871ac093b95 100644 --- a/scripts/meta/west/runner/intel_s1000.py +++ b/scripts/meta/west/runner/intel_s1000.py @@ -17,19 +17,17 @@ DEFAULT_XT_GDB_PORT = 20000 class IntelS1000BinaryRunner(ZephyrBinaryRunner): '''Runner front-end for Intel_s1000.''' - def __init__(self, - board_dir, xt_ocd_dir, + def __init__(self, cfg, xt_ocd_dir, ocd_topology, ocd_jtag_instr, gdb_flash_file, - elf_name, gdb, - gdb_port=DEFAULT_XT_GDB_PORT, debug=False): - super(IntelS1000BinaryRunner, self).__init__(debug=debug) - self.board_dir = board_dir + gdb_port=DEFAULT_XT_GDB_PORT): + super(IntelS1000BinaryRunner, self).__init__(cfg) + self.board_dir = cfg.board_dir + self.elf_name = cfg.kernel_elf + self.gdb_cmd = cfg.gdb self.xt_ocd_dir = xt_ocd_dir self.ocd_topology = ocd_topology self.ocd_jtag_instr = ocd_jtag_instr self.gdb_flash_file = gdb_flash_file - self.elf_name = elf_name - self.gdb_cmd = gdb self.gdb_port = gdb_port @classmethod @@ -38,12 +36,7 @@ class IntelS1000BinaryRunner(ZephyrBinaryRunner): @classmethod def do_add_parser(cls, parser): - # Required - # Optional - parser.add_argument( - '--gdb-port', default=DEFAULT_XT_GDB_PORT, - help='xt-gdb port, defaults to 20000') parser.add_argument( '--xt-ocd-dir', default='/opt/Tensilica/xocd-12.0.4/xt-ocd', help='ocd-dir, defaults to /opt/Tensilica/xocd-12.0.4/xt-ocd') @@ -56,14 +49,16 @@ class IntelS1000BinaryRunner(ZephyrBinaryRunner): parser.add_argument( '--gdb-flash-file', default='load_elf.txt', help='gdb-flash-file, defaults to load_elf.txt') + parser.add_argument( + '--gdb-port', default=DEFAULT_XT_GDB_PORT, + help='xt-gdb port, defaults to 20000') @classmethod - def create_from_args(command, args): + def create(cls, cfg, args): return IntelS1000BinaryRunner( - args.board_dir, args.xt_ocd_dir, + cfg, args.xt_ocd_dir, args.ocd_topology, args.ocd_jtag_instr, args.gdb_flash_file, - args.kernel_elf, args.gdb, - gdb_port=args.gdb_port, debug=args.verbose) + gdb_port=args.gdb_port) def do_run(self, command, **kwargs): kwargs['ocd-topology'] = path.join(self.board_dir, 'support', diff --git a/scripts/meta/west/runner/jlink.py b/scripts/meta/west/runner/jlink.py index 861a10d68cb..4729278488a 100644 --- a/scripts/meta/west/runner/jlink.py +++ b/scripts/meta/west/runner/jlink.py @@ -16,23 +16,23 @@ DEFAULT_JLINK_GDB_PORT = 2331 class JLinkBinaryRunner(ZephyrBinaryRunner): '''Runner front-end for the J-Link GDB server.''' - def __init__(self, device, - commander='JLinkExe', bin_name=None, + def __init__(self, cfg, device, + commander='JLinkExe', flash_addr=0x0, erase=True, - gdbserver='JLinkGDBServer', iface='swd', speed='auto', - elf_name=None, gdb=None, gdb_port=DEFAULT_JLINK_GDB_PORT, - tui=False, debug=False): - super(JLinkBinaryRunner, self).__init__(debug=debug) + iface='swd', speed='auto', + gdbserver='JLinkGDBServer', gdb_port=DEFAULT_JLINK_GDB_PORT, + tui=False): + super(JLinkBinaryRunner, self).__init__(cfg) + self.bin_name = cfg.kernel_bin + self.elf_name = cfg.kernel_elf + self.gdb_cmd = [cfg.gdb] if cfg.gdb else None self.device = device self.commander = commander - self.bin_name = bin_name self.flash_addr = flash_addr self.erase = erase self.gdbserver_cmd = [gdbserver] self.iface = iface self.speed = speed - self.elf_name = elf_name - self.gdb_cmd = [gdb] if gdb is not None else None self.gdb_port = gdb_port self.tui_arg = ['-tui'] if tui else [] @@ -67,17 +67,16 @@ class JLinkBinaryRunner(ZephyrBinaryRunner): help='if given, mass erase flash before loading') @classmethod - def create_from_args(cls, args): + def create(cls, cfg, args): build_conf = BuildConfiguration(os.getcwd()) flash_addr = cls.get_flash_address(args, build_conf) - return JLinkBinaryRunner(args.device, gdbserver=args.gdbserver, + return JLinkBinaryRunner(cfg, args.device, commander=args.commander, - bin_name=args.kernel_bin, flash_addr=flash_addr, erase=args.erase, iface=args.iface, speed=args.speed, - elf_name=args.kernel_elf, - gdb=args.gdb, gdb_port=args.gdb_port, - tui=args.tui, debug=args.verbose) + gdbserver=args.gdbserver, + gdb_port=args.gdb_port, + tui=args.tui) def print_gdbserver_message(self): log.inf('J-Link GDB server running on port {}'.format(self.gdb_port)) diff --git a/scripts/meta/west/runner/nios2.py b/scripts/meta/west/runner/nios2.py index c57126d60e4..b21013aa772 100644 --- a/scripts/meta/west/runner/nios2.py +++ b/scripts/meta/west/runner/nios2.py @@ -17,14 +17,13 @@ class Nios2BinaryRunner(ZephyrBinaryRunner): # over the JTAG and the CPU directly boots from __start. CONFIG_XIP # and CONFIG_INCLUDE_RESET_VECTOR must be disabled." - def __init__(self, hex_name=None, elf_name=None, cpu_sof=None, - quartus_py=None, gdb=None, tui=False, debug=False): - super(Nios2BinaryRunner, self).__init__(debug=debug) - self.hex_name = hex_name - self.elf_name = elf_name + def __init__(self, cfg, quartus_py=None, cpu_sof=None, tui=False): + super(Nios2BinaryRunner, self).__init__(cfg) + self.hex_name = cfg.kernel_hex + self.elf_name = cfg.kernel_elf self.cpu_sof = cpu_sof self.quartus_py = quartus_py - self.gdb_cmd = [gdb] if gdb is not None else None + self.gdb_cmd = [cfg.gdbgdb] if cfg.gdb else None self.tui_arg = ['-tui'] if tui else [] @classmethod @@ -41,13 +40,10 @@ class Nios2BinaryRunner(ZephyrBinaryRunner): help='if given, GDB uses -tui') @classmethod - def create_from_args(command, args): - return Nios2BinaryRunner(hex_name=args.kernel_hex, - elf_name=args.kernel_elf, + def create(cls, cfg, args): + return Nios2BinaryRunner(quartus_py=args.quartus_flash, cpu_sof=args.cpu_sof, - quartus_py=args.quartus_flash, - gdb=args.gdb, tui=args.tui, - debug=args.verbose) + tui=args.tui) def do_run(self, command, **kwargs): if command == 'flash': diff --git a/scripts/meta/west/runner/nrfjprog.py b/scripts/meta/west/runner/nrfjprog.py index 71a07d12a50..133127c1b3f 100644 --- a/scripts/meta/west/runner/nrfjprog.py +++ b/scripts/meta/west/runner/nrfjprog.py @@ -13,9 +13,9 @@ from .core import ZephyrBinaryRunner, RunnerCaps class NrfJprogBinaryRunner(ZephyrBinaryRunner): '''Runner front-end for nrfjprog.''' - def __init__(self, hex_, family, softreset, debug=False): - super(NrfJprogBinaryRunner, self).__init__(debug=debug) - self.hex_ = hex_ + def __init__(self, cfg, family, softreset): + super(NrfJprogBinaryRunner, self).__init__(cfg) + self.hex_ = cfg.kernel_hex self.family = family self.softreset = softreset @@ -37,9 +37,8 @@ class NrfJprogBinaryRunner(ZephyrBinaryRunner): help='use reset instead of pinreset') @classmethod - def create_from_args(cls, args): - return NrfJprogBinaryRunner(args.kernel_hex, args.nrf_family, - args.softreset, debug=args.verbose) + def create(cls, cfg, args): + return NrfJprogBinaryRunner(cfg, args.nrf_family, args.softreset) def get_board_snr_from_user(self): snrs = self.check_output(['nrfjprog', '--ids']) diff --git a/scripts/meta/west/runner/openocd.py b/scripts/meta/west/runner/openocd.py index cd55b16515f..d55771dbe3a 100644 --- a/scripts/meta/west/runner/openocd.py +++ b/scripts/meta/west/runner/openocd.py @@ -16,22 +16,21 @@ DEFAULT_OPENOCD_GDB_PORT = 3333 class OpenOcdBinaryRunner(ZephyrBinaryRunner): '''Runner front-end for openocd.''' - def __init__(self, openocd_config, - openocd='openocd', search=None, - elf_name=None, + def __init__(self, cfg, pre_cmd=None, load_cmd=None, verify_cmd=None, post_cmd=None, + tui=None, tcl_port=DEFAULT_OPENOCD_TCL_PORT, telnet_port=DEFAULT_OPENOCD_TELNET_PORT, - gdb_port=DEFAULT_OPENOCD_GDB_PORT, - gdb=None, tui=None, debug=False): - super(OpenOcdBinaryRunner, self).__init__(debug=debug) - self.openocd_config = openocd_config + gdb_port=DEFAULT_OPENOCD_GDB_PORT): + super(OpenOcdBinaryRunner, self).__init__(cfg) + self.openocd_config = path.join(cfg.board_dir, 'support', + 'openocd.cfg') search_args = [] - if search is not None: - search_args = ['-s', search] - self.openocd_cmd = [openocd] + search_args - self.elf_name = elf_name + if cfg.openocd_search is not None: + search_args = ['-s', cfg.openocd_search] + self.openocd_cmd = [cfg.openocd] + search_args + self.elf_name = cfg.kernel_elf self.load_cmd = load_cmd self.verify_cmd = verify_cmd self.pre_cmd = pre_cmd @@ -39,7 +38,7 @@ class OpenOcdBinaryRunner(ZephyrBinaryRunner): self.tcl_port = tcl_port self.telnet_port = telnet_port self.gdb_port = gdb_port - self.gdb_cmd = [gdb] if gdb is not None else None + self.gdb_cmd = [cfg.gdb] if cfg.gdb else None self.tui_arg = ['-tui'] if tui else [] @classmethod @@ -71,19 +70,14 @@ class OpenOcdBinaryRunner(ZephyrBinaryRunner): help='openocd gdb port, defaults to 3333') @classmethod - def create_from_args(cls, args): - openocd_config = path.join(args.board_dir, 'support', 'openocd.cfg') - + def create(cls, cfg, args): return OpenOcdBinaryRunner( - openocd_config, - openocd=args.openocd, search=args.openocd_search, - elf_name=args.kernel_elf, - pre_cmd=args.cmd_pre_load, - load_cmd=args.cmd_load, verify_cmd=args.cmd_verify, - post_cmd=args.cmd_post_verify, + cfg, + pre_cmd=args.cmd_pre_load, load_cmd=args.cmd_load, + verify_cmd=args.cmd_verify, post_cmd=args.cmd_post_verify, + tui=args.tui, tcl_port=args.tcl_port, telnet_port=args.telnet_port, - gdb_port=args.gdb_port, gdb=args.gdb, tui=args.tui, - debug=args.verbose) + gdb_port=args.gdb_port) def do_run(self, command, **kwargs): if command == 'flash': diff --git a/scripts/meta/west/runner/pyocd.py b/scripts/meta/west/runner/pyocd.py index eebf486b778..c86c1d18cbd 100644 --- a/scripts/meta/west/runner/pyocd.py +++ b/scripts/meta/west/runner/pyocd.py @@ -15,24 +15,23 @@ DEFAULT_PYOCD_GDB_PORT = 3333 class PyOcdBinaryRunner(ZephyrBinaryRunner): '''Runner front-end for pyOCD.''' - def __init__(self, target, + def __init__(self, cfg, target, flashtool='pyocd-flashtool', flash_addr=0x0, flashtool_opts=None, - gdb=None, gdbserver='pyocd-gdbserver', + gdbserver='pyocd-gdbserver', gdb_port=DEFAULT_PYOCD_GDB_PORT, tui=False, - bin_name=None, elf_name=None, - board_id=None, daparg=None, debug=False): - super(PyOcdBinaryRunner, self).__init__(debug=debug) + board_id=None, daparg=None): + super(PyOcdBinaryRunner, self).__init__(cfg) self.target_args = ['-t', target] self.flashtool = flashtool self.flash_addr_args = ['-a', hex(flash_addr)] if flash_addr else [] - self.gdb_cmd = [gdb] if gdb is not None else None + self.gdb_cmd = [cfg.gdb] if cfg.gdb is not None else None self.gdbserver = gdbserver self.gdb_port = gdb_port self.tui_args = ['-tui'] if tui else [] - self.bin_name = bin_name - self.elf_name = elf_name + self.bin_name = cfg.kernel_bin + self.elf_name = cfg.kernel_elf board_args = [] if board_id is not None: @@ -77,7 +76,7 @@ class PyOcdBinaryRunner(ZephyrBinaryRunner): help='ID of board to flash, default is to prompt') @classmethod - def create_from_args(cls, args): + def create(cls, cfg, args): daparg = os.environ.get('PYOCD_DAPARG') if daparg: log.wrn('Setting PYOCD_DAPARG in the environment is', @@ -91,12 +90,10 @@ class PyOcdBinaryRunner(ZephyrBinaryRunner): flash_addr = cls.get_flash_address(args, build_conf) return PyOcdBinaryRunner( - args.target, flashtool=args.flashtool, - flashtool_opts=args.flashtool_opt, - flash_addr=flash_addr, gdb=args.gdb, + cfg, args.target, flashtool=args.flashtool, + flash_addr=flash_addr, flashtool_opts=args.flashtool_opt, gdbserver=args.gdbserver, gdb_port=args.gdb_port, tui=args.tui, - bin_name=args.kernel_bin, elf_name=args.kernel_elf, - board_id=args.board_id, daparg=args.daparg, debug=args.verbose) + board_id=args.board_id, daparg=args.daparg) def port_args(self): return ['-p', str(self.gdb_port)] diff --git a/scripts/meta/west/runner/qemu.py b/scripts/meta/west/runner/qemu.py index b7e42feb3a5..dd4de5e8e47 100644 --- a/scripts/meta/west/runner/qemu.py +++ b/scripts/meta/west/runner/qemu.py @@ -4,28 +4,31 @@ '''Runner stub for QEMU.''' -from .. import log -from .core import ZephyrBinaryRunner +from .core import ZephyrBinaryRunner, RunnerCaps class QemuBinaryRunner(ZephyrBinaryRunner): '''Place-holder for QEMU runner customizations.''' - def __init__(self, debug=False): - super(QemuBinaryRunner, self).__init__(debug=debug) + def __init__(self, cfg): + super(QemuBinaryRunner, self).__init__(cfg) @classmethod def name(cls): return 'qemu' + @classmethod + def capabilities(cls): + # This is a stub. + return RunnerCaps(commands=set()) + @classmethod def do_add_parser(cls, parser): pass # Nothing to do. @classmethod - def create_from_args(command, args): - return QemuBinaryRunner(debug=args.verbose) + def create(cls, cfg, args): + return QemuBinaryRunner(cfg) def do_run(self, command, **kwargs): - if command == 'debugserver': - log.inf('Detached GDB server') + pass diff --git a/scripts/meta/west/runner/xtensa.py b/scripts/meta/west/runner/xtensa.py index ad0897ed223..931bc1610dd 100644 --- a/scripts/meta/west/runner/xtensa.py +++ b/scripts/meta/west/runner/xtensa.py @@ -12,10 +12,8 @@ from .core import ZephyrBinaryRunner, RunnerCaps class XtensaBinaryRunner(ZephyrBinaryRunner): '''Runner front-end for xt-gdb.''' - def __init__(self, gdb, elf_name, debug=False): - super(XtensaBinaryRunner, self).__init__(debug=debug) - self.gdb_cmd = [gdb] - self.elf_name = elf_name + def __init__(self, cfg): + super(XtensaBinaryRunner, self).__init__(cfg) @classmethod def name(cls): @@ -31,11 +29,12 @@ class XtensaBinaryRunner(ZephyrBinaryRunner): help='path to XTensa tools') @classmethod - def create_from_args(command, args): - xt_gdb = path.join(args.xcc_tools, 'bin', 'xt-gdb') - return XtensaBinaryRunner(xt_gdb, args.kernel_elf, args.verbose) + def create(cls, cfg, args): + # Override any GDB with the one provided by the XTensa tools. + cfg.gdb = path.join(args.xcc_tools, 'bin', 'xt-gdb') + return XtensaBinaryRunner(cfg) def do_run(self, command, **kwargs): - gdb_cmd = (self.gdb_cmd + [self.elf_name]) + gdb_cmd = [self.cfg.gdb, self.cfg.kernel_elf] self.check_call(gdb_cmd)