Support subdivided nRF52 MOTA bridges

This commit is contained in:
mikecarper
2026-08-14 19:57:13 -07:00
parent d28c9f742e
commit 94a0ea2d7a
2 changed files with 53 additions and 3 deletions
@@ -44,6 +44,10 @@ class Target:
source_commit: str
bridge_stage: int = 0
os_stage: int = 0
os_stage_part: int = 0
os_stage_parts: int = 0
os_stage_subpart: int = 0
os_stage_subparts: int = 0
split_stage5: str = ""
mymesh_opt: str = ""
flood_rule_engine: bool = True
@@ -255,7 +259,9 @@ def main() -> int:
firmware_version = f"v{target.version}-{VERSION_SUFFIX}"
build_env = dict(os.environ)
for name in (
"MOTA_BRIDGE_OS_STAGE", "MOTA_BRIDGE_SPLIT_STAGE5",
"MOTA_BRIDGE_OS_STAGE", "MOTA_BRIDGE_OS_STAGE_PART",
"MOTA_BRIDGE_OS_STAGE_PARTS", "MOTA_BRIDGE_OS_STAGE_SUBPART",
"MOTA_BRIDGE_OS_STAGE_SUBPARTS", "MOTA_BRIDGE_SPLIT_STAGE5",
"MOTA_BRIDGE_MY_MESH_OPT", "MOTA_BRIDGE_OS_VERBOSE",
"PLATFORMIO_BUILD_FLAGS", "PLATFORMIO_EXTRA_SCRIPTS",
):
@@ -272,6 +278,12 @@ def main() -> int:
if target.os_stage:
build_env["MOTA_BRIDGE_OS_STAGE"] = str(target.os_stage)
build_env["PLATFORMIO_EXTRA_SCRIPTS"] = f"pre:{SELECTIVE_OS_HOOK}"
if target.os_stage_parts:
build_env["MOTA_BRIDGE_OS_STAGE_PART"] = str(target.os_stage_part)
build_env["MOTA_BRIDGE_OS_STAGE_PARTS"] = str(target.os_stage_parts)
if target.os_stage_subparts:
build_env["MOTA_BRIDGE_OS_STAGE_SUBPART"] = str(target.os_stage_subpart)
build_env["MOTA_BRIDGE_OS_STAGE_SUBPARTS"] = str(target.os_stage_subparts)
if target.split_stage5:
build_env["MOTA_BRIDGE_SPLIT_STAGE5"] = target.split_stage5
if target.mymesh_opt:
@@ -315,6 +327,10 @@ def main() -> int:
record["build_flags"] = flags
record["bridge_stage"] = target.bridge_stage
record["os_stage"] = target.os_stage
record["os_stage_part"] = target.os_stage_part
record["os_stage_parts"] = target.os_stage_parts
record["os_stage_subpart"] = target.os_stage_subpart
record["os_stage_subparts"] = target.os_stage_subparts
record["split_stage5"] = target.split_stage5
record["mymesh_opt"] = target.mymesh_opt
record["flood_rule_engine"] = target.flood_rule_engine
+36 -2
View File
@@ -3,8 +3,8 @@
Stage 1 size-optimizes crypto/Curve25519 units first. The remaining C/C++
units are assigned deterministically to stages 2 through 13. A stage includes
all earlier stages, so every intermediate is a normal bootable build and stage
13 is equivalent to globally selecting ``-Os``. The last two primary buckets
are subdivided because their measured nRF52 deltas exceeded internal staging.
13 is equivalent to globally selecting ``-Os``. A selected stage can also be
enabled cumulatively in deterministic parts when a board needs smaller deltas.
"""
import hashlib
@@ -22,6 +22,21 @@ except ValueError as exc:
if STAGE < 1 or STAGE > 13:
raise RuntimeError("MOTA_BRIDGE_OS_STAGE must be in 1..13")
try:
STAGE_PART = int(os.environ.get("MOTA_BRIDGE_OS_STAGE_PART", "1"))
STAGE_PARTS = int(os.environ.get("MOTA_BRIDGE_OS_STAGE_PARTS", "1"))
STAGE_SUBPART = int(os.environ.get("MOTA_BRIDGE_OS_STAGE_SUBPART", "1"))
STAGE_SUBPARTS = int(os.environ.get("MOTA_BRIDGE_OS_STAGE_SUBPARTS", "1"))
except ValueError as exc:
raise RuntimeError("MOTA bridge stage part values must be integers") from exc
if STAGE_PARTS < 1 or STAGE_PART < 1 or STAGE_PART > STAGE_PARTS:
raise RuntimeError("MOTA bridge stage part must be in 1..stage parts")
if STAGE_SUBPARTS < 1 or STAGE_SUBPART < 1 or STAGE_SUBPART > STAGE_SUBPARTS:
raise RuntimeError("MOTA bridge stage subpart must be in 1..stage subparts")
if STAGE_PARTS == 1 and STAGE_SUBPARTS != 1:
raise RuntimeError("MOTA bridge stage subparts require multiple stage parts")
CRYPTO_MARKERS = (
"ed25519",
"curve25519",
@@ -152,6 +167,18 @@ def _size_optimize_selected(env, node):
unit_stage = _unit_stage(path, env)
if unit_stage > STAGE:
return node
if unit_stage == STAGE and STAGE_PARTS > 1:
normalized = _normalized_unit_path(path, env)
digest = hashlib.sha256(normalized.encode("utf-8")).digest()
bucket = digest[4] % STAGE_PARTS
if bucket >= STAGE_PART:
return node
if (
bucket == STAGE_PART - 1
and STAGE_SUBPARTS > 1
and digest[5] % STAGE_SUBPARTS >= STAGE_SUBPART
):
return node
if (
STAGE == 5
and unit_stage == 5
@@ -175,6 +202,13 @@ def _size_optimize_selected(env, node):
print(f"MOTA bridge selective optimizer stage {STAGE}/13")
if STAGE_PARTS > 1:
print(f"MOTA bridge stage {STAGE} cumulative part {STAGE_PART}/{STAGE_PARTS}")
if STAGE_SUBPARTS > 1:
print(
f"MOTA bridge stage {STAGE} current bucket subpart "
f"{STAGE_SUBPART}/{STAGE_SUBPARTS}"
)
if STAGE == 5 and os.environ.get("MOTA_BRIDGE_SPLIT_STAGE5") == "first":
print("MOTA bridge stage 5 split: first half")
env.AddBuildMiddleware(_size_optimize_selected)