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>
99 lines
3.5 KiB
Python
99 lines
3.5 KiB
Python
# Copyright (c) 2017 Linaro Limited.
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
'''Runner for NIOS II, based on quartus-flash.py and GDB.'''
|
|
|
|
from .. import log
|
|
from .core import ZephyrBinaryRunner, NetworkPortHelper
|
|
|
|
|
|
class Nios2BinaryRunner(ZephyrBinaryRunner):
|
|
'''Runner front-end for NIOS II.'''
|
|
|
|
# From the original shell script:
|
|
#
|
|
# "XXX [flash] only support[s] cases where the .elf is sent
|
|
# over the JTAG and the CPU directly boots from __start. CONFIG_XIP
|
|
# and CONFIG_INCLUDE_RESET_VECTOR must be disabled."
|
|
|
|
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 = [cfg.gdbgdb] if cfg.gdb else None
|
|
self.tui_arg = ['-tui'] if tui else []
|
|
|
|
@classmethod
|
|
def name(cls):
|
|
return 'nios2'
|
|
|
|
@classmethod
|
|
def do_add_parser(cls, parser):
|
|
# TODO merge quartus-flash.py script into this file.
|
|
parser.add_argument('--quartus-flash', required=True)
|
|
parser.add_argument('--cpu-sof', required=True,
|
|
help='path to the the CPU .sof data')
|
|
parser.add_argument('--tui', default=False, action='store_true',
|
|
help='if given, GDB uses -tui')
|
|
|
|
@classmethod
|
|
def create(cls, cfg, args):
|
|
return Nios2BinaryRunner(quartus_py=args.quartus_flash,
|
|
cpu_sof=args.cpu_sof,
|
|
tui=args.tui)
|
|
|
|
def do_run(self, command, **kwargs):
|
|
if command == 'flash':
|
|
self.flash(**kwargs)
|
|
else:
|
|
self.debug_debugserver(command, **kwargs)
|
|
|
|
def flash(self, **kwargs):
|
|
if self.quartus_py is None:
|
|
raise ValueError('Cannot flash; --quartus-flash not given.')
|
|
if self.cpu_sof is None:
|
|
raise ValueError('Cannot flash; --cpu-sof not given.')
|
|
|
|
cmd = [self.quartus_py,
|
|
'--sof', self.cpu_sof,
|
|
'--kernel', self.hex_name]
|
|
|
|
self.check_call(cmd)
|
|
|
|
def print_gdbserver_message(self, gdb_port):
|
|
log.inf('Nios II GDB server running on port {}'.format(gdb_port))
|
|
|
|
def debug_debugserver(self, command, **kwargs):
|
|
# Per comments in the shell script, the NIOSII GDB server
|
|
# doesn't exit gracefully, so it's better to explicitly search
|
|
# for an unused port. The script picks a random value in
|
|
# between 1024 and 49151, but we'll start with the
|
|
# "traditional" 3333 choice.
|
|
gdb_start = 3333
|
|
nh = NetworkPortHelper()
|
|
gdb_port = nh.get_unused_ports([gdb_start])[0]
|
|
|
|
server_cmd = (['nios2-gdb-server',
|
|
'--tcpport', str(gdb_port),
|
|
'--stop', '--reset-target'])
|
|
|
|
if command == 'debugserver':
|
|
self.print_gdbserver_message(gdb_port)
|
|
self.check_call(server_cmd)
|
|
else:
|
|
if self.elf_name is None:
|
|
raise ValueError('Cannot debug; elf is missing')
|
|
if self.gdb_cmd is None:
|
|
raise ValueError('Cannot debug; no gdb specified')
|
|
|
|
gdb_cmd = (self.gdb_cmd +
|
|
self.tui_arg +
|
|
[self.elf_name,
|
|
'-ex', 'target remote :{}'.format(gdb_port)])
|
|
|
|
self.print_gdbserver_message(gdb_port)
|
|
self.run_server_and_client(server_cmd, gdb_cmd)
|