diff --git a/src/MyMesh.h b/src/MyMesh.h index 74502f0..44b6752 100644 --- a/src/MyMesh.h +++ b/src/MyMesh.h @@ -951,4 +951,8 @@ private: uint32_t _ui_trace_ping_tag = 0; }; +#if defined(ESP32_PLATFORM) +extern MyMesh& the_mesh; // PSRAM-resident (placement-new'd in main.cpp); reference keeps call sites unchanged +#else extern MyMesh the_mesh; +#endif diff --git a/src/main.cpp b/src/main.cpp index 02e342d..335efa1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,10 @@ #include // needed for PlatformIO #include #include "MyMesh.h" +#if defined(ESP32_PLATFORM) + #include // placement-new for the PSRAM-resident the_mesh + #include "esp_heap_caps.h" // heap_caps_malloc(MALLOC_CAP_SPIRAM) +#endif #if defined(ESP32_PLATFORM) && defined(HAS_TOUCH_UI) #include #include @@ -127,11 +131,31 @@ static uint32_t _atoi(const char* sp) { StdRNG fast_rng; SimpleMeshTables tables; +#if defined(ESP32_PLATFORM) +// the_mesh is ~42 KB (dominated by the MAX_CONTACTS ContactInfo array) and was the +// single biggest static internal-DRAM consumer. Place the whole object in PSRAM — +// the contacts array rides along inside it — and bind a reference so every +// `the_mesh.foo()` call site is unchanged. The constructor still runs HERE at +// static-init (PSRAM is already up; the UITask psAlloc statics rely on the same), +// so timing/behaviour are identical to the old direct global — only the address +// moves off internal DRAM. heap_caps falls back to internal RAM if PSRAM is absent. +static MyMesh& makeTheMesh() { + void* mem = heap_caps_malloc(sizeof(MyMesh), MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + if (!mem) mem = malloc(sizeof(MyMesh)); // no-PSRAM fallback: behaves as before + return *new (mem) MyMesh(radio_driver, fast_rng, rtc_clock, tables, store + #ifdef DISPLAY_CLASS + , &ui_task + #endif + ); +} +MyMesh& the_mesh = makeTheMesh(); +#else MyMesh the_mesh(radio_driver, fast_rng, rtc_clock, tables, store #ifdef DISPLAY_CLASS , &ui_task #endif ); +#endif /* END GLOBAL OBJECTS */