Commit graph

399 commits

Author SHA1 Message Date
Guennadi Liakhovetski
a3089c1ffc llext: xtensa: strip the .xtensa.info section
.xtensa.info section isn't large so it was ignored in the beginning,
but its contents can differ depending on the build platform even if
the sources and the toolchain are the same. Strip the section to
restore binary reproducibility.

Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
2025-06-19 13:59:15 +02:00
Benjamin Cabé
043bb58488 doc: ci: Zephyr now requires Python 3.12 or higher
Update getting started guide, release notes, CI actions and
Python version compliance check to use Python 3.12 as
minimum supported version.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2025-06-19 13:56:59 +02:00
Richard Hughes
3c97bf1014 cmake: kconfig: regenerate .config when Kconfig sources are updated
The existing logic caused a regeneration when any of the .conf files
changed, but modifying the Kconfig files can also cause the .config file
to become out of date e.g. by adding a new config option or by changing
the default value of a config option (when that default is not
overridden by a .conf).

Without this change, an incremental build wouldn't pick up the new value
and would require the user to notice that and manually do a clean build.

Signed-off-by: Richard Hughes <rhughes@xilinx.com>
2025-06-18 09:08:52 -04:00
Richard Hughes
3aaa68faad cmake: kconfig: rename variable to correct naming convention
Variables used only internally in the module should have lowercase
names.

Signed-off-by: Richard Hughes <rhughes@xilinx.com>
2025-06-18 09:08:52 -04:00
Keith Packard
ff8b24b6bd cmake/modules: Make SUBALIGN parameter to zephyr_iterable_sections optional
Most uses of this macro should *not* include SUBALIGN as that can reduce
the alignment requirement for data and cause unaligned access faults in
the processor. Leave support for this in place in case there are
still uses for it.

Signed-off-by: Keith Packard <keithp@keithp.com>
2025-06-17 16:06:21 +02:00
Kesavan Yogeswaran
d5fc087690 cmake: Fix warning if a Zephyr library is created in app-mode
zephyr_append_cmake_library attempts to warn the user if a user calls it
to create a Zephyr library while the build is in application mode. At
that stage of the build, the list of Zephyr libraries has already been
processed so the function is effectively a no-op.

This heuristic used to determine if the build was in kernel mode or
application mode checked for the presence of the zephyr_prebuilt target.
This check was broken by a previous commit that renamed this target.

This commit fixes the heuristic by checking for the zephyr_pre0 target.

This was tested by calling zephyr_append_cmake_library from some
application build files, building the application, and seeing the
warning only for the call I added. No warnings were printed for any
Zephyr internal libraries.

Link: https://github.com/zephyrproject-rtos/zephyr/pull/35887
Link: https://github.com/zephyrproject-rtos/zephyr/pull/39959

Signed-off-by: Kesavan Yogeswaran <hikes@google.com>
2025-06-09 15:02:01 -07:00
Luca Burelli
8e765b78a2 cmake: add_llext_target: fix command expansion
This fixes the invocation of the 'elfconvert' and 'slid_inject' commands
in the `add_llext_target` function by ensuring that the arguments are
expanded correctly before passing them to the shell.

Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
2025-06-06 11:52:31 +02:00
Björn Bergman
01d3316810 linker generator: Handle .last_section
Add  cmake linker generator things for .last_section.

Follow up to #88970. Fixes bug #89719, for gcc/ld & iar

Signed-off-by: Björn Bergman <bjorn.bergman@iar.com>
2025-05-26 14:17:21 +02:00
Benjamin Cabé
66fda826e1 shields: scripts: cmake: use list_shields.py in shields.cmake
The logic to "guess" shield names/dirs was duplicated between
list_shields.py (which is used by e.g. west shields) and shields.cmake.
This commit moves the logic to list_shields.py, and updates
shields.cmake to call the script and process its JSON output.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2025-05-23 17:19:58 +02:00
Grzegorz Swiderski
da197fe9ef sysbuild: Import image devicetrees
Make the image devicetrees available to sysbuild for advanced use cases.

This is done by calling `zephyr_dt_import` on each image target. The DT
target properties are all expected to be prefixed with `DT_`, so there
should be no conflicts.

Thus, the DT contents of a given `<image>` can be retrieved using e.g.:

    dt_nodelabel(<var> NODELABEL <label> TARGET <image>)

as noted in `extensions.cmake`.

Signed-off-by: Grzegorz Swiderski <grzegorz.swiderski@nordicsemi.no>
2025-05-22 13:44:18 +02:00
Grzegorz Swiderski
7cddb2a5e5 cmake: extensions: Add TARGET arguments to the dt_* API
The CMake dt_* API is backed by target properties. By default, it uses
the target named `devicetree_target` that is initialized in `dts.cmake`.

We should be able to customize this, now that we have a function for
loading those properties into a different target. For example:

    zephyr_dt_import(EDT_PICKLE_FILE /path/to/edt.pickle TARGET target)

    dt_nodelabel(node NODELABEL label TARGET target)

This would make it possible to reference multiple devicetrees in the
same build system, particularly sysbuild.

Signed-off-by: Grzegorz Swiderski <grzegorz.swiderski@nordicsemi.no>
2025-05-22 13:44:18 +02:00
Grzegorz Swiderski
468db18389 cmake: modules: Add zephyr_dt_import
Extract the part of `dts.cmake` that invokes `gen_dts_cmake.py`, then
generalize it into a CMake extension, which can be reused by sysbuild.

The Python script itself is also updated, so that the generated CMake
file can accept an input variable DEVICETREE_TARGET, which comes from
the `zephyr_dt_import(TARGET ...)` argument.

Signed-off-by: Grzegorz Swiderski <grzegorz.swiderski@nordicsemi.no>
2025-05-22 13:44:18 +02:00
Benjamin Cabé
0c82c3516f Revert "cmake: shields: introduce shield.yml"
This reverts commit 9d5b19710b.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2025-05-21 09:30:30 +02:00
Benjamin Cabé
9d5b19710b cmake: shields: introduce shield.yml
While legacy shields are still supported, this introduces a shield.yml
file similar to board.yml that allows to more explicitly declare a
shield and to set some useful metadata such as vendor and full name.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2025-05-20 15:23:34 +02:00
Paul Schaetzle
269799e0e9 cmake: modules: shields: pre_dt_shield.cmake file
Similar to the pre_dt_board.cmake, this is an optional file for
additional arguments that need to get passed to the devicetree compiler.

Signed-off-by: Paul Schaetzle <paulschaetzle@mailbox.org>
2025-05-20 12:47:00 +02:00
Chris Friedt
c32488f97b cmake: kconfig: auto-generate boolean board revision option
Automatically generate a boolean CONFIG_BOARD_REVISION_FOO=y Kconfig
option based on e.g. CONFIG_BOARD_REVISION="foo".

Signed-off-by: Chris Friedt <cfriedt@tenstorrent.com>
2025-05-16 16:11:48 +02:00
Luca Burelli
c1603b3163 gen_edt: use workspace dir as base for relative paths in comments
This commit allows comments to reference files with paths that are relative
to the Zephyr workspace root. This is done by adding a new argument
'--workspace-dir' to the 'gen_edt.py' script, which is passed to the
'EDT' and 'DT' classes and used instead of the current working directory.

The workspace directory is set to WEST_TOPDIR if West is in use,
otherwise it is set to the parent directory of ZEPHYR_BASE so that
Zephyr files have a 'zephyr/' prefix.

Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
2025-05-16 09:38:35 +02:00
Luca Burelli
dbf00bfca8 yaml: save intermediate files in the build directory
Make sure to provide full paths when saving the intermediate files in
the YAML export, to prevent them from being saved in the source tree.

Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
2025-05-08 19:46:18 +02:00
Armin Brauns
d6efbc8af4 cmake: clean up gen_kobject_list.py invocations
cmake/kobj.cmake now provides nice wrappers around the script itself and
common uses.

Signed-off-by: Armin Brauns <armin.brauns@embedded-solutions.at>
2025-05-07 15:10:05 +02:00
Duy Nguyen
5fabd3634a CMake: Add support for .mot binary file format
The Renesas RX support flashing .mot file for binary image
This commit target to add the .mot file output for build and
flash script

Signed-off-by: Duy Nguyen <duy.nguyen.xa@renesas.com>
2025-05-02 09:18:16 +02:00
Declan Snyder
7962eaeca6 dts: Move vendor-specific dtsi to dedicated folder
Move all the vendor-specific dtsi files that were in dts/common to a
new folder under dts/ designated for vendor-specific files,
since they are not common at all, except for one vendor.

Change MAINTAINERS.yml to reflect the moving of the files.

Update migration guide for this change.

Signed-off-by: Declan Snyder <declan.snyder@nxp.com>
2025-04-29 13:00:03 +02:00
Luca Burelli
0f71880001 cmake: yaml: update timestamp on intermediate file save
file(GENERATE ...) does not update the output file if the content is
unchanged. Since the metadata in build_info.yml mostly depends on the
build configuration, the timestamp of the intermediate file does not get
updated on most rebuilds, while the final file does, due to immediate
file(WRITE ...) calls. Since the latter is newer, no post-process step
is executed and the file is left with commented genexes.

Touching the intermediate file ensures that the post-process step is
performed every time, even if the content is unchanged, restoring the
expected behavior.

Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
2025-04-14 13:06:30 +02:00
Luca Burelli
a90870da4c cmake: yaml: improve escaping of strings with backslashes and quotes
Switching the intermediate file format from JSON to YAML has a very
significant benefit: the file is now loaded via yaml_load(), which
internally calls Python to parse the file into the JSON format that
CMake expects. This means that the file contents are now automatically
escaped properly for JSON; it is a huge improvement over the previous
implementation, which was escaping everything given as input to
to_yaml().

With the removal of the now-redundant call in to_yaml(), escaping is
applied exactly once per value or list, when it is passed to yaml_set().
This allows to convert the logic in zephyr_string(ESCAPE ...) to a more
robust "escape everything" approach.

These changes fix the handling of strings with backslashes and different
types of quotes passed either directly or via generator expression. The
existing tests are updated to cover these cases.

Two other small changes are made in this commit:

- a small check in internal_yaml_list_append() is removed, as the same
  issue is already detected by the caller yaml_set() logic.

- the to_yaml() function is modified to initialize the YAML output
  variable at the top level, which is the expected behavior. This
  resulted in genex temp files sometimes having duplicate lines.

Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
2025-04-10 10:11:47 +02:00
Luca Burelli
90aa937e3a cmake: yaml: switch to yaml for intermediate file
The intermediate file used to expand the generator expressions is now in
YAML format. This allows for a more robust handling of the data, as the
single quoted strings are a lot easier to escape: inside them every
character is a literal except for two single quotes (which intuitively
map to a literal single quote).

When saving a simple YAML file without genexes, the single quotes in
strings need to be escaped. However, doing so when saving the
intermediate file would make it harder to properly escape them later,
since it could be possible that the expansion of the generator
expressions would introduce new single quotes. For this reason, when
genexes are enabled, the escaping is now done in a single pass inside
the yaml-filter.cmake script.

Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
2025-04-10 10:11:47 +02:00
Luca Burelli
4a50fbf804 cmake: yaml: properly store strings
Store strings in YAML as single-quoted entries to avoid issues with
special characters. This also fixes a quirk with the current test
suite where the quotes in the expected value are filtered out by the
YAML import.

Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
2025-04-10 10:11:47 +02:00
Luca Burelli
f5b3e0adf4 cmake: extensions: (cosmetic) refactor zephyr_string()
This commit refactors the zephyr_string() function to explicitly
show that ESCAPE and SANITIZE are mutually exclusive options and
that SANITIZE joins multiple arguments into a single string before
processing it.

No functional change introduced by this commit.

Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
2025-04-10 10:11:47 +02:00
Luca Burelli
cab474affe cmake: yaml: (cosmetic) avoid referring to file type in variable names
To move away from the JSON/YAML terminology, rename the variables that
refer to the intermediate files to "expanded" and "output" files.

Also, clean up a few "C-style" function calls and a typo in a variable
name in the same files.

No functional change introduced in this commit.

Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
2025-04-10 10:11:47 +02:00
Torsten Rasmussen
a713f79031 cmake: fix Zephyr module ext order
MODULE_EXT_ROOT allows Zephyr modules to provide glue code for Zephyr
modules using `cmake-ext: True` and/or `kconfig-ext:True`.

A module ext root provides a `modules.cmake` file which defines
variables like: `set(ZEPHYR_FOO_CMAKE_DIR  <glue-code-path>/foo)`

It is intended that a downstream module can replace Zephyr's default
glue code, which again can be replaced further downstream.

Setting values in first modules.cmake (Zephyr's) are replaced by later
processed modules.cmake (downstream) when the setting name is identical.

Therefore the module ext root list should not be reversed, and Zephyr
itself should be placed as first entry in the list.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
2025-04-03 13:16:56 +02:00
Robin Kastberg
216ff00422 cmake: linker: dont place device tree memories at absolute addresses
Avoid placing the device tree memories at an absolute address.
This avoids placing both .rom_start AND SSRAM1 at
the same address on mps2/an521/cpu0.

This seems fine according to ld (since one placement is empty)
but causes a currently non-suppressable diag_warning

Signed-off-by: Robin Kastberg <robin.kastberg@iar.com>
2025-04-03 13:15:47 +02:00
Björn Bergman
fe0b16583c cmake: linker generator: ld: Files for section input patterns
For CONFIG_USERSPACE the input from gen_app_partitions.py there is
a need to be able to specify input files as well as input sections
patterns for zephyr_linker_section_configure().  This is used for
app partitions from libraries (which generate input patterns like
foo.a:*(.data*)).

This adds documentation to zephyr_linker_section_configure() to clarify
what INPUT allows, and also adds some parsing tricks to ld_script.cmake
to properly add the file patterns when they are missing.

Signed-off-by: Björn Bergman <bjorn.bergman@iar.com>
2025-03-27 17:17:03 +01:00
Björn Bergman
6f74d6fa90 cmake: linker generator: Functions for input from prev linker pass
Add methods for the linker-script generator to pick up information
from previus linkerpasses:
 * zephyr_linker_include_generated(FILE f.cmake [PASS X]  [KCONFIG])
   cmake-includes f.cmake in the relevant PASSes. This allows scripts
   to generate any content (e.g. sections or section configs) as if
   it was generated by the main cmake machiery. This is intended to
   cover the case of ld-script snippets generated by e.g.
   gen_app_partitions.py
   It can also parse KCconfig files to capture @CONFIG_FOO@ variables
 * @FOO[,undef:v]@ in an value or expression in the zephyr_linker_*
   inputs. This looks for a defintion of FOO (se below), and uses its
   value if found. If FOO is not defined, the whole @@ thing is left
   untouched, unless ,undef: is used, in which case v is used instead.
 * zephyr_linker_include_generated(FILE f.h [PASS x]) greps for f.h
   for #define FOO value to be accessed as @FOO@
 * zephyr_linker_include_var(VAR FOO VALUE V) allows the main
   cmake-script to set a @FOO@ variable.

Note that the #define support is VERY basic, and does not use a proper
pre-processor. It works for the current use of files generated by e.g.
gen_kobject_placeholders.py but is not a general solution.

Signed-off-by: Björn Bergman <bjorn.bergman@iar.com>
2025-03-27 17:17:03 +01:00
Björn Bergman
8382d67a9b cmake: linker generator: Refactor generator input file creation
Move creation of the generator arguments file from each target.cmake
into a function (zephyr_linker_generate_linker_settings_file).

Signed-off-by: Björn Bergman <bjorn.bergman@iar.com>
2025-03-27 17:17:03 +01:00
Björn Bergman
acdd816bdb cmake: linker generator: Add MIN/MAX_SIZE to zephyr_linker_section()
Add MIN_SIZE and MAX_SIZE options to zephyr_linker_section()
and zephyr_linker_section_configure().
This allows padding (for MIN_SIZE) and link-time checking (for MAX_SIZE)
of sections (and parts of sections).

Clarify comments for zephyr_linker_section_configure

Signed-off-by: Björn Bergman <bjorn.bergman@iar.com>
2025-03-27 17:17:03 +01:00
Björn Bergman
d3a88f7bfe cmake: linker generator: Handle NOT PASS and multiple PASS options
Make it possible to have multiple PASS parameters to
zephyr_linker_section() and zephyr_linker_section_configure() sections
(oring them) OR to have multiple PASS NOT p options (in which case the
sections applies in neither of the passes)

Signed-off-by: Björn Bergman <bjorn.bergman@iar.com>
2025-03-27 17:17:03 +01:00
Torsten Rasmussen
6384f28a2d cmake: support directory as argument to zephyr_library_amend()
Extend `zephyr_library_amend()` to support an optional directory
argument.
The current `zephyr_library_amend()` works well when used inside a
Zephyr module with same structure, but fails when the macro is called
from Zephyr module integration code is located in a Zephyr
`MODULE_EXT_ROOT` because in this case the CMake code being executed
is not present in the Zephyr module itself, in which case the dir name
creation based on relative to module dir give wrong result.

For this use-case then support a base directory.
This also allows for use-cases in Zephyr modules where the directory
structure matching Zephyr's own structure is placed in a sub-folder.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
2025-03-26 16:26:40 +01:00
Valerio Setti
13270a43c1 cmake: modules: dts: print error message if DTC fails
Currently stderr is printed only if dtc encounters warnings, but it's
not printed in case of errors. However this information can be useful
to quickly identify and resolve the problem.

To solve this let's add "COMMAND_ERROR_IS_FATAL ANY" to execute_process()
so that CMake will fail in case of errors and a proper message will be
printed on the output.

Signed-off-by: Valerio Setti <vsetti@baylibre.com>
2025-03-24 19:33:18 +01:00
Jamie McCrae
cc453dfed8 cmake: Remove previously deprecated look-ups
Removes functions that would handle deprecated variables and
functionality from CMake within Zephyr that were deprecated in
Zephyr 3.1 onwards but before 3.7

Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
2025-03-24 07:53:31 +01:00
Fabio Baltieri
c60ffe1e1b linker: update section names to be unambiguous
Recently 0ae0c3dc44 allowed for three digit priorities, this resulted
in objects potentially matching multiple sections, for example:

.z_init_PRE_KERNEL_2_0_0_
.z_init_PRE_KERNEL_2_?_*
.z_init_PRE_KERNEL_2_???_*

This does not seem to be detected by ld, but the IAR linker emits a
warning.

Add some extra qualifiers in the object section name to make it
unambiguous, this has the extra value of making it easier to interpret,
for example going from:

.z_init_POST_KERNEL_90_00012_

to

.z_init_POST_KERNEL_P_90_SUB_00012_

Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
2025-03-20 12:20:55 -04:00
Josh DeWitt
0ae0c3dc44 linker: Allow for 999 priority levels in init levels
Some projects may have needs for more than 99 priority levels, so add
a third linker input section for each obj level.

Signed-off-by: Josh DeWitt <josh.dewitt@garmin.com>
2025-03-19 18:53:22 -04:00
Josh DeWitt
0f46359cbf linker: Add underscore between the init level and priority
Ensure the priority is surrounded by underscores for clarity. This makes
sections show up as
z_init_PRE_KERNEL_1_0_0_ instead of
z_init_PRE_KERNEL_10_0_

Signed-off-by: Josh DeWitt <josh.dewitt@garmin.com>
2025-03-19 18:53:22 -04:00
Tom Hughes
4b415dfc4c cmake: modules: Refer to log file based on CMake version
Starting with cmake 3.26, the log file used for configure-time checks
has changed:

https://cmake.org/cmake/help/latest/release/3.26.html#configure-log

Signed-off-by: Tom Hughes <tomhughes@chromium.org>
2025-03-14 01:01:43 +01:00
Torsten Rasmussen
7f6b3f51ef cmake: remove BUILD type in function description.
Build type was removed in 763a49f082 but
the function description was not updated accordingly.

Remove build type from the function description.

Add board qualifier as that is missing.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
2025-03-13 16:58:10 +00:00
Jamie McCrae
9f12f8afb2 infrastructure: Remove hwmv1 support
Removes support for the deprecated hardware model version 1

Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
2025-03-13 16:53:07 +00:00
Torsten Rasmussen
991396c54a cmake: do not double escape double quote
Do not escape single escaped quote '\"'.
A single escape quote in CMake indicates the use of literal '"'.
Escaping those results in '\\"' which is a literal '\' and a quote which
encapsulates a string.
This is a result we do not want.
Therefore, exempt the '\"' sequence from further escaping.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
2025-02-24 15:35:48 +00:00
Torsten Rasmussen
cdbe424eca cmake: escape json input string
Escape the json input string given to `to_yaml()` function and the
content given to `yaml_set()` function.

This ensures that a string like `foo\bar` becomes `foo\\bar` during
internal CMake json processing and when written to the file it becomes
`foo\bar`.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
2025-02-21 11:41:26 +00:00
Sylvain Chouleur
4454734d12 scripts: code_relocate: support section filter
One might want to select the symbols to be relocated inside a file or
a library. To do this, one can use the FILTER argument of
zephyr_code_relocate which must contain a regular expression of the
section names to be selected for relocation.

The test_function_in_sram2 test case in
`tests/application_development/code_relocation` has been updated to
verify that only one function `function_in_sram()` is relocated to ram
and that the function `function_not_relocated()` is not being relocated
when using relocation filter.

Signed-off-by: Sylvain Chouleur <sylvain.chouleur@gmail.com>
Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
2025-02-14 03:02:56 +01:00
Torsten Rasmussen
cb8f99ab7a cmake: code relocation setting.
With code relocation directives passed to the gen_relocate_app.py script
using generated file, then each directive can be place on individual
line in the file and thus free up the `|` character as separator.

Furthermore, a multi-line file with each directive on separate line is
also more user-readable, making debugging easier.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
2025-02-14 03:02:56 +01:00
Björn Bergman
b0e08c8262 cmake: SHELL: vs zephyr_get_compile_X_for_lang
In zephyr_get_XYZ_for_lang() functions in extensions.cmake we try to mimic
what cmake does in generation time to filter out SHELL: tags. However,
this filtering was only done for list entries that did not contain
generator expressions.

This causes broken command lines for e.g. e.g. for the kobject_hash*c
if the toolchain puts "SHELL: $<$<COMPILER_LANGUAGE:C>:some thing>"
into the options.

Signed-off-by: Björn Bergman <bjorn.bergman@iar.com>
2025-02-13 20:09:13 +01:00
Jamie McCrae
0201683adb cmake: snippets: Add snippet help message
Adds a help message which gives details on a common issue with
snippets where the roots are not known or a snippet is applied
to multiple images

Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
2025-02-13 16:43:20 +01:00
Torsten Rasmussen
0828d0b0ef cmake: support array of maps in yaml module
This commit introduce support for maps in a yaml list.

The yaml_set() function has been extended with the following signature:
> yaml_set(NAME <name> KEY <key>...
>          [APPEND] LIST MAP <map1> MAP <map2> MAP ...
> )

where a `MAP <map>` has the form:
`MAP "<key1>: <value1>, <key2>: <value2>, ...`

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
2025-02-10 15:56:52 +00:00