diff --git a/scripts/support/runner/core.py b/scripts/support/runner/core.py index 1aafc233cf2..a38f7b04c18 100644 --- a/scripts/support/runner/core.py +++ b/scripts/support/runner/core.py @@ -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').