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)