96 lines
3.1 KiB
Python
96 lines
3.1 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
merge_image.py - Merge the CAIIC bootloader and application binaries into a
|
|
single flash package for N32WB031KEQ6-2 (512KB).
|
|
|
|
Inputs (produced by the Keil after-build fromelf step):
|
|
Boot/MDK-ARM/bin/caiic_boot.bin -> 0x01000000
|
|
mcm-ddc-04/MDK-ARM/bin/embeddedSrc.bin -> 0x01008000 (APP1 bank)
|
|
|
|
Outputs (written to tools/out/):
|
|
caiic_full.hex Intel HEX, sparse (gaps omitted) - for pyocd/NSpyocd/J-Flash
|
|
caiic_full.bin raw binary from 0x01000000, gaps padded with 0xFF
|
|
|
|
Usage: python tools/merge_image.py
|
|
Run from anywhere; paths are resolved relative to this script.
|
|
"""
|
|
import os
|
|
import sys
|
|
|
|
FLASH_BASE = 0x01000000
|
|
|
|
# (input bin relative to repo root, load address)
|
|
IMAGES = [
|
|
(os.path.join("Boot", "MDK-ARM", "bin", "caiic_boot.bin"), 0x01000000),
|
|
(os.path.join("mcm-ddc-04", "MDK-ARM", "bin", "embeddedSrc.bin"), 0x01008000),
|
|
]
|
|
|
|
OUT_DIR = "out"
|
|
HEX_NAME = "caiic_full.hex"
|
|
BIN_NAME = "caiic_full.bin"
|
|
|
|
HEX_REC_LEN = 16
|
|
|
|
|
|
def hex_record(addr, rectype, data):
|
|
"""Build one Intel HEX record string."""
|
|
body = [len(data), (addr >> 8) & 0xFF, addr & 0xFF, rectype] + list(data)
|
|
cks = (-sum(body)) & 0xFF
|
|
return ":" + "".join("%02X" % b for b in body) + "%02X" % cks + "\n"
|
|
|
|
|
|
def write_hex(path, segments):
|
|
"""Write segments [(base_addr, bytes)] as Intel HEX with ELA records."""
|
|
with open(path, "w") as f:
|
|
ela = None
|
|
for base, blob in segments:
|
|
for off in range(0, len(blob), HEX_REC_LEN):
|
|
addr = base + off
|
|
new_ela = addr >> 16
|
|
if new_ela != ela:
|
|
ela = new_ela
|
|
f.write(hex_record(0, 4, [(ela >> 8) & 0xFF, ela & 0xFF]))
|
|
f.write(hex_record(addr & 0xFFFF, 0, blob[off:off + HEX_REC_LEN]))
|
|
f.write(":00000001FF\n")
|
|
|
|
|
|
def main():
|
|
root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
segments = []
|
|
for rel, addr in IMAGES:
|
|
path = os.path.join(root, rel)
|
|
if not os.path.isfile(path):
|
|
print("ERROR: %s not found - build the Keil project first" % rel)
|
|
return 1
|
|
with open(path, "rb") as f:
|
|
blob = f.read()
|
|
segments.append((addr, blob))
|
|
print("%-46s -> 0x%08X (%d bytes)" % (rel, addr, len(blob)))
|
|
|
|
out_dir = os.path.join(root, "tools", OUT_DIR)
|
|
if not os.path.isdir(out_dir):
|
|
os.makedirs(out_dir)
|
|
|
|
hex_path = os.path.join(out_dir, HEX_NAME)
|
|
write_hex(hex_path, segments)
|
|
|
|
# merged bin: FLASH_BASE .. end of last segment, gaps padded with 0xFF
|
|
end = max(addr + len(blob) for addr, blob in segments)
|
|
merged = bytearray(b"\xFF" * (end - FLASH_BASE))
|
|
for addr, blob in segments:
|
|
merged[addr - FLASH_BASE: addr - FLASH_BASE + len(blob)] = blob
|
|
bin_path = os.path.join(out_dir, BIN_NAME)
|
|
with open(bin_path, "wb") as f:
|
|
f.write(bytes(merged))
|
|
|
|
print("")
|
|
print("package written:")
|
|
print(" %s" % hex_path)
|
|
print(" %s (base 0x%08X, %d bytes)" % (bin_path, FLASH_BASE, len(merged)))
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|