Count runtime WiFi memory in every ESP32 MQTT profile
This commit is contained in:
1 parent
937f8610c7
commit
d11bf3615d
3 files changed
+50
-1
No files matched your search
@@ -33,6 +33,10 @@ Classic ESP32 additionally retains its existing 8 KiB **static DRAM** check.
|
||||
The policy adds allowances for task stacks, radio packet pools, screen objects
|
||||
and pixel buffers, filesystem/sensor allocations, enabled wireless stacks,
|
||||
MQTT connections, OTA scratch and transient allocations. ESP32 images with
|
||||
MQTT reserve the same 49,152-byte WiFi allowance even without `WIFI_SSID` or
|
||||
`WIFI_OTA_SEEDER`: saved runtime credentials can activate WiFi. Multiple WiFi
|
||||
features count that allowance once; PSRAM-backed TLS does not remove it.
|
||||
ESP32 images with
|
||||
RS-232 reserve another 6,656 bytes even when UART defaults off: 2,560 bytes for
|
||||
the source-bounded bridge object and allocation metadata, plus an unchanged
|
||||
4 KiB for the UART driver and buffers. This
|
||||
|
||||
@@ -142,7 +142,10 @@ def requirements(platform, defines, target):
|
||||
parts["uart_bridge_and_driver"] = 2560
|
||||
elif platform == "ESP32_PLATFORM":
|
||||
parts["core_tasks_usb_filesystems"] = 24576
|
||||
wifi = 49152 if "WIFI_SSID" in defines or "WIFI_OTA_SEEDER" in defines else 0
|
||||
# MQTT joins with saved runtime credentials even without a compiled SSID
|
||||
# or OTA seeder. Count its mandatory WiFi stack once with other WiFi uses.
|
||||
wifi = 49152 if any(name in defines for name in (
|
||||
"WIFI_SSID", "WIFI_OTA_SEEDER", "WITH_MQTT_BRIDGE")) else 0
|
||||
ble = 32768 if "BLE_PIN_CODE" in defines else 0
|
||||
parts["wireless_stacks"] = max(wifi, ble) if "COMPANION_EXCLUSIVE_WIFI_BLE" in defines else wifi + ble
|
||||
if "WITH_MQTT_BRIDGE" in defines:
|
||||
|
||||
@@ -233,6 +233,48 @@ class FirmwareRamTest(unittest.TestCase):
|
||||
ordinary = ram.requirements("ESP32_PLATFORM", {"BOARD_HAS_PSRAM": 1}, "v4_companion")
|
||||
self.assertNotIn("mqtt", ordinary)
|
||||
|
||||
def test_mqtt_without_build_time_wifi_credentials_reserves_wifi_stack_exactly_once(self):
|
||||
# MQTT can use persisted station credentials without either compile-time
|
||||
# WiFi option. Isolate the wireless budget from optional browser sessions.
|
||||
base = {"WEBCONFIG_DISABLED": 1}
|
||||
for target in ("Tbeam_SX1262_repeater_observer_mqtt", "v4_companion"):
|
||||
ordinary = ram.requirements("ESP32_PLATFORM", base, target)
|
||||
self.assertEqual(ordinary["components"]["wireless_stacks"], 0)
|
||||
mqtt = ram.requirements("ESP32_PLATFORM", {**base, "WITH_MQTT_BRIDGE": 1}, target)
|
||||
self.assertEqual(mqtt["components"]["wireless_stacks"], 49152)
|
||||
self.assertEqual(mqtt["required_heap_bytes"] - ordinary["required_heap_bytes"],
|
||||
49152 + 24576)
|
||||
for extra in ({"WIFI_SSID": ""}, {"WIFI_OTA_SEEDER": 1},
|
||||
{"WIFI_SSID": "saved-at-runtime", "WIFI_OTA_SEEDER": 1}):
|
||||
with self.subTest(target=target, extra=extra):
|
||||
combined = ram.requirements("ESP32_PLATFORM", {
|
||||
**base, "WITH_MQTT_BRIDGE": 1, **extra,
|
||||
}, target)
|
||||
self.assertEqual(combined, mqtt)
|
||||
|
||||
def test_mqtt_only_elf_gate_rejects_the_previously_omitted_wifi_allowance(self):
|
||||
defines = {"WITH_MQTT_BRIDGE": 1, "WEBCONFIG_DISABLED": 1}
|
||||
target = "Tbeam_SX1262_repeater_observer_mqtt"
|
||||
policy = ram.requirements("ESP32_PLATFORM", defines, target)
|
||||
self.assertEqual(policy["components"]["wireless_stacks"], 49152)
|
||||
required = policy["required_heap_bytes"]
|
||||
with tempfile.TemporaryDirectory() as temporary:
|
||||
path = Path(temporary) / "firmware.elf"
|
||||
report = Path(temporary) / "firmware.memory.json"
|
||||
# The old WiFi-omitted policy accepted the first linked capacity.
|
||||
# The corrected gate must reject it and enforce the exact new bound.
|
||||
for capacity, expected in ((required - 49152, False),
|
||||
(required - 1, False), (required, True)):
|
||||
with self.subTest(capacity=capacity), contextlib.redirect_stdout(io.StringIO()), contextlib.redirect_stderr(io.StringIO()):
|
||||
esp_fixture(path, modern=True, internal_length=capacity + 0x4000)
|
||||
status = ram.check_firmware(path, "ESP32_PLATFORM", "esp32s3",
|
||||
defines, target, report)
|
||||
result = json.loads(report.read_text())
|
||||
self.assertEqual(status == 0, expected)
|
||||
self.assertEqual(result["passed"], expected)
|
||||
self.assertEqual(result["available_internal_bytes"], capacity)
|
||||
self.assertEqual(result["required_heap_bytes"], required)
|
||||
|
||||
def test_mqtt_worker_stack_growth_raises_gate_and_contiguous_requirement(self):
|
||||
flags = {"WITH_MQTT_BRIDGE": 1, "BOARD_HAS_PSRAM": 1}
|
||||
base = ram.requirements("ESP32_PLATFORM", flags, "v4_companion")
|
||||
|
||||
Reference in new issue
Block a user