scripts: west_commands: runners: nrf_common: update nRF54H support

nRF54H can only be flashed using nrfutil now, so some workaround present
in the nrf_common module are no longer needed, e.g. UICR erasing.

Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
This commit is contained in:
Gerard Marull-Paretas 2024-03-18 11:46:26 +01:00 committed by Carles Cufí
commit 78706dffdb
3 changed files with 44 additions and 42 deletions

View file

@ -29,10 +29,6 @@ UICR_RANGES = {
'NRFDL_DEVICE_CORE_APPLICATION': (0x00FF8000, 0x00FF8800),
'NRFDL_DEVICE_CORE_NETWORK': (0x01FF8000, 0x01FF8800),
},
'NRF54H_FAMILY': {
'NRFDL_DEVICE_CORE_APPLICATION': (0x0FFF8000, 0x0FFF8800),
'NRFDL_DEVICE_CORE_NETWORK': (0x0FFFA000, 0x0FFFA800),
},
'NRF91_FAMILY': {
'NRFDL_DEVICE_CORE_APPLICATION': (0x00FF8000, 0x00FF8800),
}
@ -42,8 +38,7 @@ class NrfBinaryRunner(ZephyrBinaryRunner):
'''Runner front-end base class for nrf tools.'''
def __init__(self, cfg, family, softreset, dev_id, erase=False,
reset=True, tool_opt=[], force=False, recover=False,
erase_all_uicrs=False):
reset=True, tool_opt=[], force=False, recover=False):
super().__init__(cfg)
self.hex_ = cfg.hex_file
if family and not family.endswith('_FAMILY'):
@ -55,7 +50,6 @@ class NrfBinaryRunner(ZephyrBinaryRunner):
self.reset = bool(reset)
self.force = force
self.recover = bool(recover)
self.erase_all_uicrs = bool(erase_all_uicrs)
self.tool_opt = []
for opts in [shlex.split(opt) for opt in tool_opt]:
@ -92,11 +86,6 @@ class NrfBinaryRunner(ZephyrBinaryRunner):
help='''erase all user available non-volatile
memory and disable read back protection before
flashing (erases flash for both cores on nRF53)''')
parser.add_argument('--erase-all-uicrs', required=False,
action='store_true',
help='''Erase all UICR registers before flashing
(nRF54H only). When not set, only UICR registers
present in the hex file will be erased.''')
parser.set_defaults(reset=True)
@ -261,14 +250,36 @@ class NrfBinaryRunner(ZephyrBinaryRunner):
# Get the command use to actually program self.hex_.
self.logger.info('Flashing file: {}'.format(self.hex_))
# What type of erase argument should we pass to the tool?
if self.erase:
erase_arg = 'ERASE_ALL'
# What type of erase/core arguments should we pass to the tool?
core = None
if self.family == 'NRF54H_FAMILY':
erase_arg = 'ERASE_NONE'
if self.erase:
self.exec_op('erase', core='NRFDL_DEVICE_CORE_APPLICATION')
self.exec_op('erase', core='NRFDL_DEVICE_CORE_NETWORK')
if self.build_conf.getboolean('CONFIG_SOC_NRF54H20_CPUAPP'):
if not self.erase:
self.exec_op('erase', core='NRFDL_DEVICE_CORE_APPLICATION',
chip_erase_mode='ERASE_UICR',
qspi_erase_mode='ERASE_NONE')
core = 'NRFDL_DEVICE_CORE_APPLICATION'
elif self.build_conf.getboolean('CONFIG_SOC_NRF54H20_CPURAD'):
if not self.erase:
self.exec_op('erase', core='NRFDL_DEVICE_CORE_NETWORK',
chip_erase_mode='ERASE_UICR',
qspi_erase_mode='ERASE_NONE')
core = 'NRFDL_DEVICE_CORE_NETWORK'
else:
if self.family == 'NRF52_FAMILY':
erase_arg = 'ERASE_PAGES_INCLUDING_UICR'
if self.erase:
erase_arg = 'ERASE_ALL'
else:
erase_arg = 'ERASE_PAGES'
if self.family == 'NRF52_FAMILY':
erase_arg = 'ERASE_PAGES_INCLUDING_UICR'
else:
erase_arg = 'ERASE_PAGES'
xip_ranges = {
'NRF52_FAMILY': (0x12000000, 0x19FFFFFF),
@ -284,24 +295,11 @@ class NrfBinaryRunner(ZephyrBinaryRunner):
if self.family == 'NRF53_FAMILY':
# nRF53 requires special treatment due to the extra coprocessor.
self.program_hex_nrf53(erase_arg, qspi_erase_opt)
elif self.family == 'NRF54H_FAMILY':
self.program_hex_nrf54h()
else:
self.op_program(self.hex_, erase_arg, qspi_erase_opt, defer=True)
self.op_program(self.hex_, erase_arg, qspi_erase_opt, defer=True, core=core)
self.flush(force=False)
def program_hex_nrf54h(self):
if self.erase_all_uicrs:
uicrs = UICR_RANGES['NRF54H_FAMILY']
else:
uicrs = self.hex_get_uicrs()
for uicr_core, range in uicrs.items():
self.exec_op('erasepage', defer=True, core=uicr_core, page=range[0])
self.op_program(self.hex_, 'NO_ERASE', None, defer=True)
def program_hex_nrf53(self, erase_arg, qspi_erase_opt):
# program_hex() helper for nRF53.

View file

@ -32,8 +32,7 @@ class NrfJprogBinaryRunner(NrfBinaryRunner):
args.dev_id, erase=args.erase,
reset=args.reset,
tool_opt=args.tool_opt, force=args.force,
recover=args.recover,
erase_all_uicrs=args.erase_all_uicrs)
recover=args.recover)
def do_get_boards(self):
snrs = self.check_output(['nrfjprog', '--ids'])

View file

@ -5,6 +5,7 @@
import argparse
import functools
import io
import os
from pathlib import Path
import shlex
@ -523,14 +524,16 @@ def check_expected(tool, test_case, check_fn, get_snr, tmpdir, runner_config):
tmpfile = nrfutil_args[nrfutil_args.index('--batch-path') + 1]
cmds = (['nrfutil', '--json', 'device', 'x-execute-batch', '--batch-path',
tmpfile, '--serial-number', expected[0]],)
call_args = [call(nrfutil_args)]
else:
cmds = expected
call_args = check_fn.call_args_list
if callable(cmds):
assert (check_fn.call_args_list ==
assert (call_args ==
[call(x) for x in cmds(tmpdir, runner_config.hex_file)])
else:
assert check_fn.call_args_list == [call(x) for x in cmds]
assert call_args == [call(x) for x in cmds]
if not test_case.snr:
get_snr.assert_called_once_with('*')
@ -542,10 +545,11 @@ def check_expected(tool, test_case, check_fn, get_snr, tmpdir, runner_config):
@patch('runners.core.ZephyrBinaryRunner.require')
@patch('runners.nrfjprog.NrfBinaryRunner.get_board_snr',
side_effect=get_board_snr_patch)
@patch('runners.nrfjprog.NrfBinaryRunner.check_output')
@patch('runners.nrfutil.subprocess.Popen')
@patch('runners.nrfjprog.NrfBinaryRunner.check_call')
def test_init(check_call, check_output, get_snr, require, tool, test_case,
def test_init(check_call, popen, get_snr, require, tool, test_case,
runner_config, tmpdir):
popen.return_value.__enter__.return_value.stdout = io.BytesIO(b'')
require.side_effect = functools.partial(require_patch, tool)
runner_config = fix_up_runner_config(test_case, runner_config, tmpdir)
@ -564,7 +568,7 @@ def test_init(check_call, check_output, get_snr, require, tool, test_case,
runner.run('flash')
assert require.called
CHECK_FN_MAP = {'nrfjprog': check_call, 'nrfutil': check_output}
CHECK_FN_MAP = {'nrfjprog': check_call, 'nrfutil': popen}
check_expected(tool, test_case, CHECK_FN_MAP[tool], get_snr, tmpdir,
runner_config)
@ -573,10 +577,11 @@ def test_init(check_call, check_output, get_snr, require, tool, test_case,
@patch('runners.core.ZephyrBinaryRunner.require')
@patch('runners.nrfjprog.NrfBinaryRunner.get_board_snr',
side_effect=get_board_snr_patch)
@patch('runners.nrfjprog.NrfBinaryRunner.check_output')
@patch('runners.nrfutil.subprocess.Popen')
@patch('runners.nrfjprog.NrfBinaryRunner.check_call')
def test_create(check_call, check_output, get_snr, require, tool, test_case,
def test_create(check_call, popen, get_snr, require, tool, test_case,
runner_config, tmpdir):
popen.return_value.__enter__.return_value.stdout = io.BytesIO(b'')
require.side_effect = functools.partial(require_patch, tool)
runner_config = fix_up_runner_config(test_case, runner_config, tmpdir)
@ -603,6 +608,6 @@ def test_create(check_call, check_output, get_snr, require, tool, test_case,
assert require.called
CHECK_FN_MAP = {'nrfjprog': check_call, 'nrfutil': check_output}
CHECK_FN_MAP = {'nrfjprog': check_call, 'nrfutil': popen}
check_expected(tool, test_case, CHECK_FN_MAP[tool], get_snr, tmpdir,
runner_config)