Move OTA_HEAP_CONTEXT from two hand-edited envs to a pre-script gated on build.mcu == "esp32", so every classic ESP32 image gets it and none can drift. S2/S3/C-series and nRF52 keep the .bss singleton: they have no equivalent static-DRAM ceiling, so there a guaranteed-present workspace is the better trade for what is ultimately a recovery path. It has to be a build flag rather than a header default, because OTA_HEAP_CONTEXT must hold the same value in every translation unit that sees OtaContext.h - OtaContext.cpp included - and a header test on CONFIG_IDF_TARGET_ESP32 would depend on include order relative to sdkconfig.h. The script defers to OTA_SHARED_COMPANION_QUEUE where a Full Companion recipe already owns the storage. Fix a gap this exposes in the roles that now use it. Only CLI entry points acquire the context, so once it was released, a repeater with the temporary radio profile up would no longer serve or announce its own firmware - LoRa OTA would look enabled and silently do nothing. ota_service_temp_radio_context() holds the workspace for exactly the temp-radio window and hands it back outside it, which is where the saving was coming from anyway. Wired into the repeater, room server and sensor loops; the Companion keeps its own acquire-on-host-demand policy, since its context is borrowed from the offline message queue and must not be taken speculatively. Static DRAM, classic ESP32 (bytes occupied of a 124,580 region): Heltec_v2_repeater 108,332 -> 70,732 Heltec_v2_room_server 83,716 -> 68,300 Heltec_v2_companion_radio_ble 123,236 -> 107,772 (was failing on main) Tbeam_SX1262_repeater 86,932 -> 71,468 Tbeam_SX1262_repeater_observer_mqtt 121,132 -> 83,532 (was failing)
57 lines
2.4 KiB
Python
57 lines
2.4 KiB
Python
#!/usr/bin/env python3
|
|
"""Keep the idle mOTA workspace off classic ESP32's static DRAM.
|
|
|
|
Classic ESP32 links into a dram0_0_seg of ~124 KiB: memory.ld reserves the BT
|
|
controller's 0xdb5c bytes off the 0x2c200 window before the application gets
|
|
any, and no runtime call gives those static bytes back. OtaContext is several
|
|
kilobytes of that budget, held for the life of the device even though a
|
|
repeater or room server is outside an OTA window essentially always.
|
|
|
|
OTA_HEAP_CONTEXT switches OtaContext to the on-demand storage path, so it is
|
|
allocated when an OTA operation needs it and freed once idle. Applied here
|
|
rather than per-env so every classic ESP32 build gets it and none can drift.
|
|
|
|
Scoped to build.mcu == "esp32" deliberately. S2/S3/C-series and nRF52 have no
|
|
equivalent static-DRAM ceiling, so there the .bss singleton is the better
|
|
trade: it guarantees the workspace is present, and OTA is a recovery path.
|
|
|
|
This must be a build flag, not a header default. OTA_HEAP_CONTEXT has to hold
|
|
the same value in every translation unit that sees OtaContext.h - including
|
|
OtaContext.cpp, which defines the storage - and a header test on
|
|
CONFIG_IDF_TARGET_ESP32 would depend on whether that unit had already reached
|
|
sdkconfig.h.
|
|
"""
|
|
|
|
Import("env") # noqa: F821 -- PlatformIO/SCons supplies Import
|
|
|
|
# Both name the owner of the context storage, and OtaContext.h rejects the
|
|
# pair. OTA_SHARED_COMPANION_QUEUE arrives via PLATFORMIO_BUILD_FLAGS from
|
|
# build.sh's Full Companion recipes, which are nRF52/S3 today - but a future
|
|
# classic ESP32 Full Companion must lose this default, not fail to compile.
|
|
CONFLICTING = ("OTA_HEAP_CONTEXT", "OTA_SHARED_COMPANION_QUEUE")
|
|
|
|
|
|
def _already_defined(env):
|
|
for define in env.get("CPPDEFINES", []):
|
|
name = define[0] if isinstance(define, (list, tuple)) else define
|
|
if str(name) in CONFLICTING:
|
|
return True
|
|
# PLATFORMIO_BUILD_FLAGS reaches BUILD_FLAGS as raw text, which may not be
|
|
# parsed into CPPDEFINES yet when this pre-script runs.
|
|
for flag in env.get("BUILD_FLAGS", []):
|
|
text = str(flag)
|
|
if any(("-D" + name) in text for name in CONFLICTING):
|
|
return True
|
|
return False
|
|
|
|
|
|
def _apply(env):
|
|
if str(env.BoardConfig().get("build.mcu", "")).lower() != "esp32":
|
|
return
|
|
if _already_defined(env):
|
|
return
|
|
env.Append(CPPDEFINES=[("OTA_HEAP_CONTEXT", 1)])
|
|
|
|
|
|
_apply(env) # noqa: F821
|