Files
trail-mate/scripts/prepare_webflash_release.py
T
liu weikai fc10860e4c feat(esp-idf): harden P4 Reticulum runtime
Validate T-Display P4 TFT ESP-IDF build after Reticulum runtime integration.

Build: idf.py -B build.t_display_p4_tft -D TRAIL_MATE_IDF_TARGET=t_display_p4_tft build
2026-07-17 00:01:22 +08:00

128 lines
3.8 KiB
Python

from __future__ import annotations
import argparse
import subprocess
import sys
from pathlib import Path
from webflash_targets import TARGETS_BY_ENV
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Create merged ESP Web Tools firmware binaries for a built PlatformIO env."
)
parser.add_argument("--env", required=True, help="PlatformIO environment name")
parser.add_argument(
"--build-root",
default=".pio/build",
help="Root directory that contains PlatformIO build outputs",
)
parser.add_argument(
"--dist",
default="dist",
help="Directory where merged web flasher binaries should be written",
)
parser.add_argument(
"--boot-app0",
default=None,
help="Path to boot_app0.bin from the Arduino ESP32 framework package",
)
parser.add_argument(
"--esptool",
default=None,
help="Path to esptool.py used to merge the firmware image",
)
return parser.parse_args()
def main() -> int:
args = parse_args()
target = TARGETS_BY_ENV.get(args.env)
if target is None:
print(f"Skipping web flasher packaging for unsupported env: {args.env}")
return 0
build_system = target.get("build_system", "platformio")
build_dir = (
Path(args.build_root) / f"build.{args.env}"
if build_system == "esp_idf"
else Path(args.build_root) / args.env
)
dist_dir = Path(args.dist)
dist_dir.mkdir(parents=True, exist_ok=True)
output = dist_dir / target["merged_asset_name"]
if build_system == "esp_idf":
bootloader = build_dir / "bootloader" / "bootloader.bin"
partitions = build_dir / "partition_table" / "partition-table.bin"
ota_data = build_dir / "ota_data_initial.bin"
firmware = build_dir / "trail-mate.bin"
required_paths = (bootloader, partitions, ota_data, firmware)
esptool_command = (
[sys.executable, args.esptool]
if args.esptool
else [sys.executable, "-m", "esptool"]
)
image_parts = (
"0x2000",
str(bootloader),
"0x8000",
str(partitions),
"0xe000",
str(ota_data),
"0x10000",
str(firmware),
)
else:
if not args.boot_app0 or not args.esptool:
raise ValueError("PlatformIO webflash packaging requires --boot-app0 and --esptool")
bootloader = build_dir / "bootloader.bin"
partitions = build_dir / "partitions.bin"
firmware = build_dir / "firmware.bin"
boot_app0 = Path(args.boot_app0)
esptool = Path(args.esptool)
required_paths = (bootloader, partitions, firmware, boot_app0, esptool)
esptool_command = [sys.executable, str(esptool)]
image_parts = (
"0x0",
str(bootloader),
"0x8000",
str(partitions),
"0xe000",
str(boot_app0),
"0x10000",
str(firmware),
)
missing_paths = [str(path) for path in required_paths if not path.exists()]
if missing_paths:
raise FileNotFoundError(
"Missing required files for web flasher packaging:\n "
+ "\n ".join(missing_paths)
)
command = esptool_command + [
"--chip",
target.get("esptool_chip", "esp32s3"),
"merge_bin",
"-o",
str(output),
"--flash_mode",
target["flash_mode"],
"--flash_freq",
target["flash_freq"],
"--flash_size",
target["flash_size"],
*image_parts,
]
print(f"Creating merged web flasher image for {args.env} -> {output}")
subprocess.run(command, check=True)
return 0
if __name__ == "__main__":
raise SystemExit(main())