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>
diff --git a/scripts/support/runner/core.py b/scripts/support/runner/core.py
index 1aafc23..a38f7b0 100644
--- a/scripts/support/runner/core.py
+++ b/scripts/support/runner/core.py
@@ -12,6 +12,7 @@
"""
import abc
+import argparse
import os
import platform
import shlex
@@ -147,12 +148,36 @@
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 @@
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 @@
* --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 @@
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 @@
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').