-
Notifications
You must be signed in to change notification settings - Fork 694
[nrf toup] nordic: Reorganize how gen_uicr.py is invoked #3202
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
dc098ca
to
546e163
Compare
soc/nordic/common/uicr/gen_uicr.py
Outdated
@@ -169,13 +149,25 @@ def main() -> None: | |||
"--out-uicr-hex", | |||
required=True, | |||
type=argparse.FileType("w", encoding="utf-8"), | |||
help="Path to write the generated UICR HEX file to", | |||
help="Path to write the generated merged UICR+PERIPHCONF HEX file to (typically zephyr.hex)", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These artifacts are useful to have separate depending on your application, so the choice to keep them separate was deliberate. Can we keep them as two different outputs and use something like mergehex afterwards instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How are they useful? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is possible to have them separate. But it would complicate the build system, and also to a certain degree the user experience.
So I would prefer to not keep them separate unless necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PERIPHCONF area in MRAM can be modified even when UICR is locked, as long as you haven't put it in the PROTECTEDMEM region. So there is a use case for pulling out just the periphconf.hex part and including it in a DFU package without the UICR part.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
customers might bundle the periphconf in their ota image but not the rest of the uicr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, I did not think of that, will fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose even in non-DFU use-cases, you may have locked your UICR, and which to west flash a new periphconf, but not the UICR.
I could make this configurable via KConfig.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hex files restored
soc/nordic/common/uicr/gen_uicr.py
Outdated
f"Expected a DT node with label '{UICR_NODELABEL}'." | ||
) from e | ||
uicr.PERIPHCONF.ADDRESS = args.periphconf_address | ||
uicr.PERIPHCONF.MAXCOUNT = math.floor(args.periphconf_size / 8) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: noticed this earlier, but this could just be args.periphconf_size // 8
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about we error-out when it's not divisible by 8?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah super nice, but please split into independent hex files again
|
||
menu "UICR generator options" | ||
|
||
config UICR_SAMPLE_GENERATE_PERIPHCONF |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does the sample in the name stand for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is trying to communicate to the reader that this Kconfig option is specific to this gen_uicr "sample".
As opposed to most other Kconfigs in ~/ncs/zephyr/soc, which are read by all zephyr images.
Maybe
GEN_UICR_SAMPLE_GENERATE_PERIPHCONF
Would be clearer?
Or do you have another idea?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sample in the sense of example? That's what I assume and find confusing, this shouldn't be example code right?
Or in sample the sense of this one unit? image or target?
Wouldn't GEN_UICR_GENERATE_PERIPHCONF
be enough? Or would that be confusing because it only applies to the uicr target and not actually be set in the app or radio build?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
default y | ||
help | ||
Generate UICR HEX file. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trailing newline
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
dt_nodelabel(partition_path NODELABEL ${partition_nodelabel}) | ||
if(NOT DEFINED partition_path) | ||
message(FATAL_ERROR "${partition_nodelabel} not found in devicetree") | ||
endif() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dt_nodelabel(partition_path NODELABEL ${partition_nodelabel}) | |
if(NOT DEFINED partition_path) | |
message(FATAL_ERROR "${partition_nodelabel} not found in devicetree") | |
endif() | |
dt_nodelabel(partition_path NODELABEL ${partition_nodelabel} REQUIRED) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
Was not aware.
# Use CMAKE_VERBOSE_MAKEFILE to silence an unused-variable warning. | ||
if(CMAKE_VERBOSE_MAKEFILE) | ||
endif() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got 5 lines of warning in the logs when this variable went unreferenced.
I assume SYSBUILD passes it to each image, and Zephyr usually references it, but since I have this minimal Zephyr it goes unreferenced.
|
||
set(periphconf_args) | ||
set(periphconf_elfs) | ||
set(merged_hex_file ${APPLICATION_BINARY_DIR}/zephyr/zephyr.hex) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use the Kconfig for this for the bin name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
I couldn't find neither a variable nor a Kconfig that contained the hex suffix unfortunately.
@@ -0,0 +1,13 @@ | |||
# SPDX-License-Identifier: Apache-2.0 | |||
|
|||
source "Kconfig.zephyr" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit. non-blocking - might want to put this at bottom so that the application Kconfigs appear at the top
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't think prj.conf is needed and it will fallback to empty.conf? Could be wrong on that though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got an error without it earlier, but I'll retest.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get this error without it:
-- Board: nrf54h20dk, Revision: 0.9.0, qualifiers: nrf54h20/cpurad
CMake Error at /home/sebo/ncs/zephyr/cmake/modules/extensions.cmake:2919 (message):
No prj.conf file(s) was found in the
/home/sebo/ncs/zephyr/soc/nordic/common/uicr/gen_uicr folder(s), please
read the Zephyr documentation on application development.
Call Stack (most recent call first):
/home/sebo/ncs/zephyr/cmake/modules/configuration_files.cmake:40 (zephyr_file)
/home/sebo/ncs/zephyr/cmake/modules/zephyr_default.cmake:131 (include)
/home/sebo/ncs/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:75 (include)
/home/sebo/ncs/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:92 (include_boilerplate)
CMakeLists.txt:15 (find_package)
-- Configuring incomplete, errors occurred!
CMake Error at cmake/modules/sysbuild_extensions.cmake:530 (message):
CMake configure failed for Zephyr project: uicr
Location: /home/sebo/ncs/zephyr/soc/nordic/common/uicr/gen_uicr
Call Stack (most recent call first):
cmake/modules/sysbuild_images.cmake:43 (ExternalZephyrProject_Cmake)
cmake/modules/sysbuild_default.cmake:21 (include)
/home/sebo/ncs/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:75 (include)
/home/sebo/ncs/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:92 (include_boilerplate)
/home/sebo/ncs/zephyr/share/sysbuild-package/cmake/SysbuildConfig.cmake:8 (include)
template/CMakeLists.txt:10 (find_package)
-- Configuring incomplete, errors occurred!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
keep the empty file, maybe something to look at in future @tejlmand
|
||
# Ensure UICR is configured and built after the default image so EDT/ELFs exist. | ||
sysbuild_add_dependencies(CONFIGURE uicr ${DEFAULT_IMAGE}) | ||
add_dependencies( uicr ${DEFAULT_IMAGE}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add_dependencies( uicr ${DEFAULT_IMAGE}) | |
add_dependencies(uicr ${DEFAULT_IMAGE}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
soc/nordic/common/uicr/gen_uicr.py
Outdated
# Update UICR hex with the modified UICR data | ||
uicr_data = bytes(uicr) | ||
uicr_hex = IntelHex() # Reset and rebuild with updated UICR | ||
uicr_hex.frombytes(uicr_data, offset=args.uicr_address) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this might flow a bit cleaner if we populated each hex object just once, instead of populating them with initial data first and then overwriting it. For example:
periphconf_hex = IntelHex()
if args.in_periphconf_elfs: # Check if periphconf data is provided
periphconf_combined = extract_and_combine_periphconfs(args.in_periphconf_elfs)
padding_len = args.periphconf_size - len(periphconf_combined)
periphconf_final = periphconf_combined + bytes([0xFF for _ in range(padding_len)])
# Add periphconf data to separate and merged hex files
periphconf_hex.frombytes(periphconf_final, offset=args.periphconf_address)
uicr.PERIPHCONF.ENABLE = ENABLED_VALUE
uicr.PERIPHCONF.ADDRESS = args.periphconf_address
uicr.PERIPHCONF.MAXCOUNT = args.periphconf_size // 8
uicr_hex = IntelHex()
uicr_hex.frombytes(bytes(uicr), offset=args.uicr_address)
merged_hex = IntelHex()
merged_hex.fromdict(uicr_hex.todict())
if periphconf_hex:
merged_hex.fromdict(periphconf_hex.todict())
# Write the three hex files
merged_hex.write_hex_file(args.out_merged_hex)
uicr_hex.write_hex_file(args.out_uicr_hex)
if args.out_periphconf_hex:
periphconf_hex.write_hex_file(args.out_periphconf_hex)
(I think IntelHex.todict() works there, but haven't tried running it)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
much better!
soc/nordic/common/uicr/gen_uicr.py
Outdated
if args.in_periphconf_elfs: # Check if periphconf data is provided | ||
periphconf_combined = extract_and_combine_periphconfs(args.in_periphconf_elfs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should retain the ability to generate an empty (0xFFFF_FFFFs) periphconf blob if no elf is provided here - an empty periphconf is still valid
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
@karstenkoenig , @jonathannilsen , @nordicjm : All feedback addressed, will reupload to upstream zephyr soon. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should there be a license header in this file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
endif() | ||
|
||
if(EXISTS ${_dir}/zephyr/zephyr.dts) | ||
list(APPEND periphconf_elfs ${_dir}/zephyr/zephyr.elf) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this should also take into account whether KERNEL_BIN_NAME has been changed in the image it's getting from? Not sure how that is best handled
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't expect this to ever be anything but zephyr
Reorganize how gen_uicr.py is invoked. Instead of invoking it from one of the Zephyr images we invoke it from a new special Zephyr image called uicr. This uicr Zephyr image is flashed in the same way as normal Zephyr images so special handling in the runner is no longer necessary. Also, we simplify gen_uicr.py by moving parsing of Kconfig/DT from gen_uicr.py to CMake. Signed-off-by: Sebastian Bøe <[email protected]>
These patches are now up for review upstream in zephyrproject-rtos/zephyr#94796 |
Reorganize how gen_uicr.py is invoked
Ref: NCSDK-NONE