diff options
author | xengineering <me@xengineering.eu> | 2025-05-24 11:31:11 +0200 |
---|---|---|
committer | xengineering <me@xengineering.eu> | 2025-05-24 11:31:11 +0200 |
commit | a82bdbbec681cec0c6f5304318b6010f1752dbf6 (patch) | |
tree | 539d4610508c1bb3069c5f11ee63977e534b2a68 | |
parent | f38300b15627e5234f0f0a07c31c32135901dee7 (diff) | |
parent | bf8d20fe4d8d3369dd7f63e95f53613dbbfa3603 (diff) | |
download | iot-contact-a82bdbbec681cec0c6f5304318b6010f1752dbf6.tar iot-contact-a82bdbbec681cec0c6f5304318b6010f1752dbf6.tar.zst iot-contact-a82bdbbec681cec0c6f5304318b6010f1752dbf6.zip |
Merge build system improvements
- remove flash targets (replaced by easy to flash `factory-image.bin`)
- replaced installation step by copy targets
- provide `factory-image.bin` and `update-image.bin`
-rw-r--r-- | README.md | 8 | ||||
-rw-r--r-- | artifacts/meson.build | 22 | ||||
-rw-r--r-- | fw/app/meson.build | 45 | ||||
-rw-r--r-- | fw/btl/meson.build | 19 | ||||
-rw-r--r-- | fw/meson.build | 17 | ||||
-rw-r--r-- | fw/sim/meson.build | 3 | ||||
-rw-r--r-- | meson.build | 19 | ||||
-rw-r--r-- | pcb/meson.build | 8 | ||||
-rwxr-xr-x | tools/build_zephyr.py | 5 | ||||
-rwxr-xr-x | tools/configure_zephyr.py | 2 | ||||
-rwxr-xr-x | tools/make_factory_image.py | 95 | ||||
-rw-r--r-- | tools/meson.build | 1 | ||||
-rw-r--r-- | web/index.html | 4 | ||||
-rw-r--r-- | web/meson.build | 7 |
14 files changed, 168 insertions, 87 deletions
@@ -25,19 +25,17 @@ The project is built with the Meson build system. ``` meson setup build -cd build -ninja -meson install --destdir artifacts +ninja -C build ``` The resulting artifacts can be listed with `tree`. ``` -tree artifacts +tree build/artifacts ``` These artifacts are organized as static website. It can be opened with Firefox. ``` -firefox artifacts/index.html +firefox build/artifacts/index.html ``` diff --git a/artifacts/meson.build b/artifacts/meson.build new file mode 100644 index 0000000..278c695 --- /dev/null +++ b/artifacts/meson.build @@ -0,0 +1,22 @@ +artifacts = [ + index_html, + css, + schematic, + bom, + simulation, + update_image, + factory_image, +] + +foreach artifact : artifacts + custom_target( + output: [fs.name(artifact.full_path())], + command: [ + cp, + artifact.full_path(), + meson.current_build_dir(), + ], + depends: artifact, + build_by_default: true, + ) +endforeach diff --git a/fw/app/meson.build b/fw/app/meson.build index ddd5aa6..6665fe4 100644 --- a/fw/app/meson.build +++ b/fw/app/meson.build @@ -15,7 +15,6 @@ external_project.add_project( ) application = custom_target( - 'application', output: ['application.bin'], command: [ build_zephyr, @@ -25,35 +24,37 @@ application = custom_target( ], ) -application_signed = custom_target( - 'application_signed', - output: ['application.signed.bin'], +version = '0.0.0' +header_size = '0x200' +slot_size = '0xc0000' + +update_image = custom_target( + output: ['update-image.bin'], command: [ imgtool, 'sign', - '--version', '0.0.0', - '--header-size', '0x200', - '--slot-size', '0xc0000', + '--version', version, + '--header-size', header_size, + '--slot-size', slot_size, '--key', signing_key, - meson.current_build_dir() / 'application.bin', - meson.current_build_dir() / 'application.signed.bin', + application, + '@OUTPUT@', ], - build_by_default: true, depends: application, - install: true, - install_dir: '/', ) -flash_application = custom_target( - build_always_stale: true, - build_by_default: false, +application_signed_confirmed = custom_target( + output: ['application.signed.confirmed.bin'], command: [ - 'st-flash', - '--connect-under-reset', - 'write', - meson.current_build_dir() / 'application.signed.bin', - '0x8040000', + imgtool, + 'sign', + '--version', version, + '--header-size', header_size, + '--slot-size', slot_size, + '--key', signing_key, + '--confirm', + application, + '@OUTPUT@', ], - depends: application_signed, - output: ['flash'], + depends: application, ) diff --git a/fw/btl/meson.build b/fw/btl/meson.build index 8ca1eb3..204fe20 100644 --- a/fw/btl/meson.build +++ b/fw/btl/meson.build @@ -14,7 +14,7 @@ external_project.add_project( verbose: true, ) -bootloader = custom_target('bootloader', +bootloader = custom_target( output: ['bootloader.bin'], command: [ build_zephyr, @@ -22,21 +22,4 @@ bootloader = custom_target('bootloader', '--binary-name', 'zephyr.bin', '--target-name', 'bootloader.bin', ], - build_by_default: true, - install: true, - install_dir: '/', -) - -flash_bootloader = custom_target( - build_always_stale: true, - build_by_default: false, - command: [ - 'st-flash', - '--connect-under-reset', - 'write', - meson.current_build_dir() / 'bootloader.bin', - '0x8000000', - ], - depends: bootloader, - output: ['flash'], ) diff --git a/fw/meson.build b/fw/meson.build index f61058c..8f45d5b 100644 --- a/fw/meson.build +++ b/fw/meson.build @@ -8,13 +8,16 @@ subdir('app') subdir('btl') subdir('sim') -erase = custom_target( - build_always_stale: true, - build_by_default: false, +factory_image = custom_target( + output: ['factory-image.bin'], command: [ - 'st-flash', - '--connect-under-reset', - 'erase', + make_factory_image, + '--bootloader', bootloader, + '--application', application_signed_confirmed, + '--factory-image', '@OUTPUT@', + ], + depends: [ + bootloader, + application_signed_confirmed, ], - output: ['erase'], ) diff --git a/fw/sim/meson.build b/fw/sim/meson.build index 7667f9b..5edcad9 100644 --- a/fw/sim/meson.build +++ b/fw/sim/meson.build @@ -13,7 +13,6 @@ external_project.add_project( ) simulation = custom_target( - 'simulation', output: ['simulation-linux-amd64.exe'], command: [ build_zephyr, @@ -22,6 +21,4 @@ simulation = custom_target( '--target-name', 'simulation-linux-amd64.exe', ], build_by_default: true, - install: true, - install_dir: '/', ) diff --git a/meson.build b/meson.build index eb7f9ad..9b7d7c1 100644 --- a/meson.build +++ b/meson.build @@ -1,20 +1,13 @@ -project( - 'iot-contact', - default_options: { - 'prefix': '/', - }, -) +project('iot-contact') -subdir('tools') +cp = find_program('cp', required : true) fs = import('fs') -css = fs.copyfile( - meson.current_source_dir() / 'simple.css' / 'simple.css', - 'simple.css', - install: true, - install_dir: '/', -) +css = fs.copyfile(meson.current_source_dir() / 'simple.css' / 'simple.css') + +subdir('tools') subdir('fw') subdir('pcb') subdir('web') +subdir('artifacts') diff --git a/pcb/meson.build b/pcb/meson.build index f320aae..293b2a1 100644 --- a/pcb/meson.build +++ b/pcb/meson.build @@ -7,7 +7,7 @@ schematic_files = [ 'processor.kicad_sch', ] -schematic = custom_target('schematic', +schematic = custom_target( output: ['schematic.pdf'], command: [ 'kicad-cli', @@ -19,11 +19,9 @@ schematic = custom_target('schematic', ], depend_files: schematic_files, build_by_default: true, - install: true, - install_dir: '/', ) -bom = custom_target('bom', +bom = custom_target( output: ['bill-of-materials.csv'], command: [ 'kicad-cli', @@ -37,6 +35,4 @@ bom = custom_target('bom', ], depend_files: schematic_files, build_by_default: true, - install: true, - install_dir: '/', ) diff --git a/tools/build_zephyr.py b/tools/build_zephyr.py index 1d9e783..5dd9e47 100755 --- a/tools/build_zephyr.py +++ b/tools/build_zephyr.py @@ -38,10 +38,7 @@ def main() -> None: check=True, ) - shutil.copy( - build_tree / "zephyr" / args.binary_name, - output_dir / args.target_name - ) + shutil.copy(build_tree / "zephyr" / args.binary_name, output_dir / args.target_name) if __name__ == "__main__": diff --git a/tools/configure_zephyr.py b/tools/configure_zephyr.py index e709063..f4707c6 100755 --- a/tools/configure_zephyr.py +++ b/tools/configure_zephyr.py @@ -43,7 +43,7 @@ def main() -> None: command.append(f"-DEXTRA_CONF_FILE={args.extra_config}") if args.signing_key is not None: - command.append(f"-DCONFIG_BOOT_SIGNATURE_KEY_FILE=\"{args.signing_key}\"") + command.append(f'-DCONFIG_BOOT_SIGNATURE_KEY_FILE="{args.signing_key}"') subprocess.run(command, shell=False, check=True) diff --git a/tools/make_factory_image.py b/tools/make_factory_image.py new file mode 100755 index 0000000..735f657 --- /dev/null +++ b/tools/make_factory_image.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python3 + + +import argparse +import dataclasses +import pathlib + + +PADDING_BYTE: bytes = b"\xff" + + +def main() -> None: + args = Arguments.from_cli() + print(args) + + factory_image: bytes = join( + bootloader=args.bootloader.read_bytes(), + application=args.application.read_bytes(), + offset=args.offset, + ) + + args.factory_image.write_bytes(factory_image) + + +def join(bootloader: bytes, application: bytes, offset: int) -> bytes: + padding = PADDING_BYTE * (offset - len(bootloader)) + + return bootloader + padding + application + + +@dataclasses.dataclass +class Arguments: + bootloader: pathlib.Path + offset: int + application: pathlib.Path + factory_image: pathlib.Path + + def __post_init__(self) -> None: + assert isinstance(self.bootloader, pathlib.Path) + + assert isinstance(self.offset, int) + assert self.offset >= 0 + + assert isinstance(self.application, pathlib.Path) + + assert isinstance(self.factory_image, pathlib.Path) + + def __str__(self) -> str: + return f"""{__file__} \\ + --bootloader {self.bootloader} \\ + --offset 0x{self.offset:X} \\ + --application {self.application} \\ + --factory_image {self.factory_image}""" + + @staticmethod + def from_cli() -> "Arguments": + parser = argparse.ArgumentParser( + description="Join bootloader and application firmware to a factory image" + ) + + parser.add_argument( + "-b", "--bootloader", required=True, help="path to bootloader firmware" + ) + + default_offset = 0x40000 + parser.add_argument( + "-o", + "--offset", + default=default_offset, + help=f"offset in bytes between bootloader and application (default: 0x{default_offset:X})", + ) + + parser.add_argument( + "-a", "--application", required=True, help="path to application firmware" + ) + + parser.add_argument( + "-f", + "--factory-image", + default=pathlib.Path("factory-image.bin"), + help="path to output factory image file", + ) + + args = parser.parse_args() + + return Arguments( + bootloader=pathlib.Path(args.bootloader), + offset=int(args.offset), + application=pathlib.Path(args.application), + factory_image=pathlib.Path(args.factory_image), + ) + + +if __name__ == "__main__": + main() diff --git a/tools/meson.build b/tools/meson.build index 85ddbb3..f58c54b 100644 --- a/tools/meson.build +++ b/tools/meson.build @@ -1,2 +1,3 @@ configure_zephyr = meson.current_source_dir() / 'configure_zephyr.py' build_zephyr = meson.current_source_dir() / 'build_zephyr.py' +make_factory_image = meson.current_source_dir() / 'make_factory_image.py' diff --git a/web/index.html b/web/index.html index 1f23096..e5bf005 100644 --- a/web/index.html +++ b/web/index.html @@ -18,8 +18,8 @@ <h4>Firmware</h4> <ul> - <li><a href="application.signed.bin">application.signed.bin</a></li> - <li><a href="bootloader.bin">bootloader.bin</a></li> + <li><a href="factory-image.bin">factory-image.bin</a></li> + <li><a href="update-image.bin">update-image.bin</a></li> <li><a href="simulation-linux-amd64.exe">simulation-linux-amd64.exe</a></li> </ul> </main> diff --git a/web/meson.build b/web/meson.build index f8c2024..19551a5 100644 --- a/web/meson.build +++ b/web/meson.build @@ -1,6 +1 @@ -website = fs.copyfile( - meson.current_source_dir() / 'index.html', - 'index.html', - install: true, - install_dir: '/', -) +index_html = fs.copyfile(meson.current_source_dir() / 'index.html') |