[esp32] Fix post build (#9951)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Jesse Hills 2025-07-29 18:44:45 +12:00 committed by GitHub
parent 5f7c2f771f
commit ace375944c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,10 +1,11 @@
Import("env") Import("env") # noqa: F821
import itertools # noqa: E402
import json # noqa: E402
import os # noqa: E402
import pathlib # noqa: E402
import shutil # noqa: E402
import os
import json
import shutil
import pathlib
import itertools
def merge_factory_bin(source, target, env): def merge_factory_bin(source, target, env):
""" """
@ -25,7 +26,9 @@ def merge_factory_bin(source, target, env):
try: try:
with flasher_args_path.open() as f: with flasher_args_path.open() as f:
flash_data = json.load(f) flash_data = json.load(f)
for addr, fname in sorted(flash_data["flash_files"].items(), key=lambda kv: int(kv[0], 16)): for addr, fname in sorted(
flash_data["flash_files"].items(), key=lambda kv: int(kv[0], 16)
):
file_path = pathlib.Path(fname) file_path = pathlib.Path(fname)
if file_path.exists(): if file_path.exists():
sections.append((addr, str(file_path))) sections.append((addr, str(file_path)))
@ -40,20 +43,27 @@ def merge_factory_bin(source, target, env):
if flash_images: if flash_images:
print("Using FLASH_EXTRA_IMAGES from PlatformIO environment") print("Using FLASH_EXTRA_IMAGES from PlatformIO environment")
# flatten any nested lists # flatten any nested lists
flat = list(itertools.chain.from_iterable( flat = list(
itertools.chain.from_iterable(
x if isinstance(x, (list, tuple)) else [x] for x in flash_images x if isinstance(x, (list, tuple)) else [x] for x in flash_images
)) )
)
entries = [env.subst(x) for x in flat] entries = [env.subst(x) for x in flat]
for i in range(0, len(entries) - 1, 2): for i in range(0, len(entries) - 1, 2):
addr, fname = entries[i], entries[i + 1] addr, fname = entries[i], entries[i + 1]
if isinstance(fname, (list, tuple)): if isinstance(fname, (list, tuple)):
print(f"Warning: Skipping malformed FLASH_EXTRA_IMAGES entry: {fname}") print(
f"Warning: Skipping malformed FLASH_EXTRA_IMAGES entry: {fname}"
)
continue continue
file_path = pathlib.Path(str(fname)) file_path = pathlib.Path(str(fname))
if file_path.exists(): if file_path.exists():
sections.append((addr, str(file_path))) sections.append((addr, file_path))
else: else:
print(f"Info: {file_path.name} not found — skipping") print(f"Info: {file_path.name} not found — skipping")
if sections:
# Append main firmware to sections
sections.append(("0x10000", firmware_path))
# 3. Final fallback: guess standard image locations # 3. Final fallback: guess standard image locations
if not sections: if not sections:
@ -62,11 +72,11 @@ def merge_factory_bin(source, target, env):
("0x0", build_dir / "bootloader" / "bootloader.bin"), ("0x0", build_dir / "bootloader" / "bootloader.bin"),
("0x8000", build_dir / "partition_table" / "partition-table.bin"), ("0x8000", build_dir / "partition_table" / "partition-table.bin"),
("0xe000", build_dir / "ota_data_initial.bin"), ("0xe000", build_dir / "ota_data_initial.bin"),
("0x10000", firmware_path) ("0x10000", firmware_path),
] ]
for addr, file_path in guesses: for addr, file_path in guesses:
if file_path.exists(): if file_path.exists():
sections.append((addr, str(file_path))) sections.append((addr, file_path))
else: else:
print(f"Info: {file_path.name} not found — skipping") print(f"Info: {file_path.name} not found — skipping")
@ -76,21 +86,25 @@ def merge_factory_bin(source, target, env):
return return
output_path = firmware_path.with_suffix(".factory.bin") output_path = firmware_path.with_suffix(".factory.bin")
python_exe = f'"{env.subst("$PYTHONEXE")}"'
cmd = [ cmd = [
"--chip", chip, python_exe,
"-m",
"esptool",
"--chip",
chip,
"merge_bin", "merge_bin",
"--flash_size", flash_size, "--flash_size",
"--output", str(output_path) flash_size,
"--output",
str(output_path),
] ]
for addr, file_path in sections: for addr, file_path in sections:
cmd += [addr, file_path] cmd += [addr, str(file_path)]
print(f"Merging binaries into {output_path}") print(f"Merging binaries into {output_path}")
result = env.Execute( result = env.Execute(
env.VerboseAction( env.VerboseAction(" ".join(cmd), "Merging binaries with esptool")
f"{env.subst('$PYTHONEXE')} -m esptool " + " ".join(cmd),
"Merging binaries with esptool"
)
) )
if result == 0: if result == 0:
@ -98,6 +112,7 @@ def merge_factory_bin(source, target, env):
else: else:
print(f"Error: esptool merge_bin failed with code {result}") print(f"Error: esptool merge_bin failed with code {result}")
def esp32_copy_ota_bin(source, target, env): def esp32_copy_ota_bin(source, target, env):
""" """
Copy the main firmware to a .ota.bin file for compatibility with ESPHome OTA tools. Copy the main firmware to a .ota.bin file for compatibility with ESPHome OTA tools.
@ -107,6 +122,7 @@ def esp32_copy_ota_bin(source, target, env):
shutil.copyfile(firmware_name, new_file_name) shutil.copyfile(firmware_name, new_file_name)
print(f"Copied firmware to {new_file_name}") print(f"Copied firmware to {new_file_name}")
# Run merge first, then ota copy second # Run merge first, then ota copy second
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", merge_factory_bin) env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", merge_factory_bin) # noqa: F821
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", esp32_copy_ota_bin) env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", esp32_copy_ota_bin) # noqa: F821