mirror of
https://github.com/mikecarper/MeshCore.git
synced 2026-09-12 13:45:44 +00:00
112 lines
4.4 KiB
Python
112 lines
4.4 KiB
Python
Import("env")
|
|
|
|
import os
|
|
|
|
|
|
# These layouts encode board-specific data-placement contracts, not merely an
|
|
# application-size preference. A Full merged image must retain them so an
|
|
# application/partition-table migration does not silently move or orphan the
|
|
# board's persistent data.
|
|
PRESERVED_FULL_PARTITION_TABLES = {
|
|
"variants/sensecap_indicator-espnow/dual_ota_2560k_preserve_spiffs.csv",
|
|
"variants/sensecap_indicator-espnow/dual_ota_6400k_preserve_spiffs.csv",
|
|
}
|
|
|
|
# Explicitly selected by the smaller NimBLE capacity trials. The normal
|
|
# 4 MiB Full Companion still needs huge_app.csv for its larger application.
|
|
OPT_IN_FULL_PARTITION_TABLES = {"variants/dual_ota_1536k.csv"}
|
|
|
|
|
|
def parse_flash_size(value):
|
|
text = str(value).strip().upper()
|
|
multipliers = {"KB": 1024, "MB": 1024 * 1024}
|
|
for suffix, multiplier in multipliers.items():
|
|
if text.endswith(suffix):
|
|
return int(text[: -len(suffix)]) * multiplier
|
|
return int(text, 0)
|
|
|
|
|
|
def preserved_full_partition_table(value):
|
|
path = str(value or "").strip().replace("\\", "/")
|
|
return next(
|
|
(
|
|
table
|
|
for table in PRESERVED_FULL_PARTITION_TABLES
|
|
if path == table or path.endswith("/" + table)
|
|
),
|
|
None,
|
|
)
|
|
|
|
|
|
if os.environ.get("MESHCORE_ESP32_FULL_BUILD") == "1":
|
|
board = env.BoardConfig()
|
|
flash_size = parse_flash_size(board.get("upload.flash_size", "4MB"))
|
|
requested_partitions = os.environ.get(
|
|
"MESHCORE_ESP32_FULL_PARTITION_TABLE", ""
|
|
).strip() or str(board.get("build.full_partitions", "")).strip()
|
|
required_partitions = preserved_full_partition_table(
|
|
requested_partitions
|
|
)
|
|
if requested_partitions in OPT_IN_FULL_PARTITION_TABLES:
|
|
if flash_size < 4 * 1024 * 1024:
|
|
raise ValueError("Full dual-OTA trial requires at least 4 MiB flash")
|
|
required_partitions = requested_partitions
|
|
if requested_partitions and not required_partitions:
|
|
raise ValueError(
|
|
"unsupported required Full partition table: "
|
|
+ requested_partitions
|
|
)
|
|
preserved_partitions = required_partitions or preserved_full_partition_table(
|
|
board.get("build.partitions", "")
|
|
)
|
|
if str(board.get("build.mcu", "")).lower() == "esp32s3":
|
|
# Every S3 Full image must remain ROM-bootable across the supported
|
|
# flash parts. Some board manifests default to QIO even though their
|
|
# ROM/bootloader chain only starts a merged image reliably in DIO.
|
|
# PSRAM mode is an independent setting and is intentionally untouched.
|
|
board.update("build.flash_mode", "dio")
|
|
print("ESP32-S3 FULL build: forcing ROM-compatible DIO flash mode")
|
|
companion_radio_full = (
|
|
os.environ.get("MESHCORE_COMPANION_RADIO_FULL") == "1"
|
|
)
|
|
tbeam_1w = board.get("build.variant", "") == "lilygo_tbeam_1w"
|
|
|
|
if companion_radio_full and tbeam_1w:
|
|
# The Full Companion is an mOTA source only and never installs into a
|
|
# second local app slot. Match LilyGo's factory T-Beam 1W boot layout so
|
|
# a merged recovery image changes only the application, not the proven
|
|
# boot/partition chain. The 3 MiB app slot has ample room for this role.
|
|
partitions = "huge_app.csv"
|
|
elif preserved_partitions:
|
|
partitions = preserved_partitions
|
|
elif flash_size >= 16 * 1024 * 1024:
|
|
partitions = "default_16MB.csv"
|
|
elif flash_size >= 8 * 1024 * 1024:
|
|
partitions = "default_8MB.csv"
|
|
elif flash_size >= 4 * 1024 * 1024 and companion_radio_full:
|
|
# A classic ESP32 Companion with USB, BLE, WiFi, WebConfig, and the
|
|
# mOTA seeder can exceed the largest possible pair of 4 MiB OTA
|
|
# slots. This role cannot install mOTA on itself, so give it one 3 MiB
|
|
# application slot and retain SPIFFS/coredump.
|
|
partitions = "huge_app.csv"
|
|
elif flash_size >= 4 * 1024 * 1024:
|
|
partitions = "variants/dual_ota_full_4MB.csv"
|
|
else:
|
|
partitions = None
|
|
|
|
if partitions:
|
|
board.update("build.partitions", partitions)
|
|
print(
|
|
"ESP32 FULL build%s: using %s for %s flash"
|
|
% (
|
|
" (Companion source-only)" if companion_radio_full else "",
|
|
partitions,
|
|
board.get("upload.flash_size", "4MB"),
|
|
)
|
|
)
|
|
else:
|
|
print(
|
|
"ESP32 FULL build: retaining target partition table for %s flash"
|
|
% board.get("upload.flash_size", "unknown")
|
|
)
|