summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxengineering <me@xengineering.eu>2025-05-24 11:31:11 +0200
committerxengineering <me@xengineering.eu>2025-05-24 11:31:11 +0200
commita82bdbbec681cec0c6f5304318b6010f1752dbf6 (patch)
tree539d4610508c1bb3069c5f11ee63977e534b2a68
parentf38300b15627e5234f0f0a07c31c32135901dee7 (diff)
parentbf8d20fe4d8d3369dd7f63e95f53613dbbfa3603 (diff)
downloadiot-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.md8
-rw-r--r--artifacts/meson.build22
-rw-r--r--fw/app/meson.build45
-rw-r--r--fw/btl/meson.build19
-rw-r--r--fw/meson.build17
-rw-r--r--fw/sim/meson.build3
-rw-r--r--meson.build19
-rw-r--r--pcb/meson.build8
-rwxr-xr-xtools/build_zephyr.py5
-rwxr-xr-xtools/configure_zephyr.py2
-rwxr-xr-xtools/make_factory_image.py95
-rw-r--r--tools/meson.build1
-rw-r--r--web/index.html4
-rw-r--r--web/meson.build7
14 files changed, 168 insertions, 87 deletions
diff --git a/README.md b/README.md
index 3d81e83..a6dfe0a 100644
--- a/README.md
+++ b/README.md
@@ -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')