From b87a8c5dd58ed56d917c2e243dd30e020f8c48ce Mon Sep 17 00:00:00 2001 From: Brendan O'Leary Date: Wed, 17 Dec 2025 20:27:38 -0500 Subject: [PATCH] Memory cleanup --- src/CrossPointWebServer.cpp | 14 ++++++++++++++ src/activities/network/WifiScreen.cpp | 21 +++++++++++++++++---- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/CrossPointWebServer.cpp b/src/CrossPointWebServer.cpp index 546676c..a87ffac 100644 --- a/src/CrossPointWebServer.cpp +++ b/src/CrossPointWebServer.cpp @@ -68,8 +68,11 @@ void CrossPointWebServer::begin() { return; } + Serial.printf("[%lu] [WEB] [MEM] Free heap before begin: %d bytes\n", millis(), ESP.getFreeHeap()); + Serial.printf("[%lu] [WEB] Creating web server on port %d...\n", millis(), port); server = new WebServer(port); + Serial.printf("[%lu] [WEB] [MEM] Free heap after WebServer allocation: %d bytes\n", millis(), ESP.getFreeHeap()); if (!server) { Serial.printf("[%lu] [WEB] Failed to create WebServer!\n", millis()); @@ -92,12 +95,14 @@ void CrossPointWebServer::begin() { server->on("/delete", HTTP_POST, [this]() { handleDelete(); }); server->onNotFound([this]() { handleNotFound(); }); + Serial.printf("[%lu] [WEB] [MEM] Free heap after route setup: %d bytes\n", millis(), ESP.getFreeHeap()); server->begin(); running = true; Serial.printf("[%lu] [WEB] Web server started on port %d\n", millis(), port); Serial.printf("[%lu] [WEB] Access at http://%s/\n", millis(), WiFi.localIP().toString().c_str()); + Serial.printf("[%lu] [WEB] [MEM] Free heap after server.begin(): %d bytes\n", millis(), ESP.getFreeHeap()); } void CrossPointWebServer::stop() { @@ -105,12 +110,21 @@ void CrossPointWebServer::stop() { return; } + Serial.printf("[%lu] [WEB] [MEM] Free heap before stop: %d bytes\n", millis(), ESP.getFreeHeap()); + server->stop(); + Serial.printf("[%lu] [WEB] [MEM] Free heap after server->stop(): %d bytes\n", millis(), ESP.getFreeHeap()); + delete server; server = nullptr; running = false; Serial.printf("[%lu] [WEB] Web server stopped\n", millis()); + Serial.printf("[%lu] [WEB] [MEM] Free heap after delete server: %d bytes\n", millis(), ESP.getFreeHeap()); + + // Note: Static upload variables (uploadFileName, uploadPath, uploadError) are declared + // later in the file and will be cleared when they go out of scope or on next upload + Serial.printf("[%lu] [WEB] [MEM] Free heap final: %d bytes\n", millis(), ESP.getFreeHeap()); } void CrossPointWebServer::handleClient() { diff --git a/src/activities/network/WifiScreen.cpp b/src/activities/network/WifiScreen.cpp index 1fdc34c..5f60f7d 100644 --- a/src/activities/network/WifiScreen.cpp +++ b/src/activities/network/WifiScreen.cpp @@ -48,24 +48,37 @@ void WifiScreen::onEnter() { } void WifiScreen::onExit() { + Serial.printf("[%lu] [WIFI] [MEM] Free heap at onExit start: %d bytes\n", millis(), ESP.getFreeHeap()); + // Stop any ongoing WiFi scan WiFi.scanDelete(); + Serial.printf("[%lu] [WIFI] [MEM] Free heap after scanDelete: %d bytes\n", millis(), ESP.getFreeHeap()); // Stop the web server to free memory crossPointWebServer.stop(); + Serial.printf("[%lu] [WIFI] [MEM] Free heap after webserver stop: %d bytes\n", millis(), ESP.getFreeHeap()); // Disconnect WiFi to free memory WiFi.disconnect(true); WiFi.mode(WIFI_OFF); + Serial.printf("[%lu] [WIFI] [MEM] Free heap after WiFi disconnect: %d bytes\n", millis(), ESP.getFreeHeap()); - // Wait until not rendering to delete task to avoid killing mid-instruction to EPD - xSemaphoreTake(renderingMutex, portMAX_DELAY); + // Delete the display task if (displayTaskHandle) { vTaskDelete(displayTaskHandle); displayTaskHandle = nullptr; } - vSemaphoreDelete(renderingMutex); - renderingMutex = nullptr; + + // Small delay to ensure task is fully deleted before cleaning up mutex + vTaskDelay(10 / portTICK_PERIOD_MS); + + // Now safe to delete the mutex + if (renderingMutex) { + vSemaphoreDelete(renderingMutex); + renderingMutex = nullptr; + } + + Serial.printf("[%lu] [WIFI] [MEM] Free heap at onExit end: %d bytes\n", millis(), ESP.getFreeHeap()); } void WifiScreen::startWifiScan() {