diff --git a/scripts/west_commands/runners/nrf_common.py b/scripts/west_commands/runners/nrf_common.py index afa4665d8f4..75ad66aed99 100644 --- a/scripts/west_commands/runners/nrf_common.py +++ b/scripts/west_commands/runners/nrf_common.py @@ -53,7 +53,7 @@ class NrfBinaryRunner(ZephyrBinaryRunner): def __init__(self, cfg, family, softreset, pinreset, dev_id, erase=False, erase_mode=None, ext_erase_mode=None, reset=True, - tool_opt=None, force=False, recover=False): + tool_opt=None, force=False, recover=False, dry_run=False): super().__init__(cfg) self.hex_ = cfg.hex_file # The old --nrf-family options takes upper-case family names @@ -67,6 +67,7 @@ def __init__(self, cfg, family, softreset, pinreset, dev_id, erase=False, self.reset = bool(reset) self.force = force self.recover = bool(recover) + self.dry_run = bool(dry_run) self.tool_opt = [] if tool_opt is not None: @@ -118,7 +119,6 @@ def do_add_parser(cls, parser): choices=['none', 'ranges', 'all'], help='Select the type of erase operation for the ' 'external non-volatile memory') - parser.set_defaults(reset=True) @classmethod @@ -139,7 +139,10 @@ def ensure_snr(self): self.dev_id = [d.lstrip("0") for d in dev_id] return if not dev_id or "*" in dev_id: - dev_id = self.get_board_snr(dev_id or "*") + if not self.dry_run: + dev_id = self.get_board_snr(dev_id or "*") + else: + dev_id = "DEVICEID" # for a dry run self.dev_id = dev_id.lstrip("0") @abc.abstractmethod @@ -357,10 +360,13 @@ def program_hex(self): if not self.erase and regtool_generated_uicr: self.exec_op('erase', core=core, kind='uicr') else: + erase_mode = self._get_erase_mode(self.erase_mode) if self.erase: erase_arg = 'ERASE_ALL' + elif self.erase_mode: + erase_arg = erase_mode elif self.family == 'nrf54l': - erase_arg = self._get_erase_mode(self.erase_mode) or 'ERASE_NONE' + erase_arg = 'ERASE_NONE' else: erase_arg = 'ERASE_RANGES_TOUCHED_BY_FIRMWARE' @@ -479,10 +485,6 @@ def do_run(self, command, **kwargs): self.ensure_family() - if self.family != 'nrf54l' and self.erase_mode: - raise RuntimeError('Option --erase-mode can only be used with the ' - 'nRF54L family.') - self.ensure_output('hex') if IntelHex is None: raise RuntimeError('Python dependency intelhex was missing; ' diff --git a/scripts/west_commands/runners/nrfutil.py b/scripts/west_commands/runners/nrfutil.py index 0490df29ca1..9deb32e06a0 100644 --- a/scripts/west_commands/runners/nrfutil.py +++ b/scripts/west_commands/runners/nrfutil.py @@ -5,6 +5,7 @@ '''Runner for flashing with nrfutil.''' import json +import shlex import subprocess import sys from pathlib import Path @@ -18,12 +19,12 @@ class NrfUtilBinaryRunner(NrfBinaryRunner): def __init__(self, cfg, family, softreset, pinreset, dev_id, erase=False, erase_mode=None, ext_erase_mode=None, reset=True, tool_opt=None, - force=False, recover=False, - ext_mem_config_file=None): + force=False, recover=False, ext_mem_config_file=None, + dry_run=False): super().__init__(cfg, family, softreset, pinreset, dev_id, erase, erase_mode, ext_erase_mode, reset, tool_opt, force, - recover) + recover, dry_run) self.ext_mem_config_file = ext_mem_config_file @@ -55,7 +56,8 @@ def do_create(cls, cfg, args): ext_erase_mode=args.ext_erase_mode, reset=args.reset, tool_opt=args.tool_opt, force=args.force, recover=args.recover, - ext_mem_config_file=args.ext_mem_config_file) + ext_mem_config_file=args.ext_mem_config_file, + dry_run=args.dry_run) @classmethod def do_add_parser(cls, parser): @@ -63,15 +65,23 @@ def do_add_parser(cls, parser): parser.add_argument('--ext-mem-config-file', required=False, dest='ext_mem_config_file', help='path to an JSON file with external memory configuration') + parser.add_argument('--dry-run', required=False, + action='store_true', + help='''Generate all the commands without actually + executing them''') - def _exec(self, args): + def _exec(self, args, force=False): jout_all = [] cmd = ['nrfutil', '--json', 'device'] + args - self._log_cmd(cmd) - if _DRY_RUN: - return {} + escaped = ' '.join(shlex.quote(s) for s in cmd) + if _DRY_RUN or (self.dry_run): + self.logger.info(escaped) + if not force: + return {} + else: + self.logger.debug(escaped) with subprocess.Popen(cmd, stdout=subprocess.PIPE) as p: for line in iter(p.stdout.readline, b''): @@ -148,7 +158,7 @@ def _append_batch(self, op, json_file): cmd += ['--core', op['core']] if op.get('core') else [] cmd += ['--x-family', f'{self.family}'] cmd += ['--x-append-batch', f'{json_file}'] - self._exec(cmd) + self._exec(cmd, force=True) def _exec_batch(self): # Use x-append-batch to get the JSON from nrfutil itself