1#!/usr/bin/env python3
2#
3# Copyright (c) 2018 Nordic Semiconductor ASA
4#
5# SPDX-License-Identifier: Apache-2.0
6
7# This merges a set of input hex files into a single output hex file.
8# Any conflicts will result in an error being reported.
9
10import argparse
11
12from intelhex import AddressOverlapError, IntelHex
13
14
15def merge_hex_files(output, input_hex_files, overlap, output_bin):
16    ih = IntelHex()
17
18    for hex_file_path in input_hex_files:
19        to_merge = IntelHex(hex_file_path)
20
21        # Since 'arm-none-eabi-objcopy' incorrectly inserts record
22        # type '03 - Start Segment Address', we need to remove the
23        # start_addr to avoid conflicts when merging.
24        to_merge.start_addr = None
25
26        try:
27            ih.merge(to_merge, overlap=overlap)
28        except AddressOverlapError as e:
29            raise AddressOverlapError(f"{hex_file_path} has merge issues") from e
30
31    output_format = "bin" if output_bin else "hex"
32    ih.tofile(output, format=output_format)
33
34
35def parse_args():
36    parser = argparse.ArgumentParser(
37        description="Merge hex files.",
38        formatter_class=argparse.RawDescriptionHelpFormatter,
39        allow_abbrev=False,
40    )
41    parser.add_argument(
42        "-o", "--output", required=False, default="merged.hex", help="Output file name."
43    )
44    parser.add_argument(
45        "--overlap",
46        default="error",
47        help="What to do when files overlap (error, ignore, replace). "
48        "See IntelHex.merge() for more info.",
49    )
50    parser.add_argument(
51        "--output-bin", action='store_true', help="Save the merged content as binary file."
52    )
53    parser.add_argument("input_files", nargs='*')
54    return parser.parse_args()
55
56
57def main():
58    args = parse_args()
59
60    merge_hex_files(args.output, args.input_files, args.overlap, args.output_bin)
61
62
63if __name__ == "__main__":
64    main()
65