debug mode added for memory testing
This commit is contained in:
parent
d8bee1d21f
commit
a707cc6da2
@ -63,3 +63,11 @@ extends = base
|
|||||||
build_flags =
|
build_flags =
|
||||||
${base.build_flags}
|
${base.build_flags}
|
||||||
-DCROSSPOINT_VERSION=\"${crosspoint.version}\"
|
-DCROSSPOINT_VERSION=\"${crosspoint.version}\"
|
||||||
|
|
||||||
|
[env:debug_memory]
|
||||||
|
extends = base
|
||||||
|
build_flags =
|
||||||
|
${base.build_flags}
|
||||||
|
-DCROSSPOINT_VERSION=\"${crosspoint.version}-dev\"
|
||||||
|
-DDEBUG_MEMORY=1
|
||||||
|
-DCORE_DEBUG_LEVEL=4
|
||||||
|
|||||||
@ -60,6 +60,7 @@ void OpdsBookBrowserActivity::onExit() {
|
|||||||
if (displayTaskHandle) {
|
if (displayTaskHandle) {
|
||||||
vTaskDelete(displayTaskHandle);
|
vTaskDelete(displayTaskHandle);
|
||||||
displayTaskHandle = nullptr;
|
displayTaskHandle = nullptr;
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS); // Let idle task free stack
|
||||||
}
|
}
|
||||||
vSemaphoreDelete(renderingMutex);
|
vSemaphoreDelete(renderingMutex);
|
||||||
renderingMutex = nullptr;
|
renderingMutex = nullptr;
|
||||||
|
|||||||
@ -45,6 +45,7 @@ void DictionaryMenuActivity::onExit() {
|
|||||||
if (displayTaskHandle) {
|
if (displayTaskHandle) {
|
||||||
vTaskDelete(displayTaskHandle);
|
vTaskDelete(displayTaskHandle);
|
||||||
displayTaskHandle = nullptr;
|
displayTaskHandle = nullptr;
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS); // Let idle task free stack
|
||||||
}
|
}
|
||||||
vSemaphoreDelete(renderingMutex);
|
vSemaphoreDelete(renderingMutex);
|
||||||
renderingMutex = nullptr;
|
renderingMutex = nullptr;
|
||||||
|
|||||||
@ -40,6 +40,7 @@ void DictionaryResultActivity::onExit() {
|
|||||||
if (displayTaskHandle) {
|
if (displayTaskHandle) {
|
||||||
vTaskDelete(displayTaskHandle);
|
vTaskDelete(displayTaskHandle);
|
||||||
displayTaskHandle = nullptr;
|
displayTaskHandle = nullptr;
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS); // Let idle task free stack
|
||||||
}
|
}
|
||||||
vSemaphoreDelete(renderingMutex);
|
vSemaphoreDelete(renderingMutex);
|
||||||
renderingMutex = nullptr;
|
renderingMutex = nullptr;
|
||||||
|
|||||||
@ -88,6 +88,7 @@ void DictionarySearchActivity::onExit() {
|
|||||||
if (displayTaskHandle) {
|
if (displayTaskHandle) {
|
||||||
vTaskDelete(displayTaskHandle);
|
vTaskDelete(displayTaskHandle);
|
||||||
displayTaskHandle = nullptr;
|
displayTaskHandle = nullptr;
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS); // Let idle task free stack
|
||||||
}
|
}
|
||||||
vSemaphoreDelete(renderingMutex);
|
vSemaphoreDelete(renderingMutex);
|
||||||
renderingMutex = nullptr;
|
renderingMutex = nullptr;
|
||||||
|
|||||||
@ -42,6 +42,7 @@ void EpubWordSelectionActivity::onExit() {
|
|||||||
if (displayTaskHandle) {
|
if (displayTaskHandle) {
|
||||||
vTaskDelete(displayTaskHandle);
|
vTaskDelete(displayTaskHandle);
|
||||||
displayTaskHandle = nullptr;
|
displayTaskHandle = nullptr;
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS); // Let idle task free stack
|
||||||
}
|
}
|
||||||
vSemaphoreDelete(renderingMutex);
|
vSemaphoreDelete(renderingMutex);
|
||||||
renderingMutex = nullptr;
|
renderingMutex = nullptr;
|
||||||
|
|||||||
@ -39,6 +39,10 @@ int HomeActivity::getMenuItemCount() const {
|
|||||||
void HomeActivity::onEnter() {
|
void HomeActivity::onEnter() {
|
||||||
Activity::onEnter();
|
Activity::onEnter();
|
||||||
|
|
||||||
|
Serial.printf("[%lu] [HOME] [MEM] onEnter - Free: %d, Largest: %d, CoverBuffer: %s (%d bytes)\n", millis(),
|
||||||
|
ESP.getFreeHeap(), ESP.getMaxAllocHeap(), coverBufferStored ? "allocated" : "null",
|
||||||
|
coverBufferStored ? static_cast<int>(GfxRenderer::getBufferSize()) : 0);
|
||||||
|
|
||||||
renderingMutex = xSemaphoreCreateMutex();
|
renderingMutex = xSemaphoreCreateMutex();
|
||||||
|
|
||||||
// Check if we have a book to continue reading
|
// Check if we have a book to continue reading
|
||||||
@ -153,17 +157,24 @@ void HomeActivity::onEnter() {
|
|||||||
void HomeActivity::onExit() {
|
void HomeActivity::onExit() {
|
||||||
Activity::onExit();
|
Activity::onExit();
|
||||||
|
|
||||||
|
Serial.printf("[%lu] [HOME] [MEM] onExit start - Free: %d, Largest: %d, CoverBuffer: %s\n", millis(),
|
||||||
|
ESP.getFreeHeap(), ESP.getMaxAllocHeap(), coverBufferStored ? "allocated" : "null");
|
||||||
|
|
||||||
// Wait until not rendering to delete task to avoid killing mid-instruction to EPD
|
// Wait until not rendering to delete task to avoid killing mid-instruction to EPD
|
||||||
xSemaphoreTake(renderingMutex, portMAX_DELAY);
|
xSemaphoreTake(renderingMutex, portMAX_DELAY);
|
||||||
if (displayTaskHandle) {
|
if (displayTaskHandle) {
|
||||||
vTaskDelete(displayTaskHandle);
|
vTaskDelete(displayTaskHandle);
|
||||||
displayTaskHandle = nullptr;
|
displayTaskHandle = nullptr;
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS); // Let idle task free stack
|
||||||
}
|
}
|
||||||
vSemaphoreDelete(renderingMutex);
|
vSemaphoreDelete(renderingMutex);
|
||||||
renderingMutex = nullptr;
|
renderingMutex = nullptr;
|
||||||
|
|
||||||
// NOTE: Do NOT free cover buffer here - keep it cached for fast re-entry
|
// NOTE: Do NOT free cover buffer here - keep it cached for fast re-entry
|
||||||
// The buffer will be freed/replaced when the book changes
|
// The buffer will be freed/replaced when the book changes
|
||||||
|
|
||||||
|
Serial.printf("[%lu] [HOME] [MEM] onExit end - Free: %d, Largest: %d\n", millis(), ESP.getFreeHeap(),
|
||||||
|
ESP.getMaxAllocHeap());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HomeActivity::storeCoverBuffer() {
|
bool HomeActivity::storeCoverBuffer() {
|
||||||
@ -202,8 +213,11 @@ bool HomeActivity::restoreCoverBuffer() {
|
|||||||
|
|
||||||
void HomeActivity::freeCoverBuffer() {
|
void HomeActivity::freeCoverBuffer() {
|
||||||
if (coverBuffer) {
|
if (coverBuffer) {
|
||||||
|
Serial.printf("[%lu] [HOME] [MEM] Freeing cover buffer (%d bytes), heap before: %d\n", millis(),
|
||||||
|
static_cast<int>(GfxRenderer::getBufferSize()), ESP.getFreeHeap());
|
||||||
free(coverBuffer);
|
free(coverBuffer);
|
||||||
coverBuffer = nullptr;
|
coverBuffer = nullptr;
|
||||||
|
Serial.printf("[%lu] [HOME] [MEM] Cover buffer freed, heap after: %d\n", millis(), ESP.getFreeHeap());
|
||||||
}
|
}
|
||||||
coverBufferStored = false;
|
coverBufferStored = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -96,6 +96,7 @@ void ListViewActivity::onExit() {
|
|||||||
if (displayTaskHandle) {
|
if (displayTaskHandle) {
|
||||||
vTaskDelete(displayTaskHandle);
|
vTaskDelete(displayTaskHandle);
|
||||||
displayTaskHandle = nullptr;
|
displayTaskHandle = nullptr;
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS); // Let idle task free stack
|
||||||
}
|
}
|
||||||
vSemaphoreDelete(renderingMutex);
|
vSemaphoreDelete(renderingMutex);
|
||||||
renderingMutex = nullptr;
|
renderingMutex = nullptr;
|
||||||
|
|||||||
@ -188,6 +188,7 @@ void MyLibraryActivity::onExit() {
|
|||||||
if (displayTaskHandle) {
|
if (displayTaskHandle) {
|
||||||
vTaskDelete(displayTaskHandle);
|
vTaskDelete(displayTaskHandle);
|
||||||
displayTaskHandle = nullptr;
|
displayTaskHandle = nullptr;
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS); // Let idle task free stack
|
||||||
}
|
}
|
||||||
vSemaphoreDelete(renderingMutex);
|
vSemaphoreDelete(renderingMutex);
|
||||||
renderingMutex = nullptr;
|
renderingMutex = nullptr;
|
||||||
|
|||||||
@ -82,6 +82,7 @@ void CalibreWirelessActivity::onExit() {
|
|||||||
if (networkTaskHandle) {
|
if (networkTaskHandle) {
|
||||||
vTaskDelete(networkTaskHandle);
|
vTaskDelete(networkTaskHandle);
|
||||||
networkTaskHandle = nullptr;
|
networkTaskHandle = nullptr;
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS); // Let idle task free stack
|
||||||
}
|
}
|
||||||
xSemaphoreGive(stateMutex);
|
xSemaphoreGive(stateMutex);
|
||||||
|
|
||||||
@ -90,6 +91,7 @@ void CalibreWirelessActivity::onExit() {
|
|||||||
if (displayTaskHandle) {
|
if (displayTaskHandle) {
|
||||||
vTaskDelete(displayTaskHandle);
|
vTaskDelete(displayTaskHandle);
|
||||||
displayTaskHandle = nullptr;
|
displayTaskHandle = nullptr;
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS); // Let idle task free stack
|
||||||
}
|
}
|
||||||
vSemaphoreDelete(renderingMutex);
|
vSemaphoreDelete(renderingMutex);
|
||||||
renderingMutex = nullptr;
|
renderingMutex = nullptr;
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include <GfxRenderer.h>
|
#include <GfxRenderer.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <esp_task_wdt.h>
|
#include <esp_task_wdt.h>
|
||||||
|
#include <esp_wifi.h>
|
||||||
#include <qrcode.h>
|
#include <qrcode.h>
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
@ -94,15 +95,18 @@ void CrossPointWebServerActivity::onEnter() {
|
|||||||
void CrossPointWebServerActivity::onExit() {
|
void CrossPointWebServerActivity::onExit() {
|
||||||
ActivityWithSubactivity::onExit();
|
ActivityWithSubactivity::onExit();
|
||||||
|
|
||||||
Serial.printf("[%lu] [WEBACT] [MEM] Free heap at onExit start: %d bytes\n", millis(), ESP.getFreeHeap());
|
Serial.printf("[%lu] [WEBACT] [MEM] Free heap at onExit start: %d, Largest: %d\n", millis(), ESP.getFreeHeap(),
|
||||||
|
ESP.getMaxAllocHeap());
|
||||||
|
|
||||||
state = WebServerActivityState::SHUTTING_DOWN;
|
state = WebServerActivityState::SHUTTING_DOWN;
|
||||||
|
|
||||||
// Stop the web server first (before disconnecting WiFi)
|
// Stop the web server first (before disconnecting WiFi)
|
||||||
stopWebServer();
|
stopWebServer();
|
||||||
|
Serial.printf("[%lu] [WEBACT] [MEM] After stopWebServer: %d bytes\n", millis(), ESP.getFreeHeap());
|
||||||
|
|
||||||
// Stop mDNS
|
// Stop mDNS
|
||||||
MDNS.end();
|
MDNS.end();
|
||||||
|
Serial.printf("[%lu] [WEBACT] [MEM] After MDNS.end: %d bytes\n", millis(), ESP.getFreeHeap());
|
||||||
|
|
||||||
// Stop DNS server if running (AP mode)
|
// Stop DNS server if running (AP mode)
|
||||||
if (dnsServer) {
|
if (dnsServer) {
|
||||||
@ -110,6 +114,7 @@ void CrossPointWebServerActivity::onExit() {
|
|||||||
dnsServer->stop();
|
dnsServer->stop();
|
||||||
delete dnsServer;
|
delete dnsServer;
|
||||||
dnsServer = nullptr;
|
dnsServer = nullptr;
|
||||||
|
Serial.printf("[%lu] [WEBACT] [MEM] After DNS server cleanup: %d bytes\n", millis(), ESP.getFreeHeap());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Brief wait for LWIP stack to flush pending packets
|
// Brief wait for LWIP stack to flush pending packets
|
||||||
@ -120,16 +125,24 @@ void CrossPointWebServerActivity::onExit() {
|
|||||||
Serial.printf("[%lu] [WEBACT] Stopping WiFi AP...\n", millis());
|
Serial.printf("[%lu] [WEBACT] Stopping WiFi AP...\n", millis());
|
||||||
WiFi.softAPdisconnect(true);
|
WiFi.softAPdisconnect(true);
|
||||||
} else {
|
} else {
|
||||||
Serial.printf("[%lu] [WEBACT] Disconnecting WiFi (graceful)...\n", millis());
|
Serial.printf("[%lu] [WEBACT] Disconnecting WiFi...\n", millis());
|
||||||
WiFi.disconnect(false); // false = don't erase credentials, send disconnect frame
|
WiFi.disconnect(false); // false = don't erase credentials, just send disconnect frame
|
||||||
}
|
}
|
||||||
delay(30); // Allow disconnect frame to be sent
|
delay(100); // Allow disconnect frame to be sent and event callbacks to complete
|
||||||
|
Serial.printf("[%lu] [WEBACT] [MEM] After WiFi disconnect: %d bytes\n", millis(), ESP.getFreeHeap());
|
||||||
|
|
||||||
Serial.printf("[%lu] [WEBACT] Setting WiFi mode OFF...\n", millis());
|
Serial.printf("[%lu] [WEBACT] Setting WiFi mode OFF...\n", millis());
|
||||||
WiFi.mode(WIFI_OFF);
|
WiFi.mode(WIFI_OFF);
|
||||||
delay(30); // Allow WiFi hardware to power down
|
delay(50);
|
||||||
|
Serial.printf("[%lu] [WEBACT] [MEM] After WiFi.mode(OFF): %d bytes\n", millis(), ESP.getFreeHeap());
|
||||||
|
|
||||||
Serial.printf("[%lu] [WEBACT] [MEM] Free heap after WiFi disconnect: %d bytes\n", millis(), ESP.getFreeHeap());
|
// Aggressive WiFi cleanup: stop the WiFi driver to recover more memory
|
||||||
|
// WiFi is on-demand for File Transfer only, so full cleanup is safe
|
||||||
|
Serial.printf("[%lu] [WEBACT] Stopping WiFi driver (esp_wifi_stop)...\n", millis());
|
||||||
|
esp_wifi_stop();
|
||||||
|
delay(100); // Allow LWIP stack to fully release
|
||||||
|
Serial.printf("[%lu] [WEBACT] [MEM] After esp_wifi_stop: %d, Largest: %d\n", millis(), ESP.getFreeHeap(),
|
||||||
|
ESP.getMaxAllocHeap());
|
||||||
|
|
||||||
// Acquire mutex before deleting task
|
// Acquire mutex before deleting task
|
||||||
Serial.printf("[%lu] [WEBACT] Acquiring rendering mutex before task deletion...\n", millis());
|
Serial.printf("[%lu] [WEBACT] Acquiring rendering mutex before task deletion...\n", millis());
|
||||||
@ -140,16 +153,18 @@ void CrossPointWebServerActivity::onExit() {
|
|||||||
if (displayTaskHandle) {
|
if (displayTaskHandle) {
|
||||||
vTaskDelete(displayTaskHandle);
|
vTaskDelete(displayTaskHandle);
|
||||||
displayTaskHandle = nullptr;
|
displayTaskHandle = nullptr;
|
||||||
Serial.printf("[%lu] [WEBACT] Display task deleted\n", millis());
|
// Allow idle task to free the task stack
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||||
|
Serial.printf("[%lu] [WEBACT] [MEM] After task delete + yield: %d bytes\n", millis(), ESP.getFreeHeap());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete the mutex
|
// Delete the mutex
|
||||||
Serial.printf("[%lu] [WEBACT] Deleting mutex...\n", millis());
|
Serial.printf("[%lu] [WEBACT] Deleting mutex...\n", millis());
|
||||||
vSemaphoreDelete(renderingMutex);
|
vSemaphoreDelete(renderingMutex);
|
||||||
renderingMutex = nullptr;
|
renderingMutex = nullptr;
|
||||||
Serial.printf("[%lu] [WEBACT] Mutex deleted\n", millis());
|
|
||||||
|
|
||||||
Serial.printf("[%lu] [WEBACT] [MEM] Free heap at onExit end: %d bytes\n", millis(), ESP.getFreeHeap());
|
Serial.printf("[%lu] [WEBACT] [MEM] Free heap at onExit end: %d, Largest: %d, MinFree: %d\n", millis(),
|
||||||
|
ESP.getFreeHeap(), ESP.getMaxAllocHeap(), ESP.getMinFreeHeap());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CrossPointWebServerActivity::onNetworkModeSelected(const NetworkMode mode) {
|
void CrossPointWebServerActivity::onNetworkModeSelected(const NetworkMode mode) {
|
||||||
|
|||||||
@ -44,6 +44,7 @@ void NetworkModeSelectionActivity::onExit() {
|
|||||||
if (displayTaskHandle) {
|
if (displayTaskHandle) {
|
||||||
vTaskDelete(displayTaskHandle);
|
vTaskDelete(displayTaskHandle);
|
||||||
displayTaskHandle = nullptr;
|
displayTaskHandle = nullptr;
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS); // Let idle task free stack
|
||||||
}
|
}
|
||||||
vSemaphoreDelete(renderingMutex);
|
vSemaphoreDelete(renderingMutex);
|
||||||
renderingMutex = nullptr;
|
renderingMutex = nullptr;
|
||||||
|
|||||||
@ -82,6 +82,7 @@ void WifiSelectionActivity::onExit() {
|
|||||||
if (displayTaskHandle) {
|
if (displayTaskHandle) {
|
||||||
vTaskDelete(displayTaskHandle);
|
vTaskDelete(displayTaskHandle);
|
||||||
displayTaskHandle = nullptr;
|
displayTaskHandle = nullptr;
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS); // Let idle task free stack
|
||||||
Serial.printf("[%lu] [WIFI] Display task deleted\n", millis());
|
Serial.printf("[%lu] [WIFI] Display task deleted\n", millis());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -192,6 +192,7 @@ void EpubReaderActivity::onExit() {
|
|||||||
if (displayTaskHandle) {
|
if (displayTaskHandle) {
|
||||||
vTaskDelete(displayTaskHandle);
|
vTaskDelete(displayTaskHandle);
|
||||||
displayTaskHandle = nullptr;
|
displayTaskHandle = nullptr;
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS); // Let idle task free stack
|
||||||
}
|
}
|
||||||
vSemaphoreDelete(renderingMutex);
|
vSemaphoreDelete(renderingMutex);
|
||||||
renderingMutex = nullptr;
|
renderingMutex = nullptr;
|
||||||
|
|||||||
@ -88,6 +88,7 @@ void EpubReaderChapterSelectionActivity::onExit() {
|
|||||||
if (displayTaskHandle) {
|
if (displayTaskHandle) {
|
||||||
vTaskDelete(displayTaskHandle);
|
vTaskDelete(displayTaskHandle);
|
||||||
displayTaskHandle = nullptr;
|
displayTaskHandle = nullptr;
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS); // Let idle task free stack
|
||||||
}
|
}
|
||||||
vSemaphoreDelete(renderingMutex);
|
vSemaphoreDelete(renderingMutex);
|
||||||
renderingMutex = nullptr;
|
renderingMutex = nullptr;
|
||||||
|
|||||||
@ -131,6 +131,7 @@ void TxtReaderActivity::onExit() {
|
|||||||
if (displayTaskHandle) {
|
if (displayTaskHandle) {
|
||||||
vTaskDelete(displayTaskHandle);
|
vTaskDelete(displayTaskHandle);
|
||||||
displayTaskHandle = nullptr;
|
displayTaskHandle = nullptr;
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS); // Let idle task free stack
|
||||||
}
|
}
|
||||||
vSemaphoreDelete(renderingMutex);
|
vSemaphoreDelete(renderingMutex);
|
||||||
renderingMutex = nullptr;
|
renderingMutex = nullptr;
|
||||||
|
|||||||
@ -109,6 +109,7 @@ void XtcReaderActivity::onExit() {
|
|||||||
if (displayTaskHandle) {
|
if (displayTaskHandle) {
|
||||||
vTaskDelete(displayTaskHandle);
|
vTaskDelete(displayTaskHandle);
|
||||||
displayTaskHandle = nullptr;
|
displayTaskHandle = nullptr;
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS); // Let idle task free stack
|
||||||
}
|
}
|
||||||
vSemaphoreDelete(renderingMutex);
|
vSemaphoreDelete(renderingMutex);
|
||||||
renderingMutex = nullptr;
|
renderingMutex = nullptr;
|
||||||
|
|||||||
@ -69,6 +69,7 @@ void XtcReaderChapterSelectionActivity::onExit() {
|
|||||||
if (displayTaskHandle) {
|
if (displayTaskHandle) {
|
||||||
vTaskDelete(displayTaskHandle);
|
vTaskDelete(displayTaskHandle);
|
||||||
displayTaskHandle = nullptr;
|
displayTaskHandle = nullptr;
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS); // Let idle task free stack
|
||||||
}
|
}
|
||||||
vSemaphoreDelete(renderingMutex);
|
vSemaphoreDelete(renderingMutex);
|
||||||
renderingMutex = nullptr;
|
renderingMutex = nullptr;
|
||||||
|
|||||||
@ -44,6 +44,7 @@ void CalibreSettingsActivity::onExit() {
|
|||||||
if (displayTaskHandle) {
|
if (displayTaskHandle) {
|
||||||
vTaskDelete(displayTaskHandle);
|
vTaskDelete(displayTaskHandle);
|
||||||
displayTaskHandle = nullptr;
|
displayTaskHandle = nullptr;
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS); // Let idle task free stack
|
||||||
}
|
}
|
||||||
vSemaphoreDelete(renderingMutex);
|
vSemaphoreDelete(renderingMutex);
|
||||||
renderingMutex = nullptr;
|
renderingMutex = nullptr;
|
||||||
|
|||||||
@ -63,6 +63,7 @@ void CategorySettingsActivity::onExit() {
|
|||||||
if (displayTaskHandle) {
|
if (displayTaskHandle) {
|
||||||
vTaskDelete(displayTaskHandle);
|
vTaskDelete(displayTaskHandle);
|
||||||
displayTaskHandle = nullptr;
|
displayTaskHandle = nullptr;
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS); // Let idle task free stack
|
||||||
}
|
}
|
||||||
vSemaphoreDelete(renderingMutex);
|
vSemaphoreDelete(renderingMutex);
|
||||||
renderingMutex = nullptr;
|
renderingMutex = nullptr;
|
||||||
|
|||||||
@ -35,6 +35,7 @@ void ClearCacheActivity::onExit() {
|
|||||||
if (displayTaskHandle) {
|
if (displayTaskHandle) {
|
||||||
vTaskDelete(displayTaskHandle);
|
vTaskDelete(displayTaskHandle);
|
||||||
displayTaskHandle = nullptr;
|
displayTaskHandle = nullptr;
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS); // Let idle task free stack
|
||||||
}
|
}
|
||||||
vSemaphoreDelete(renderingMutex);
|
vSemaphoreDelete(renderingMutex);
|
||||||
renderingMutex = nullptr;
|
renderingMutex = nullptr;
|
||||||
|
|||||||
@ -90,6 +90,7 @@ void OtaUpdateActivity::onExit() {
|
|||||||
if (displayTaskHandle) {
|
if (displayTaskHandle) {
|
||||||
vTaskDelete(displayTaskHandle);
|
vTaskDelete(displayTaskHandle);
|
||||||
displayTaskHandle = nullptr;
|
displayTaskHandle = nullptr;
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS); // Let idle task free stack
|
||||||
}
|
}
|
||||||
vSemaphoreDelete(renderingMutex);
|
vSemaphoreDelete(renderingMutex);
|
||||||
renderingMutex = nullptr;
|
renderingMutex = nullptr;
|
||||||
|
|||||||
@ -115,6 +115,7 @@ void SettingsActivity::onExit() {
|
|||||||
if (displayTaskHandle) {
|
if (displayTaskHandle) {
|
||||||
vTaskDelete(displayTaskHandle);
|
vTaskDelete(displayTaskHandle);
|
||||||
displayTaskHandle = nullptr;
|
displayTaskHandle = nullptr;
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS); // Let idle task free stack
|
||||||
}
|
}
|
||||||
vSemaphoreDelete(renderingMutex);
|
vSemaphoreDelete(renderingMutex);
|
||||||
renderingMutex = nullptr;
|
renderingMutex = nullptr;
|
||||||
|
|||||||
@ -55,6 +55,7 @@ void KeyboardEntryActivity::onExit() {
|
|||||||
if (displayTaskHandle) {
|
if (displayTaskHandle) {
|
||||||
vTaskDelete(displayTaskHandle);
|
vTaskDelete(displayTaskHandle);
|
||||||
displayTaskHandle = nullptr;
|
displayTaskHandle = nullptr;
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS); // Let idle task free stack
|
||||||
}
|
}
|
||||||
vSemaphoreDelete(renderingMutex);
|
vSemaphoreDelete(renderingMutex);
|
||||||
renderingMutex = nullptr;
|
renderingMutex = nullptr;
|
||||||
|
|||||||
21
src/main.cpp
21
src/main.cpp
@ -114,17 +114,38 @@ EpdFontFamily ui12FontFamily(&ui12RegularFont, &ui12BoldFont);
|
|||||||
unsigned long t1 = 0;
|
unsigned long t1 = 0;
|
||||||
unsigned long t2 = 0;
|
unsigned long t2 = 0;
|
||||||
|
|
||||||
|
// Memory debugging helper - logs heap state for tracking leaks
|
||||||
|
#ifdef DEBUG_MEMORY
|
||||||
|
void logMemoryState(const char* tag, const char* context) {
|
||||||
|
Serial.printf("[%lu] [%s] [MEM] %s - Free: %d, Largest: %d, MinFree: %d\n",
|
||||||
|
millis(), tag, context,
|
||||||
|
ESP.getFreeHeap(),
|
||||||
|
ESP.getMaxAllocHeap(),
|
||||||
|
ESP.getMinFreeHeap());
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// No-op when not in debug mode
|
||||||
|
#define logMemoryState(tag, context) ((void)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
void exitActivity() {
|
void exitActivity() {
|
||||||
if (currentActivity) {
|
if (currentActivity) {
|
||||||
|
logMemoryState("MAIN", "Before onExit");
|
||||||
currentActivity->onExit();
|
currentActivity->onExit();
|
||||||
|
logMemoryState("MAIN", "After onExit, before delete");
|
||||||
delete currentActivity;
|
delete currentActivity;
|
||||||
currentActivity = nullptr;
|
currentActivity = nullptr;
|
||||||
|
// Allow idle task to free FreeRTOS task stacks
|
||||||
|
delay(50);
|
||||||
|
logMemoryState("MAIN", "After delete + delay");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void enterNewActivity(Activity* activity) {
|
void enterNewActivity(Activity* activity) {
|
||||||
|
logMemoryState("MAIN", "Before enterNewActivity");
|
||||||
currentActivity = activity;
|
currentActivity = activity;
|
||||||
currentActivity->onEnter();
|
currentActivity->onEnter();
|
||||||
|
logMemoryState("MAIN", "After onEnter");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify long press on wake-up from deep sleep
|
// Verify long press on wake-up from deep sleep
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user