scripts: runner: add infrastructure for DT-based flashing

Add the necessary infrastructure to the runner core to support
computing flash addresses based on the devicetree. Specifically, add:

- a new RunnerCaps capability, flash_addr, which lets runners declare
  when they support flashing to an arbitrary address

- a common --dt-flash option to all runner command line parsers which
  support this capability, which lets users request flash addresses to
  be computed from device tree

- a ZephyrBinaryRunner helper method, get_flash_address(), which is
  the common code needed to compute a flash address from device
  tree (or return a default value if non-DT based flashing is
  requested). This relies on the BuildConfiguration parser introduced
  in an earlier patch.

Subsequent patches will use this functionality in individual runners.

Signed-off-by: Marti Bolivar <marti@opensourcefoundries.com>
This commit is contained in:
Marti Bolivar 2017-11-27 12:19:52 -05:00 committed by Anas Nashif
parent 7a3462de7a
commit 3830bc51f2

View file

@ -12,6 +12,7 @@ as well as some other helpers for concrete runner classes.
"""
import abc
import argparse
import os
import platform
import shlex
@ -147,12 +148,36 @@ class BuildConfiguration:
class RunnerCaps:
'''This class represents a runner class's capabilities.
The most basic capability is the set of supported commands,
available in the commands field. This defaults to all three
commands.'''
Each capability is represented as an attribute with the same
name. Flag attributes are True or False.
def __init__(self, commands={'flash', 'debug', 'debugserver'}):
Available capabilities:
- commands: set of supported commands; default is {'flash',
'debug', 'debugserver'}.
- flash_addr: whether the runner supports flashing to an
arbitrary address. Default is False. If true, the runner
must honor the --dt-flash option.
'''
def __init__(self,
commands={'flash', 'debug', 'debugserver'},
flash_addr=False):
self.commands = commands
self.flash_addr = bool(flash_addr)
_YN_CHOICES = ['Y', 'y', 'N', 'n', 'yes', 'no', 'YES', 'NO']
class _DTFlashAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
if values.lower().startswith('y'):
namespace.dt_flash = True
else:
namespace.dt_flash = False
class ZephyrBinaryRunner(abc.ABC):
@ -238,9 +263,7 @@ class ZephyrBinaryRunner(abc.ABC):
def capabilities(cls):
'''Returns a RunnerCaps representing this runner's capabilities.
This implementation returns the default capabilities, which
includes support for all three commands, but no other special
powers.
This implementation returns the default capabilities.
Subclasses should override appropriately if needed.'''
return RunnerCaps()
@ -262,6 +285,7 @@ class ZephyrBinaryRunner(abc.ABC):
* --gdb
* --openocd, --openocd-search
* --dt-flash (if the runner capabilities includes flash_addr)
Runner-specific options are added through the do_add_parser()
hook.
@ -279,6 +303,12 @@ class ZephyrBinaryRunner(abc.ABC):
help='path to kernel binary in .bin format')
# Optional options.
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
addresses.''')
parser.add_argument('--gdb', default=None,
help='GDB compatible with the target')
parser.add_argument('--openocd', default='openocd',
@ -317,6 +347,27 @@ class ZephyrBinaryRunner(abc.ABC):
These will have been parsed from the command line according to
the specification defined by add_parser().'''
@classmethod
def get_flash_address(cls, args, build_conf, default=0x0):
'''Helper method for extracting a flash address.
If args.dt_flash is true, get the address from the
BoardConfiguration, build_conf. (If
CONFIG_HAS_FLASH_LOAD_OFFSET is n in that configuration, it
returns CONFIG_FLASH_BASE_ADDRESS. Otherwise, it returns
CONFIG_FLASH_BASE_ADDRESS + CONFIG_FLASH_LOAD_OFFSET.)
Otherwise (when args.dt_flash is False), the default value is
returned.'''
if args.dt_flash:
if build_conf['CONFIG_HAS_FLASH_LOAD_OFFSET']:
return (build_conf['CONFIG_FLASH_BASE_ADDRESS'] +
build_conf['CONFIG_FLASH_LOAD_OFFSET'])
else:
return build_conf['CONFIG_FLASH_BASE_ADDRESS']
else:
return default
def run(self, command, **kwargs):
'''Runs command ('flash', 'debug', 'debugserver').