diff --git a/CMakeLists.txt b/CMakeLists.txt index c3317bf60c..8647e51faa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1304,6 +1304,27 @@ add_custom_command( # NB: COMMENT only works for some CMake-Generators ) +# To populate with hex files to merge, do the following: +# set_property(GLOBAL APPEND PROPERTY HEX_FILES_TO_MERGE ${my_local_list}) +# Note that the zephyr.hex file will not be included automatically. +get_property(HEX_FILES_TO_MERGE GLOBAL PROPERTY HEX_FILES_TO_MERGE) +if(HEX_FILES_TO_MERGE) + # Merge in out-of-tree hex files. + set(merged_hex_name merged.hex) + + add_custom_command( + OUTPUT ${merged_hex_name} + COMMAND + ${PYTHON_EXECUTABLE} + ${ZEPHYR_BASE}/scripts/mergehex.py + -o ${merged_hex_name} + ${HEX_FILES_TO_MERGE} + DEPENDS ${HEX_FILES_TO_MERGE} ${logical_target_for_zephyr_elf} + ) + + add_custom_target(mergehex ALL DEPENDS ${merged_hex_name}) +endif() + if(CONFIG_OUTPUT_PRINT_MEMORY_USAGE) # Use --print-memory-usage with the first link. # diff --git a/cmake/flash/CMakeLists.txt b/cmake/flash/CMakeLists.txt index 4b4770a37b..64d4c59119 100644 --- a/cmake/flash/CMakeLists.txt +++ b/cmake/flash/CMakeLists.txt @@ -29,8 +29,14 @@ if(RUNNERS) CACHE STRING "Board definition directory" FORCE) set(ZEPHYR_RUNNER_CONFIG_KERNEL_ELF "${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME}" CACHE STRING "Path to kernel image in ELF format" FORCE) - set(ZEPHYR_RUNNER_CONFIG_KERNEL_HEX "${PROJECT_BINARY_DIR}/${KERNEL_HEX_NAME}" - CACHE STRING "Path to kernel image in Intel Hex format" FORCE) + get_property(HEX_FILES_TO_MERGE GLOBAL PROPERTY HEX_FILES_TO_MERGE) + if(HEX_FILES_TO_MERGE) + set(ZEPHYR_RUNNER_CONFIG_KERNEL_HEX "${PROJECT_BINARY_DIR}/${MERGED_HEX_NAME}" + CACHE STRING "Path to merged image in Intel Hex format" FORCE) + else() + set(ZEPHYR_RUNNER_CONFIG_KERNEL_HEX "${PROJECT_BINARY_DIR}/${KERNEL_HEX_NAME}" + CACHE STRING "Path to kernel image in Intel Hex format" FORCE) + endif() set(ZEPHYR_RUNNER_CONFIG_KERNEL_BIN "${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME}" CACHE STRING "Path to kernel image as raw binary" FORCE) # Not always applicable, but so often needed that they're provided diff --git a/doc/application/application.rst b/doc/application/application.rst index c3a3845f2c..1099a1a929 100644 --- a/doc/application/application.rst +++ b/doc/application/application.rst @@ -930,6 +930,19 @@ Below is a simple example :file:`CMakeList.txt`: target_sources(app PRIVATE src/main.c) +The Cmake property ``HEX_FILES_TO_MERGE`` +leverages the application configuration provided by +Kconfig and CMake to let you merge externally built hex files +with the hex file generated when building the Zephyr application. +For example: + +.. code-block:: cmake + + set_property(GLOBAL APPEND PROPERTY HEX_FILES_TO_MERGE + ${app_bootloader_hex} + ${PROJECT_BINARY_DIR}/${KERNEL_HEX_NAME} + ${app_provision_hex}) + CMakeCache.txt ============== @@ -1292,3 +1305,4 @@ project that demonstrates some of these features. .. _Eclipse IDE for C/C++ Developers: https://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/oxygen2 .. _GNU MCU Eclipse plug-ins: https://gnu-mcu-eclipse.github.io/plugins/install/ .. _pyOCD v0.11.0: https://github.com/mbedmicro/pyOCD/releases/tag/v0.11.0 + diff --git a/scripts/mergehex.py b/scripts/mergehex.py new file mode 100644 index 0000000000..119fc0f0aa --- /dev/null +++ b/scripts/mergehex.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2018 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +# This merges a set of input hex files into a single output hex file. +# Any conflicts will result in an error being reported. + +from intelhex import IntelHex + +import argparse + + +def merge_hex_files(output, input_hex_files): + ih = IntelHex() + + for hex_file_path in input_hex_files: + to_merge = IntelHex(hex_file_path) + + # Since 'arm-none-eabi-objcopy' incorrectly inserts record type '03 - Start Segment Address', we need to remove + # the start_addr to avoid conflicts when merging. + to_merge.start_addr = None + + ih.merge(to_merge) + ih.write_hex_file(output) + + +def parse_args(): + parser = argparse.ArgumentParser( + description="Merge hex files.", + formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument("-o", "--output", required=False, default="merged.hex", + type=argparse.FileType('w', encoding='UTF-8'), + help="Output file name.") + parser.add_argument("input_files", nargs='*') + return parser.parse_args() + + +def main(): + args = parse_args() + + merge_hex_files(args.output, args.input_files) + + +if __name__ == "__main__": + main() diff --git a/scripts/requirements.txt b/scripts/requirements.txt index 67c63059e4..dbd9304c04 100644 --- a/scripts/requirements.txt +++ b/scripts/requirements.txt @@ -17,3 +17,4 @@ pykwalify windows-curses; sys_platform == "win32" colorama Pillow +intelhex