Skip to content

Commit

Permalink
scripts: nrf_common: Handle SUIT artifacts
Browse files Browse the repository at this point in the history
Handle MPI and root manifest for radio core separately from the main
build system logic.

Signed-off-by: Tomasz Chyrowicz <[email protected]>
  • Loading branch information
tomchy authored and jhedberg committed Jun 10, 2024
1 parent d500a3f commit f15a2e8
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 2 deletions.
3 changes: 3 additions & 0 deletions scripts/ci/check_compliance.py
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,9 @@ def check_no_undef_outside_kconfig(self, kconf):
"ZEPHYR_TRY_MASS_ERASE", # MCUBoot setting described in sysbuild
# documentation
"ZTEST_FAIL_TEST_", # regex in tests/ztest/fail/CMakeLists.txt
"SUIT_MPI_GENERATE", # Used by nRF runners to program provisioning data, based on build configuration
"SUIT_MPI_APP_AREA_PATH", # Used by nRF runners to program provisioning data, based on build configuration
"SUIT_MPI_RAD_AREA_PATH", # Used by nRF runners to program provisioning data, based on build configuration
}


Expand Down
30 changes: 28 additions & 2 deletions scripts/west_commands/runners/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ class BuildConfiguration:
Kconfig configuration values are available (parsed from .config).'''

config_prefix = 'CONFIG'

def __init__(self, build_dir: str):
self.build_dir = build_dir
self.options: Dict[str, Union[str, int]] = {}
Expand All @@ -153,8 +155,9 @@ def getboolean(self, option):

def _parse(self):
filename = self.path
opt_value = re.compile('^(?P<option>CONFIG_[A-Za-z0-9_]+)=(?P<value>.*)$')
not_set = re.compile('^# (?P<option>CONFIG_[A-Za-z0-9_]+) is not set$')

opt_value = re.compile(f'^(?P<option>{self.config_prefix}_[A-Za-z0-9_]+)=(?P<value>.*)$')
not_set = re.compile(f'^# (?P<option>{self.config_prefix}_[A-Za-z0-9_]+) is not set$')

with open(filename, 'r') as f:
for line in f:
Expand Down Expand Up @@ -187,6 +190,22 @@ def _parse(self):
# '# CONFIG_FOO is not set' means a boolean option is false.
self.options[match.group('option')] = False

class SysbuildConfiguration(BuildConfiguration):
'''This helper class provides access to sysbuild-time configuration.
Configuration options can be read as if the object were a dict,
either object['SB_CONFIG_FOO'] or object.get('SB_CONFIG_FOO').
Kconfig configuration values are available (parsed from .config).'''

config_prefix = 'SB_CONFIG'

def _parse(self):
# If the build does not use sysbuild, skip parsing the file.
if not os.path.exists(self.path):
return
super()._parse()

class MissingProgram(FileNotFoundError):
'''FileNotFoundError subclass for missing program dependencies.
Expand Down Expand Up @@ -653,6 +672,13 @@ def build_conf(self) -> BuildConfiguration:
self._build_conf = BuildConfiguration(self.cfg.build_dir)
return self._build_conf

@property
def sysbuild_conf(self) -> SysbuildConfiguration:
'''Get a SysbuildConfiguration for the sysbuild directory.'''
if not hasattr(self, '_sysbuild_conf'):
self._sysbuild_conf = SysbuildConfiguration(os.path.dirname(self.cfg.build_dir))
return self._sysbuild_conf

@property
def thread_info_enabled(self) -> bool:
'''Returns True if self.build_conf has
Expand Down
23 changes: 23 additions & 0 deletions scripts/west_commands/runners/nrf_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,29 @@ def program_hex(self):
self.exec_op('erase', core='NRFDL_DEVICE_CORE_APPLICATION')
self.exec_op('erase', core='NRFDL_DEVICE_CORE_NETWORK')

# Manage SUIT artifacts.
# This logic should be executed only once per build.
# Use sysbuild board qualifiers to select the context, with which the artifacts will be programmed.
if self.build_conf.get('CONFIG_BOARD_QUALIFIERS') == self.sysbuild_conf.get('SB_CONFIG_BOARD_QUALIFIERS'):
hex_path = Path(self.hex_)

# Handle Manifest Provisioning Information
if self.build_conf.getboolean('CONFIG_SUIT_MPI_GENERATE'):
app_mpi_hex_file = os.fspath(
hex_path.parent / self.build_conf.get('CONFIG_SUIT_MPI_APP_AREA_PATH'))
rad_mpi_hex_file = os.fspath(
hex_path.parent / self.build_conf.get('CONFIG_SUIT_MPI_RAD_AREA_PATH'))
self.op_program(app_mpi_hex_file, 'ERASE_NONE', None, defer=True, core='NRFDL_DEVICE_CORE_APPLICATION')
self.op_program(rad_mpi_hex_file, 'ERASE_NONE', None, defer=True, core='NRFDL_DEVICE_CORE_NETWORK')

# 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 self.build_conf.getboolean('CONFIG_SOC_NRF54H20_CPUAPP') and self.sysbuild_conf.get('SB_CONFIG_SUIT_ENVELOPE'):
app_root_envelope_hex_file = os.fspath(
hex_path.parent / 'suit_installed_envelopes_application_merged.hex')
self.op_program(app_root_envelope_hex_file, 'ERASE_NONE', None, defer=True, core='NRFDL_DEVICE_CORE_APPLICATION')

if self.build_conf.getboolean('CONFIG_SOC_NRF54H20_CPUAPP'):
if not self.erase and self.build_conf.getboolean('CONFIG_NRF_REGTOOL_GENERATE_UICR'):
self.exec_op('erase', core='NRFDL_DEVICE_CORE_APPLICATION',
Expand Down

0 comments on commit f15a2e8

Please sign in to comment.