Fit Full Tbeam Room servers using qualified auxiliary memory

This commit is contained in:
mikecarper committed 2026-10-24 07:12:46 -07:00
1 parent 9d667835de
commit 03214a16df
5 files changed
+105 -6

No files matched your search

+4 -2
View File
@@ -3872,7 +3872,8 @@ apply_esp32_iram_advert_storage_profile() {
lilygo_tlora_v2_1_1_6_repeater_observer_mqtt|lilygo_tlora_v2_1_1_6_repeater_observer_mqtt_|\
lilygo_tlora_v2_1_1_6_room_server|lilygo_tlora_v2_1_1_6_room_server_|\
lilygo_tlora_v2_1_1_6_room_server_observer_mqtt|lilygo_tlora_v2_1_1_6_room_server_observer_mqtt_|\
tbeam_sx1262_repeater_observer_mqtt|tbeam_sx1276_repeater_observer_mqtt)
tbeam_sx1262_repeater_observer_mqtt|tbeam_sx1276_repeater_observer_mqtt|\
tbeam_sx1262_room_server_observer_mqtt|tbeam_sx1276_room_server_observer_mqtt)
export PLATFORMIO_BUILD_FLAGS="${PLATFORMIO_BUILD_FLAGS} -DFLOOD_ADVERT_IRAM_WORD_STORAGE=1"
;;
esac
@@ -3907,7 +3908,8 @@ apply_esp32_full_size_profile() {
case "${env_name,,}" in
lilygo_tlora_v2_1_1_6_room_server|lilygo_tlora_v2_1_1_6_room_server_|\
lilygo_tlora_v2_1_1_6_room_server_observer_mqtt|lilygo_tlora_v2_1_1_6_room_server_observer_mqtt_)
lilygo_tlora_v2_1_1_6_room_server_observer_mqtt|lilygo_tlora_v2_1_1_6_room_server_observer_mqtt_|\
tbeam_sx1262_room_server_observer_mqtt|tbeam_sx1276_room_server_observer_mqtt)
# Preserve all 32 Room posts in genuine byte-accessible RTC SLOW memory.
# The bounded proof implementation serves the same maximum 4096 leaves
# without retaining the legacy 16 KiB leaf cache alongside Room services.
+3 -2
View File
@@ -153,9 +153,10 @@ namespace mesh { class RoomJsonWriter; }
#if ROOM_POSTS_RTC_SLOW_STORAGE != 0 && ROOM_POSTS_RTC_SLOW_STORAGE != 1
#error "ROOM_POSTS_RTC_SLOW_STORAGE must be 0 or 1"
#endif
#if ROOM_POSTS_RTC_SLOW_STORAGE && (!defined(ESP32_PLATFORM) || !defined(LILYGO_TLORA) \
#if ROOM_POSTS_RTC_SLOW_STORAGE && (!defined(ESP32_PLATFORM) \
|| (!defined(LILYGO_TLORA) && !defined(TBEAM_SX1262) && !defined(TBEAM_SX1276)) \
|| !defined(MESHCORE_EXPANDED_PARTITION_PROFILE))
#error "RTC slow Room posts require the qualified Full TLora ESP32 recipe"
#error "RTC slow Room posts require a qualified Full TLora or Tbeam ESP32 recipe"
#endif
struct PostInfo {
+4 -1
View File
@@ -106,7 +106,10 @@ class FloodAdvertIramTests(unittest.TestCase):
('LilyGo_TLora_V2_1_1_6_room_server_observer_mqtt_',True),
('Tbeam_SX1262_repeater_observer_mqtt',True),
('Tbeam_SX1276_repeater_observer_mqtt',True),
('Tbeam_SX1262_room_server_observer_mqtt',False),
('Tbeam_SX1262_room_server_observer_mqtt',True),
('Tbeam_SX1276_room_server_observer_mqtt',True),
('Tbeam_SX1262_room_server',False),
('Tbeam_SX1276_room_server',False),
('Tbeam_SX1276_companion_radio_ble',False),
('LilyGo_TLora_V2_1_1_6_companion_radio_ble',False),
('Heltec_Wireless_Tracker_repeater',False),
+35
View File
@@ -129,6 +129,41 @@ int main() {
f"-DENV_INCLUDE_BME680_BSEC={sensors}",
])
def test_tbeam_full_rooms_preserve_maximum_source_and_bounded_ownership(self):
for board in ("TBEAM_SX1262", "TBEAM_SX1276"):
with self.subTest(board=board):
self.check_grouped_equivalence([
"-DESP32_PLATFORM=1", "-D" + board + "=1", "-DBOARD_HAS_PSRAM=1",
"-DOTA_BOUNDED_SOURCE_PROOFS=1",
])
def test_tbeam_room_budget_changes_only_actual_source_workspace(self):
import sys
sys.path.insert(0, str(ROOT / "scripts"))
from check_firmware_ram import requirements
flags = dict(ENABLE_OTA=1, OTA_HEAP_CONTEXT=1, WITH_MQTT_BRIDGE=1,
ADMIN_PASSWORD="password", BOARD_HAS_PSRAM=1,
DISPLAY_CLASS="SSD1306Display", MESH_ENABLE_ROOM_FLOOD_RULE_ENGINE=1,
MESHCORE_OTA_DEVICE_DEFLATE=1)
for radio in ("SX1262", "SX1276"):
with self.subTest(radio=radio):
target = "Tbeam_" + radio + "_room_server_observer_mqtt"
before = requirements("ESP32_PLATFORM", flags, target)
after = requirements("ESP32_PLATFORM", dict(flags, OTA_BOUNDED_SOURCE_PROOFS=1), target)
self.assertEqual(before["required_heap_bytes"], 212784)
self.assertEqual(after["required_heap_bytes"], 197936)
self.assertEqual(before["required_contiguous_bytes"], 18464)
self.assertEqual(after["required_contiguous_bytes"], 16400)
self.assertEqual(before["components"]["ota_generic_source_buffers"], 18464)
self.assertEqual(after["components"]["ota_generic_source_buffers"], 3616)
before_parts = dict(before["components"])
after_parts = dict(after["components"])
before_parts.pop("ota_generic_source_buffers")
after_parts.pop("ota_generic_source_buffers")
self.assertEqual(before_parts, after_parts)
self.assertEqual(before["mqtt"], after["mqtt"])
self.assertEqual(after_parts["allocation_and_transient_margin"], 16384)
def test_tlora_full_room_preserves_maximum_source_and_bounded_ownership(self):
self.check_grouped_equivalence([
"-DESP32_PLATFORM=1", "-DLILYGO_TLORA=1", "-DOTA_BOUNDED_SOURCE_PROOFS=1",
+59 -1
View File
@@ -131,7 +131,12 @@ int main(int argc,char** argv) {
(["-DROOM_POSTS_RTC_SLOW_STORAGE=1", "-DNRF52_PLATFORM=1"], False),
(["-DROOM_POSTS_RTC_SLOW_STORAGE=1", "-DESP32_PLATFORM=1"], False),
(["-DROOM_POSTS_RTC_SLOW_STORAGE=1", "-DESP32_PLATFORM=1", "-DLILYGO_TLORA=1",
"-DMESHCORE_EXPANDED_PARTITION_PROFILE=1"], True))
"-DMESHCORE_EXPANDED_PARTITION_PROFILE=1"], True),
*((["-DROOM_POSTS_RTC_SLOW_STORAGE=1", "-DESP32_PLATFORM=1", "-D" + board + "=1",
"-DMESHCORE_EXPANDED_PARTITION_PROFILE=1"], True)
for board in ("TBEAM_SX1262", "TBEAM_SX1276")),
*((["-DROOM_POSTS_RTC_SLOW_STORAGE=1", "-DESP32_PLATFORM=1", "-D" + board + "=1"], False)
for board in ("LILYGO_TLORA", "TBEAM_SX1262", "TBEAM_SX1276")))
for flags, valid in cases:
with self.subTest(flags=flags):
result = subprocess.run([shutil.which("g++") or "clang++", "-std=c++17", "-x", "c++",
@@ -139,6 +144,59 @@ int main(int argc,char** argv) {
capture_output=True, text=True, timeout=20)
self.assertEqual(result.returncode == 0, valid, result.stderr)
def test_only_qualified_full_room_recipes_select_complete_storage_policy(self):
text = (ROOT / "build_legacy.sh").read_text()
functions = []
for name in ("apply_esp32_full_size_profile", "apply_esp32_iram_advert_storage_profile"):
start = text.index(name + "() {")
functions.append(text[start:text.index("\n}\n", start) + 2])
targets = {
"Tbeam_SX1262_room_server_observer_mqtt": True,
"Tbeam_SX1276_room_server_observer_mqtt": True,
"LilyGo_TLora_V2_1_1_6_room_server_observer_mqtt_": True,
"Tbeam_SX1262_room_server": False,
"Tbeam_SX1276_room_server": False,
"Tbeam_SX1262_repeater_observer_mqtt": False,
"Tbeam_SX1276_companion_radio_ble": False,
"T_Beam_S3_Supreme_SX1262_room_server_observer_mqtt": False,
"RAK_4631_room_server": False,
}
for full in ("0", "1"):
for supported in ("0", "1"):
for target, selected in targets.items():
with self.subTest(full=full, supported=supported, target=target):
code = r'''
ESP32_FULL_BUILD="$1"
QUALIFIED="$2"
ESP32_FULL_MAX_NEIGHBOURS=254
DRAM_LIMITED_MAX_NEIGHBOURS=50
PLATFORMIO_BUILD_FLAGS="-DEXISTING=1"
declare -A PIO_ENV_FULL_WIFI_OTA_BY_NAME=()
supports_esp32_full_build() { [ "$QUALIFIED" = 1 ]; }
is_room_server_role_target() { [[ "$1" == *room_server* ]]; }
requires_dram_limited_neighbors() { [[ "$1" == Tbeam_SX12* ]]; }
requires_esp32_companion_full_ota_fallback() { return 1; }
append_platformio_build_unflags() { :; }
record_build_reduction() { :; }
''' + "\n".join(functions) + r'''
apply_esp32_full_size_profile "$3"
apply_esp32_iram_advert_storage_profile "$3"
printf "%s" "$PLATFORMIO_BUILD_FLAGS"
'''
result = subprocess.run(["bash", "-c", code, "bash", full, supported, target],
capture_output=True, text=True, check=True, timeout=10)
enabled = full == "1" and supported == "1" and selected
flags = result.stdout.split()
for name in ("ROOM_POSTS_RTC_SLOW_STORAGE", "OTA_BOUNDED_SOURCE_PROOFS"):
self.assertEqual(flags.count("-D" + name + "=1"), int(enabled), result.stdout)
if enabled:
self.assertIn("-DFLOOD_ADVERT_IRAM_WORD_STORAGE=1", flags)
self.assertNotIn("-DFLOOD_PACKET_FILTER_SLOTS=31", flags)
self.assertIn("-DMESH_ENABLE_ROOM_FLOOD_RULE_ENGINE=1", flags)
self.assertIn("-DMAX_NEIGHBOURS=" + ("50" if target.startswith("Tbeam_") else "254"), flags)
self.assertNotIn("-DMAX_UNSYNCED_POSTS", result.stdout)
self.assertNotIn("-DFLOOD_ADVERT_SOURCE_SLOTS", result.stdout)
def test_real_post_fifo_history_reload_maximum_text_and_catchup(self):
source, header, bank, initializer, clear, destructor, post = self.sources()
fixture = (ROOT / "test/fixtures/room_history_integration/test.cpp").read_text().split("int main()", 1)[0]