zephyr/scripts/meta/west/runner/openocd.py
Marti Bolivar 5317f76dec 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 <marti@opensourcefoundries.com>
2018-05-19 07:01:39 +03:00

146 lines
5.2 KiB
Python

# Copyright (c) 2017 Linaro Limited.
#
# SPDX-License-Identifier: Apache-2.0
'''Runner for openocd.'''
from os import path
from .core import ZephyrBinaryRunner
DEFAULT_OPENOCD_TCL_PORT = 6333
DEFAULT_OPENOCD_TELNET_PORT = 4444
DEFAULT_OPENOCD_GDB_PORT = 3333
class OpenOcdBinaryRunner(ZephyrBinaryRunner):
'''Runner front-end for openocd.'''
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):
super(OpenOcdBinaryRunner, self).__init__(cfg)
self.openocd_config = path.join(cfg.board_dir, 'support',
'openocd.cfg')
search_args = []
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
self.post_cmd = post_cmd
self.tcl_port = tcl_port
self.telnet_port = telnet_port
self.gdb_port = gdb_port
self.gdb_cmd = [cfg.gdb] if cfg.gdb else None
self.tui_arg = ['-tui'] if tui else []
@classmethod
def name(cls):
return 'openocd'
@classmethod
def do_add_parser(cls, parser):
# Options for flashing:
parser.add_argument('--cmd-pre-load',
help='Command to run before flashing')
parser.add_argument('--cmd-load',
help='''Command to load/flash binary
(required when flashing)''')
parser.add_argument('--cmd-verify',
help='''Command to verify flashed binary''')
parser.add_argument('--cmd-post-verify',
help='Command to run after verification')
# Options for debugging:
parser.add_argument('--tui', default=False, action='store_true',
help='if given, GDB uses -tui')
parser.add_argument('--tcl-port', default=DEFAULT_OPENOCD_TCL_PORT,
help='openocd TCL port, defaults to 6333')
parser.add_argument('--telnet-port',
default=DEFAULT_OPENOCD_TELNET_PORT,
help='openocd telnet port, defaults to 4444')
parser.add_argument('--gdb-port', default=DEFAULT_OPENOCD_GDB_PORT,
help='openocd gdb port, defaults to 3333')
@classmethod
def create(cls, cfg, args):
return OpenOcdBinaryRunner(
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)
def do_run(self, command, **kwargs):
if command == 'flash':
self.do_flash(**kwargs)
elif command == 'debug':
self.do_debug(**kwargs)
else:
self.do_debugserver(**kwargs)
def do_flash(self, **kwargs):
if self.load_cmd is None:
raise ValueError('Cannot flash; load command is missing')
if self.verify_cmd is None:
raise ValueError('Cannot flash; verify command is missing')
pre_cmd = []
if self.pre_cmd is not None:
pre_cmd = ['-c', self.pre_cmd]
post_cmd = []
if self.post_cmd is not None:
post_cmd = ['-c', self.post_cmd]
cmd = (self.openocd_cmd +
['-f', self.openocd_config,
'-c', 'init',
'-c', 'targets'] +
pre_cmd +
['-c', 'reset halt',
'-c', self.load_cmd,
'-c', 'reset halt',
'-c', self.verify_cmd] +
post_cmd +
['-c', 'reset run',
'-c', 'shutdown'])
self.check_call(cmd)
def do_debug(self, **kwargs):
if self.gdb_cmd is None:
raise ValueError('Cannot debug; no gdb specified')
if self.elf_name is None:
raise ValueError('Cannot debug; no .elf specified')
server_cmd = (self.openocd_cmd +
['-f', self.openocd_config,
'-c', 'tcl_port {}'.format(self.tcl_port),
'-c', 'telnet_port {}'.format(self.telnet_port),
'-c', 'gdb_port {}'.format(self.gdb_port),
'-c', 'init',
'-c', 'targets',
'-c', 'halt'])
gdb_cmd = (self.gdb_cmd + self.tui_arg +
['-ex', 'target remote :{}'.format(self.gdb_port),
self.elf_name])
self.run_server_and_client(server_cmd, gdb_cmd)
def do_debugserver(self, **kwargs):
cmd = (self.openocd_cmd +
['-f', self.openocd_config,
'-c', 'init',
'-c', 'targets',
'-c', 'reset halt'])
self.check_call(cmd)