scripts: runners: nrf: Remove the nRF5340 special handling

This is no longer necessary, because thanks to sysbuild we no longer
invoke a runner with a .hex file that is the result of merging builds
for more than one core.

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
This commit is contained in:
Carles Cufi 2025-01-28 13:58:15 +01:00 committed by Benjamin Cabé
commit aaefaad898
6 changed files with 41 additions and 260 deletions

View file

@ -295,31 +295,37 @@ class NrfBinaryRunner(ZephyrBinaryRunner):
self.exec_op('recover')
def _get_core(self):
if self.family in ('nrf54h', 'nrf92'):
if (self.build_conf.getboolean('CONFIG_SOC_NRF54H20_CPUAPP') or
self.build_conf.getboolean('CONFIG_SOC_NRF9280_CPUAPP')):
return 'Application'
if (self.build_conf.getboolean('CONFIG_SOC_NRF54H20_CPURAD') or
self.build_conf.getboolean('CONFIG_SOC_NRF9280_CPURAD')):
return 'Network'
raise RuntimeError(f'Core not found for family: {self.family}')
if self.family in ('nrf53'):
if self.build_conf.getboolean('CONFIG_SOC_NRF5340_CPUAPP'):
return 'Application'
if self.build_conf.getboolean('CONFIG_SOC_NRF5340_CPUNET'):
return 'Network'
raise RuntimeError(f'Core not found for family: {self.family}')
return None
def program_hex(self):
# Get the command use to actually program self.hex_.
self.logger.info(f'Flashing file: {self.hex_}')
# What type of erase/core arguments should we pass to the tool?
core = None
core = self._get_core()
if self.family in ('nrf54h', 'nrf92'):
erase_arg = 'ERASE_NONE'
cpuapp = (
self.build_conf.getboolean('CONFIG_SOC_NRF54H20_CPUAPP') or
self.build_conf.getboolean('CONFIG_SOC_NRF9280_CPUAPP')
)
cpurad = (
self.build_conf.getboolean('CONFIG_SOC_NRF54H20_CPURAD') or
self.build_conf.getboolean('CONFIG_SOC_NRF9280_CPURAD')
)
generated_uicr = self.build_conf.getboolean('CONFIG_NRF_REGTOOL_GENERATE_UICR')
if cpuapp:
core = 'Application'
elif cpurad:
core = 'Network'
if generated_uicr and not self.hex_get_uicrs().get(core):
raise RuntimeError(
f"Expected a UICR to be contained in: {self.hex_}\n"
@ -367,7 +373,7 @@ class NrfBinaryRunner(ZephyrBinaryRunner):
# Handle SUIT root manifest if application manifests are not used.
# If an application firmware is built, the root envelope is merged
# with other application manifests as well as the output HEX file.
if not cpuapp and self.sysbuild_conf.get('SB_CONFIG_SUIT_ENVELOPE'):
if core != 'Application' and self.sysbuild_conf.get('SB_CONFIG_SUIT_ENVELOPE'):
app_root_envelope_hex_file = os.fspath(
mpi_hex_dir / 'suit_installed_envelopes_application_merged.hex'
)
@ -399,83 +405,9 @@ class NrfBinaryRunner(ZephyrBinaryRunner):
if self.hex_refers_region(xip_start, xip_end):
ext_mem_erase_opt = 'ERASE_ALL'
# What tool commands do we need to flash this target?
if self.family == 'nrf53':
# nRF53 requires special treatment due to the extra coprocessor.
self.program_hex_nrf53(erase_arg, ext_mem_erase_opt)
else:
self.op_program(self.hex_, erase_arg, ext_mem_erase_opt, defer=True, core=core)
self.op_program(self.hex_, erase_arg, ext_mem_erase_opt, defer=True, core=core)
self.flush(force=False)
def program_hex_nrf53(self, erase_arg, ext_mem_erase_opt):
# program_hex() helper for nRF53.
# *********************** NOTE *******************************
# self.hex_ can contain code for both the application core and
# the network core.
#
# We can't assume, for example, that
# CONFIG_SOC_NRF5340_CPUAPP=y means self.hex_ only contains
# data for the app core's flash: the user can put arbitrary
# addresses into one of the files in HEX_FILES_TO_MERGE.
#
# Therefore, on this family, we may need to generate two new
# hex files, one for each core, and flash them individually
# with the correct '--coprocessor' arguments.
#
# Kind of hacky, but it works, and the tools are not capable of
# flashing to both cores at once. If self.hex_ only affects
# one core's flash, then we skip the extra work to save time.
# ************************************************************
# Address range of the network coprocessor's flash. From nRF5340 OPS.
# We should get this from DTS instead if multiple values are possible,
# but this is fine for now.
net_flash_start = 0x01000000
net_flash_end = 0x0103FFFF
# If there is nothing in the hex file for the network core,
# only the application core is programmed.
if not self.hex_refers_region(net_flash_start, net_flash_end):
self.op_program(self.hex_, erase_arg, ext_mem_erase_opt, defer=True,
core='Application')
# If there is some content that addresses a region beyond the network
# core flash range, two hex files are generated and the two cores
# are programmed one by one.
elif self.hex_contents.minaddr() < net_flash_start or \
self.hex_contents.maxaddr() > net_flash_end:
net_hex, app_hex = IntelHex(), IntelHex()
for start, end in self.hex_contents.segments():
if net_flash_start <= start <= net_flash_end:
net_hex.merge(self.hex_contents[start:end])
else:
app_hex.merge(self.hex_contents[start:end])
hex_path = Path(self.hex_)
hex_dir, hex_name = hex_path.parent, hex_path.name
net_hex_file = os.fspath(
hex_dir / f'GENERATED_CP_NETWORK_{hex_name}')
app_hex_file = os.fspath(
hex_dir / f'GENERATED_CP_APPLICATION_{hex_name}')
self.logger.info(
f'{self.hex_} targets both nRF53 coprocessors; '
f'splitting it into: {net_hex_file} and {app_hex_file}')
net_hex.write_hex_file(net_hex_file)
app_hex.write_hex_file(app_hex_file)
self.op_program(net_hex_file, erase_arg, None, defer=True,
core='Network')
self.op_program(app_hex_file, erase_arg, ext_mem_erase_opt, defer=True,
core='Application')
# Otherwise, only the network core is programmed.
else:
self.op_program(self.hex_, erase_arg, None, defer=True,
core='Network')
def reset_target(self):
if self.family == 'nrf52' and not self.softreset:

View file

@ -1 +0,0 @@
This directory contains test data files for test_nrf.py.

View file

@ -1,5 +0,0 @@
:020000040000FA
:0100000001FE
:020000040100F9
:0100000001FE
:00000001FF

View file

@ -1,2 +0,0 @@
:0100000001FE
:00000001FF

View file

@ -1,3 +0,0 @@
:020000040100F9
:0100000001FE
:00000001FF

View file

@ -7,9 +7,7 @@ import argparse
import functools
import io
import os
from pathlib import Path
import shlex
import shutil
import typing
from unittest.mock import patch, call
@ -30,14 +28,6 @@ TEST_OVR_SNR = 'test-override-serial-number'
TEST_TOOL_OPT = '--ip 192.168.1.10'
TEST_TOOL_OPT_L = shlex.split(TEST_TOOL_OPT)
# nRF53 flashing is special in that we have different results
# depending on the input hex file. For that reason, we test it with
# real hex files.
TEST_DIR = Path(__file__).parent / 'nrf'
NRF5340_APP_ONLY_HEX = os.fspath(TEST_DIR / 'nrf5340_app_only.hex')
NRF5340_NET_ONLY_HEX = os.fspath(TEST_DIR / 'nrf5340_net_only.hex')
NRF5340_APP_AND_NET_HEX = os.fspath(TEST_DIR / 'nrf5340_app_and_net.hex')
CLASS_MAP = {'nrfjprog': NrfJprogBinaryRunner, 'nrfutil': NrfUtilBinaryRunner}
#
@ -182,29 +172,29 @@ EXPECTED_RESULTS = {
(TEST_OVR_SNR, None)),
# -------------------------------------------------------------------------
# NRF53 APP only
# NRF53 APP
#
# family CP recov soft snr erase tool_opt
TC('nrf53', 'APP', False, False, False, False, False):
((['nrfjprog', '--program', NRF5340_APP_ONLY_HEX, '--sectorerase',
((['nrfjprog', '--program', RC_KERNEL_HEX, '--sectorerase',
'--verify', '-f', 'NRF53', '--coprocessor', 'CP_APPLICATION', '--snr', TEST_DEF_SNR],
['nrfjprog', '--pinreset', '-f', 'NRF53', '--snr', TEST_DEF_SNR]),
(TEST_DEF_SNR, None)),
TC('nrf53', 'APP', False, False, False, True, False):
((['nrfjprog', '--program', NRF5340_APP_ONLY_HEX, '--chiperase',
((['nrfjprog', '--program', RC_KERNEL_HEX, '--chiperase',
'--verify', '-f', 'NRF53', '--coprocessor', 'CP_APPLICATION', '--snr', TEST_DEF_SNR],
['nrfjprog', '--pinreset', '-f', 'NRF53', '--snr', TEST_DEF_SNR]),
(TEST_DEF_SNR, None)),
TC('nrf53', 'APP', False, False, True, False, False):
((['nrfjprog', '--program', NRF5340_APP_ONLY_HEX, '--sectorerase',
((['nrfjprog', '--program', RC_KERNEL_HEX, '--sectorerase',
'--verify', '-f', 'NRF53', '--coprocessor', 'CP_APPLICATION', '--snr', TEST_OVR_SNR],
['nrfjprog', '--pinreset', '-f', 'NRF53', '--snr', TEST_OVR_SNR]),
(TEST_OVR_SNR, None)),
TC('nrf53', 'APP', False, True, False, False, False):
((['nrfjprog', '--program', NRF5340_APP_ONLY_HEX, '--sectorerase',
((['nrfjprog', '--program', RC_KERNEL_HEX, '--sectorerase',
'--verify', '-f', 'NRF53', '--coprocessor', 'CP_APPLICATION', '--snr', TEST_DEF_SNR],
['nrfjprog', '--reset', '-f', 'NRF53', '--snr', TEST_DEF_SNR]),
(TEST_DEF_SNR, None)),
@ -213,7 +203,7 @@ EXPECTED_RESULTS = {
((['nrfjprog', '--recover', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK',
'--snr', TEST_DEF_SNR],
['nrfjprog', '--recover', '-f', 'NRF53', '--snr', TEST_DEF_SNR],
['nrfjprog', '--program', NRF5340_APP_ONLY_HEX, '--sectorerase',
['nrfjprog', '--program', RC_KERNEL_HEX, '--sectorerase',
'--verify', '-f', 'NRF53', '--coprocessor', 'CP_APPLICATION', '--snr', TEST_DEF_SNR],
['nrfjprog', '--pinreset', '-f', 'NRF53', '--snr', TEST_DEF_SNR]),
(TEST_DEF_SNR, None)),
@ -222,35 +212,35 @@ EXPECTED_RESULTS = {
((['nrfjprog', '--recover', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK',
'--snr', TEST_OVR_SNR],
['nrfjprog', '--recover', '-f', 'NRF53', '--snr', TEST_OVR_SNR],
['nrfjprog', '--program', NRF5340_APP_ONLY_HEX, '--chiperase',
['nrfjprog', '--program', RC_KERNEL_HEX, '--chiperase',
'--verify', '-f', 'NRF53', '--coprocessor', 'CP_APPLICATION', '--snr', TEST_OVR_SNR],
['nrfjprog', '--reset', '-f', 'NRF53', '--snr', TEST_OVR_SNR]),
(TEST_OVR_SNR, None)),
# -------------------------------------------------------------------------
# NRF53 NET only
# NRF53 NET
#
# family CP recov soft snr erase tool_opt
TC('nrf53', 'NET', False, False, False, False, False):
((['nrfjprog', '--program', NRF5340_NET_ONLY_HEX, '--sectorerase',
((['nrfjprog', '--program', RC_KERNEL_HEX, '--sectorerase',
'--verify', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK', '--snr', TEST_DEF_SNR],
['nrfjprog', '--pinreset', '-f', 'NRF53', '--snr', TEST_DEF_SNR]),
(TEST_DEF_SNR, None)),
TC('nrf53', 'NET', False, False, False, True, False):
((['nrfjprog', '--program', NRF5340_NET_ONLY_HEX, '--chiperase',
((['nrfjprog', '--program', RC_KERNEL_HEX, '--chiperase',
'--verify', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK', '--snr', TEST_DEF_SNR],
['nrfjprog', '--pinreset', '-f', 'NRF53', '--snr', TEST_DEF_SNR]),
(TEST_DEF_SNR, None)),
TC('nrf53', 'NET', False, False, True, False, False):
((['nrfjprog', '--program', NRF5340_NET_ONLY_HEX, '--sectorerase',
((['nrfjprog', '--program', RC_KERNEL_HEX, '--sectorerase',
'--verify', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK', '--snr', TEST_OVR_SNR],
['nrfjprog', '--pinreset', '-f', 'NRF53', '--snr', TEST_OVR_SNR]),
(TEST_OVR_SNR, None)),
TC('nrf53', 'NET', False, True, False, False, False):
((['nrfjprog', '--program', NRF5340_NET_ONLY_HEX, '--sectorerase',
((['nrfjprog', '--program', RC_KERNEL_HEX, '--sectorerase',
'--verify', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK', '--snr', TEST_DEF_SNR],
['nrfjprog', '--reset', '-f', 'NRF53', '--snr', TEST_DEF_SNR]),
(TEST_DEF_SNR, None)),
@ -259,7 +249,7 @@ EXPECTED_RESULTS = {
((['nrfjprog', '--recover', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK',
'--snr', TEST_DEF_SNR],
['nrfjprog', '--recover', '-f', 'NRF53', '--snr', TEST_DEF_SNR],
['nrfjprog', '--program', NRF5340_NET_ONLY_HEX, '--sectorerase',
['nrfjprog', '--program', RC_KERNEL_HEX, '--sectorerase',
'--verify', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK', '--snr', TEST_DEF_SNR],
['nrfjprog', '--pinreset', '-f', 'NRF53', '--snr', TEST_DEF_SNR]),
(TEST_DEF_SNR, None)),
@ -268,130 +258,11 @@ EXPECTED_RESULTS = {
((['nrfjprog', '--recover', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK',
'--snr', TEST_OVR_SNR],
['nrfjprog', '--recover', '-f', 'NRF53', '--snr', TEST_OVR_SNR],
['nrfjprog', '--program', NRF5340_NET_ONLY_HEX, '--chiperase',
['nrfjprog', '--program', RC_KERNEL_HEX, '--chiperase',
'--verify', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK', '--snr', TEST_OVR_SNR],
['nrfjprog', '--reset', '-f', 'NRF53', '--snr', TEST_OVR_SNR]),
(TEST_OVR_SNR, None)),
# -------------------------------------------------------------------------
# NRF53 APP+NET
#
# family CP recov soft snr erase tool_opt
TC('nrf53', 'APP+NET', False, False, False, False, False):
((lambda tmpdir, infile: \
(['nrfjprog',
'--program',
os.fspath(tmpdir / 'GENERATED_CP_NETWORK_' + Path(infile).name),
'--sectorerase', '--verify', '-f', 'NRF53',
'--coprocessor', 'CP_NETWORK', '--snr', TEST_DEF_SNR],
['nrfjprog',
'--program',
os.fspath(tmpdir / 'GENERATED_CP_APPLICATION_' + Path(infile).name),
'--sectorerase', '--verify', '-f', 'NRF53',
'--coprocessor', 'CP_APPLICATION', '--snr', TEST_DEF_SNR],
['nrfjprog', '--pinreset', '-f', 'NRF53', '--snr', TEST_DEF_SNR])),
(TEST_DEF_SNR, None)),
TC('nrf53', 'APP+NET', False, False, False, True, False):
((lambda tmpdir, infile: \
(['nrfjprog',
'--program',
os.fspath(tmpdir / 'GENERATED_CP_NETWORK_' + Path(infile).name),
'--chiperase', '--verify', '-f', 'NRF53',
'--coprocessor', 'CP_NETWORK', '--snr', TEST_DEF_SNR],
['nrfjprog',
'--program',
os.fspath(tmpdir / 'GENERATED_CP_APPLICATION_' + Path(infile).name),
'--chiperase', '--verify', '-f', 'NRF53',
'--coprocessor', 'CP_APPLICATION', '--snr', TEST_DEF_SNR],
['nrfjprog', '--pinreset', '-f', 'NRF53', '--snr', TEST_DEF_SNR])),
(TEST_DEF_SNR, None)),
TC('nrf53', 'APP+NET', False, False, True, False, False):
((lambda tmpdir, infile: \
(['nrfjprog',
'--program',
os.fspath(tmpdir / 'GENERATED_CP_NETWORK_' + Path(infile).name),
'--sectorerase', '--verify', '-f', 'NRF53',
'--coprocessor', 'CP_NETWORK', '--snr', TEST_OVR_SNR],
['nrfjprog',
'--program',
os.fspath(tmpdir / 'GENERATED_CP_APPLICATION_' + Path(infile).name),
'--sectorerase', '--verify', '-f', 'NRF53',
'--coprocessor', 'CP_APPLICATION', '--snr', TEST_OVR_SNR],
['nrfjprog', '--pinreset', '-f', 'NRF53', '--snr', TEST_OVR_SNR])),
(TEST_OVR_SNR, None)),
TC('nrf53', 'APP+NET', False, True, False, False, False):
((lambda tmpdir, infile: \
(['nrfjprog',
'--program',
os.fspath(tmpdir / 'GENERATED_CP_NETWORK_' + Path(infile).name),
'--sectorerase', '--verify', '-f', 'NRF53',
'--coprocessor', 'CP_NETWORK', '--snr', TEST_DEF_SNR],
['nrfjprog',
'--program',
os.fspath(tmpdir / 'GENERATED_CP_APPLICATION_' + Path(infile).name),
'--sectorerase', '--verify', '-f', 'NRF53',
'--coprocessor', 'CP_APPLICATION', '--snr', TEST_DEF_SNR],
['nrfjprog', '--reset', '-f', 'NRF53', '--snr', TEST_DEF_SNR])),
(TEST_DEF_SNR, None)),
TC('nrf53', 'APP+NET', True, False, False, False, False):
((lambda tmpdir, infile: \
(['nrfjprog', '--recover', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK',
'--snr', TEST_DEF_SNR],
['nrfjprog', '--recover', '-f', 'NRF53', '--snr', TEST_DEF_SNR],
['nrfjprog',
'--program',
os.fspath(tmpdir / 'GENERATED_CP_NETWORK_' + Path(infile).name),
'--sectorerase', '--verify', '-f', 'NRF53',
'--coprocessor', 'CP_NETWORK', '--snr', TEST_DEF_SNR],
['nrfjprog',
'--program',
os.fspath(tmpdir / 'GENERATED_CP_APPLICATION_' + Path(infile).name),
'--sectorerase', '--verify', '-f', 'NRF53',
'--coprocessor', 'CP_APPLICATION', '--snr', TEST_DEF_SNR],
['nrfjprog', '--pinreset', '-f', 'NRF53', '--snr', TEST_DEF_SNR])),
(TEST_DEF_SNR, None)),
TC('nrf53', 'APP+NET', True, True, True, True, False):
((lambda tmpdir, infile: \
(['nrfjprog', '--recover', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK',
'--snr', TEST_OVR_SNR],
['nrfjprog', '--recover', '-f', 'NRF53', '--snr', TEST_OVR_SNR],
['nrfjprog',
'--program',
os.fspath(tmpdir / 'GENERATED_CP_NETWORK_' + Path(infile).name),
'--chiperase', '--verify', '-f', 'NRF53',
'--coprocessor', 'CP_NETWORK', '--snr', TEST_OVR_SNR],
['nrfjprog',
'--program',
os.fspath(tmpdir / 'GENERATED_CP_APPLICATION_' + Path(infile).name),
'--chiperase', '--verify', '-f', 'NRF53',
'--coprocessor', 'CP_APPLICATION', '--snr', TEST_OVR_SNR],
['nrfjprog', '--reset', '-f', 'NRF53', '--snr', TEST_OVR_SNR])),
(TEST_OVR_SNR, None)),
TC('nrf53', 'APP+NET', True, True, True, True, True):
((lambda tmpdir, infile: \
(['nrfjprog', '--recover', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK',
'--snr', TEST_OVR_SNR] + TEST_TOOL_OPT_L,
['nrfjprog', '--recover', '-f', 'NRF53', '--snr', TEST_OVR_SNR] + TEST_TOOL_OPT_L,
['nrfjprog',
'--program',
os.fspath(tmpdir / 'GENERATED_CP_NETWORK_' + Path(infile).name),
'--chiperase', '--verify', '-f', 'NRF53',
'--coprocessor', 'CP_NETWORK', '--snr', TEST_OVR_SNR] + TEST_TOOL_OPT_L,
['nrfjprog',
'--program',
os.fspath(tmpdir / 'GENERATED_CP_APPLICATION_' + Path(infile).name),
'--chiperase', '--verify', '-f', 'NRF53',
'--coprocessor', 'CP_APPLICATION', '--snr', TEST_OVR_SNR] + TEST_TOOL_OPT_L,
['nrfjprog', '--reset', '-f', 'NRF53', '--snr', TEST_OVR_SNR] + TEST_TOOL_OPT_L)),
(TEST_OVR_SNR, None)),
# -------------------------------------------------------------------------
# NRF91
#
@ -493,24 +364,13 @@ def fix_up_runner_config(test_case, runner_config, tmpdir):
f.write(f'''
CONFIG_SOC_SERIES_{test_case.family.upper()}X=y
''')
if test_case.family == 'nrf53':
f.write(f'''
CONFIG_SOC_NRF5340_CPU{test_case.coprocessor}=y
''')
to_replace['build_dir'] = tmpdir
if test_case.family != 'nrf53':
return runner_config._replace(**to_replace)
if test_case.coprocessor == 'APP':
to_replace['hex_file'] = NRF5340_APP_ONLY_HEX
elif test_case.coprocessor == 'NET':
to_replace['hex_file'] = NRF5340_NET_ONLY_HEX
elif test_case.coprocessor == 'APP+NET':
# Since the runner is going to generate files next to its input
# file, we need to stash a copy in a tmpdir it can use.
outfile = tmpdir / Path(NRF5340_APP_AND_NET_HEX).name
shutil.copyfile(NRF5340_APP_AND_NET_HEX, outfile)
to_replace['hex_file'] = os.fspath(outfile)
else:
assert False, f'bad test case {test_case}'
return runner_config._replace(**to_replace)
def check_expected(tool, test_case, check_fn, get_snr, tmpdir, runner_config):