Fix heap exhaustion: enable PSRAM allocator + bound all tables + auto-reboot watchdog

Root cause: heltec_V4_boundary build was missing -DRNS_USE_TLSF=1 and
-DRNS_USE_ALLOCATOR=1 flags, causing ALL C++ new/delete to use internal
SRAM (239KB) instead of the PSRAM-backed TLSF pool (~1.6MB). Transport
data structures consumed internal heap until WiFi driver could not
allocate RX buffers (ESP_ERR_NO_MEM).

Changes:
- platformio.ini: Add TLSF/allocator flags to heltec_V4_boundary env,
  re-enable NDEBUG
- Transport.cpp: Add periodic culling of _path_requests (was unbounded,
  grew one entry per unique destination forever). Cull entries older than
  DESTINATION_TIMEOUT. Also cull _pending_local_path_requests for removed
  interfaces, and fix missing .erase() (Python .pop() equivalent).
- RNode_Firmware.ino: Replace WiFi watchdog halt-serial with auto-reboot.
  Add heap pressure check (reboot if free heap < 20KB). Increase WiFi
  grace period from 5s to 15s. Remove orphaned boundary_done label.
This commit is contained in:
James L
2026-02-25 13:48:10 -05:00
parent 8ee8e86563
commit 990649d810
3 changed files with 58 additions and 36 deletions

View File

@@ -571,6 +571,32 @@ static bool is_backbone_interface(const Interface& iface) {
}
}
// Cull the path requests table (entries older than destination timeout)
{
std::vector<Bytes> stale_path_requests;
for (const auto& [destination_hash, timestamp] : _path_requests) {
if (OS::time() > (timestamp + DESTINATION_TIMEOUT)) {
stale_path_requests.push_back(destination_hash);
}
}
for (const Bytes& destination_hash : stale_path_requests) {
_path_requests.erase(destination_hash);
}
}
// Cull pending local path requests for interfaces that no longer exist
{
std::vector<Bytes> stale_plpr;
for (const auto& [destination_hash, iface] : _pending_local_path_requests) {
if (_interfaces.count(iface.get_hash()) == 0) {
stale_plpr.push_back(destination_hash);
}
}
for (const Bytes& destination_hash : stale_plpr) {
_pending_local_path_requests.erase(destination_hash);
}
}
// Cull the tunnel table
count = 0;
std::vector<Bytes> stale_tunnels;
@@ -2144,6 +2170,7 @@ static bool is_backbone_interface(const Interface& iface) {
if (iter != _pending_local_path_requests.end()) {
//p desiring_interface = Transport.pending_local_path_requests.pop(packet.destination_hash)
//const Interface& desiring_interface = (*iter).second;
_pending_local_path_requests.erase(iter); // CBA FIX: pop() equivalent
retransmit_timeout = now;
retries = PATHFINDER_R;