west: runners: Add support for multiple device IDs
In order to enable the use case where the underlying flash tool supports bulk-flashing using multiple device IDs, augment the core runner class with this new runner capability and implement it in the nrfutil runner, since the nrfutil tool supports it natively. Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
This commit is contained in:
parent
9388349957
commit
c9151be798
4 changed files with 56 additions and 11 deletions
|
@ -268,6 +268,9 @@ class RunnerCaps:
|
|||
connected to a single computer, in order to select which one will be used
|
||||
with the command provided.
|
||||
|
||||
- mult_dev_ids: whether the runner supports multiple device identifiers
|
||||
for a single operation, allowing for bulk flashing of devices.
|
||||
|
||||
- flash_addr: whether the runner supports flashing to an
|
||||
arbitrary address. Default is False. If true, the runner
|
||||
must honor the --dt-flash option.
|
||||
|
@ -305,6 +308,7 @@ class RunnerCaps:
|
|||
|
||||
commands: set[str] = field(default_factory=lambda: set(_RUNNERCAPS_COMMANDS))
|
||||
dev_id: bool = False
|
||||
mult_dev_ids: bool = False
|
||||
flash_addr: bool = False
|
||||
erase: bool = False
|
||||
reset: bool = False
|
||||
|
@ -316,6 +320,8 @@ class RunnerCaps:
|
|||
# to allow other commands to use the rtt address
|
||||
|
||||
def __post_init__(self):
|
||||
if self.mult_dev_ids and not self.dev_id:
|
||||
raise RuntimeError('dev_id must be set along mult_dev_ids')
|
||||
if not self.commands.issubset(_RUNNERCAPS_COMMANDS):
|
||||
raise ValueError(f'{self.commands=} contains invalid command')
|
||||
|
||||
|
@ -543,7 +549,9 @@ class ZephyrBinaryRunner(abc.ABC):
|
|||
caps = cls.capabilities()
|
||||
|
||||
if caps.dev_id:
|
||||
action = 'append' if caps.mult_dev_ids else 'store'
|
||||
parser.add_argument('-i', '--dev-id',
|
||||
action=action,
|
||||
dest='dev_id',
|
||||
help=cls.dev_id_help())
|
||||
else:
|
||||
|
@ -749,10 +757,13 @@ class ZephyrBinaryRunner(abc.ABC):
|
|||
@classmethod
|
||||
def dev_id_help(cls) -> str:
|
||||
''' Get the ArgParse help text for the --dev-id option.'''
|
||||
return '''Device identifier. Use it to select
|
||||
help = '''Device identifier. Use it to select
|
||||
which debugger, device, node or instance to
|
||||
target when multiple ones are available or
|
||||
connected.'''
|
||||
addendum = '''\nThis option can be present multiple times.''' if \
|
||||
cls.capabilities().mult_dev_ids else ''
|
||||
return help + addendum
|
||||
|
||||
@classmethod
|
||||
def extload_help(cls) -> str:
|
||||
|
|
|
@ -101,12 +101,13 @@ class NrfBinaryRunner(ZephyrBinaryRunner):
|
|||
self.tool_opt += opts
|
||||
|
||||
@classmethod
|
||||
def capabilities(cls):
|
||||
return RunnerCaps(commands={'flash'}, dev_id=True, erase=True,
|
||||
reset=True, tool_opt=True)
|
||||
def _capabilities(cls, mult_dev_ids=False):
|
||||
return RunnerCaps(commands={'flash'}, dev_id=True,
|
||||
mult_dev_ids=mult_dev_ids, erase=True, reset=True,
|
||||
tool_opt=True)
|
||||
|
||||
@classmethod
|
||||
def dev_id_help(cls) -> str:
|
||||
def _dev_id_help(cls) -> str:
|
||||
return '''Device identifier. Use it to select the J-Link Serial Number
|
||||
of the device connected over USB. '*' matches one or more
|
||||
characters/digits'''
|
||||
|
@ -146,9 +147,19 @@ class NrfBinaryRunner(ZephyrBinaryRunner):
|
|||
args.dev_id = previous_runner.dev_id
|
||||
|
||||
def ensure_snr(self):
|
||||
if not self.dev_id or "*" in self.dev_id:
|
||||
self.dev_id = self.get_board_snr(self.dev_id or "*")
|
||||
self.dev_id = self.dev_id.lstrip("0")
|
||||
# dev_id can be None, str or list of str
|
||||
dev_id = self.dev_id
|
||||
if isinstance(dev_id, list):
|
||||
if len(dev_id) == 0:
|
||||
dev_id = None
|
||||
elif len(dev_id) == 1:
|
||||
dev_id = dev_id[0]
|
||||
else:
|
||||
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 "*")
|
||||
self.dev_id = dev_id.lstrip("0")
|
||||
|
||||
@abc.abstractmethod
|
||||
def do_get_boards(self):
|
||||
|
@ -528,5 +539,5 @@ class NrfBinaryRunner(ZephyrBinaryRunner):
|
|||
# All done, now flush any outstanding ops
|
||||
self.flush(force=True)
|
||||
|
||||
self.logger.info(f'Board with serial number {self.dev_id} '
|
||||
'flashed successfully.')
|
||||
self.logger.info(f'Board(s) with serial number(s) {self.dev_id} '
|
||||
'flashed successfully.')
|
||||
|
|
|
@ -30,6 +30,14 @@ class NrfJprogBinaryRunner(NrfBinaryRunner):
|
|||
def name(cls):
|
||||
return 'nrfjprog'
|
||||
|
||||
@classmethod
|
||||
def capabilities(cls):
|
||||
return NrfBinaryRunner._capabilities()
|
||||
|
||||
@classmethod
|
||||
def dev_id_help(cls) -> str:
|
||||
return NrfBinaryRunner._dev_id_help()
|
||||
|
||||
@classmethod
|
||||
def tool_opt_help(cls) -> str:
|
||||
return 'Additional options for nrfjprog, e.g. "--clockspeed"'
|
||||
|
|
|
@ -33,6 +33,15 @@ class NrfUtilBinaryRunner(NrfBinaryRunner):
|
|||
def name(cls):
|
||||
return 'nrfutil'
|
||||
|
||||
@classmethod
|
||||
def capabilities(cls):
|
||||
return NrfBinaryRunner._capabilities(mult_dev_ids=True)
|
||||
|
||||
@classmethod
|
||||
def dev_id_help(cls) -> str:
|
||||
return NrfBinaryRunner._dev_id_help() + \
|
||||
'''.\n This option can be specified multiple times'''
|
||||
|
||||
@classmethod
|
||||
def tool_opt_help(cls) -> str:
|
||||
return 'Additional options for nrfutil, e.g. "--log-level"'
|
||||
|
@ -107,6 +116,12 @@ class NrfUtilBinaryRunner(NrfBinaryRunner):
|
|||
self._op_id += 1
|
||||
self._ops.append(op)
|
||||
|
||||
def _format_dev_ids(self):
|
||||
if isinstance(self.dev_id, list):
|
||||
return ','.join(self.dev_id)
|
||||
else:
|
||||
return self.dev_id
|
||||
|
||||
def _append_batch(self, op, json_file):
|
||||
_op = op['operation']
|
||||
op_type = _op['type']
|
||||
|
@ -151,7 +166,7 @@ class NrfUtilBinaryRunner(NrfBinaryRunner):
|
|||
precmd = ['--x-ext-mem-config-file', self.ext_mem_config_file]
|
||||
|
||||
self._exec(precmd + ['x-execute-batch', '--batch-path', f'{json_file}',
|
||||
'--serial-number', f'{self.dev_id}'])
|
||||
'--serial-number', self._format_dev_ids()])
|
||||
|
||||
def do_exec_op(self, op, force=False):
|
||||
self.logger.debug(f'Executing op: {op}')
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue