From f3f20f40c74a03c89244c4a7127d5af45af748f8 Mon Sep 17 00:00:00 2001 From: Norbert Walter Date: Sun, 1 Mar 2026 14:52:53 +0000 Subject: [PATCH] Fix crash with reboot (GwWifi + PageNavigation) --- lib/gwwifi/GwWifi.cpp | 36 ++++++++++++++++++++++------ lib/obp60task/OBP60Extensions.h | 3 +++ lib/obp60task/PageNavigation.cpp | 40 +++++++++++++++++++++++++++----- 3 files changed, 66 insertions(+), 13 deletions(-) diff --git a/lib/gwwifi/GwWifi.cpp b/lib/gwwifi/GwWifi.cpp index cd475c2..f4a81ce 100644 --- a/lib/gwwifi/GwWifi.cpp +++ b/lib/gwwifi/GwWifi.cpp @@ -132,18 +132,40 @@ void GwWifi::loop(){ { LOG_DEBUG(GwLog::LOG,"wifiClient: retry connect to %s", wifiSSID->asCString()); - // CRITICAL SECTION: WiFi-Operationen müssen serialisiert werden + // Keep locked sections short to avoid cross-core stalls/WDT. if (acquireMutex()){ - WiFi.disconnect(true); - delay(300); - esp_wifi_stop(); - delay(100); - esp_wifi_start(); + WiFi.disconnect(true); releaseMutex(); + } + else{ + LOG_DEBUG(GwLog::ERROR,"GwWifi: mutex timeout in loop (disconnect)"); + } + + delay(300); + + if (acquireMutex()){ + esp_err_t stopErr=esp_wifi_stop(); + releaseMutex(); + if (stopErr != ESP_OK){ + LOG_DEBUG(GwLog::ERROR,"GwWifi: esp_wifi_stop failed: %d",(int)stopErr); + } + } + else{ + LOG_DEBUG(GwLog::ERROR,"GwWifi: mutex timeout in loop (stop)"); + } + + delay(100); + + if (acquireMutex()){ + esp_err_t startErr=esp_wifi_start(); + releaseMutex(); + if (startErr != ESP_OK){ + LOG_DEBUG(GwLog::ERROR,"GwWifi: esp_wifi_start failed: %d",(int)startErr); + } connectInternal(); } else{ - LOG_DEBUG(GwLog::ERROR,"GwWifi: mutex timeout in loop"); + LOG_DEBUG(GwLog::ERROR,"GwWifi: mutex timeout in loop (start)"); } } } diff --git a/lib/obp60task/OBP60Extensions.h b/lib/obp60task/OBP60Extensions.h index c0d9a58..7923c75 100644 --- a/lib/obp60task/OBP60Extensions.h +++ b/lib/obp60task/OBP60Extensions.h @@ -316,6 +316,9 @@ inline void drawMonochromeBitmap( getdisplay().drawPixel(x + xx, y + yy, color); } } + if ((yy & 0x0F) == 0) { + yield(); + } } #else // E‑Paper: just hand over to driver (expects MSB‑first horizontal) diff --git a/lib/obp60task/PageNavigation.cpp b/lib/obp60task/PageNavigation.cpp index 03729e1..262bce1 100644 --- a/lib/obp60task/PageNavigation.cpp +++ b/lib/obp60task/PageNavigation.cpp @@ -394,8 +394,20 @@ bool showValues = false; // Show values HDT, SOG, DBT in navigation map int numPix = json["number_pixels"] | 0; // Read number of pixels imgWidth = json["width"] | 0; // Read width of image imgHeight = json["height"] | 0; // Read height og image + size_t requiredBytes = 0; + if (imgWidth > 0 && imgHeight > 0){ + requiredBytes = (size_t)((imgWidth + 7) / 8) * (size_t)imgHeight; + } + if (requiredBytes == 0){ + LOG_DEBUG(GwLog::ERROR,"Error PageNavigation: invalid image geometry w=%d h=%d",imgWidth,imgHeight); + return PAGE_UPDATE; + } const char* b64src = json["picture_base64"].as(); // Read picture as Base64 content + if (b64src == nullptr){ + LOG_DEBUG(GwLog::ERROR,"Error PageNavigation: picture_base64 missing"); + return PAGE_UPDATE; + } size_t b64len = strlen(b64src); // Calculate length of Base64 content // Copy Base64 content in PSRAM char* b64 = (char*) heap_caps_malloc(b64len + 1, MALLOC_CAP_SPIRAM); // Allcate PSRAM for Base64 content @@ -407,7 +419,10 @@ bool showValues = false; // Show values HDT, SOG, DBT in navigation map // Set image buffer in PSRAM //size_t imgSize = getdisplay().width() * getdisplay().height(); - size_t imgSize = numPix; // Calculate image size + size_t imgSize = (numPix > 0) ? (size_t)numPix : requiredBytes; // Calculate image size + if (imgSize < requiredBytes){ + imgSize = requiredBytes; + } uint8_t* imageData = (uint8_t*) heap_caps_malloc(imgSize, MALLOC_CAP_SPIRAM); // Allocate PSRAM for image if (!imageData) { LOG_DEBUG(GwLog::ERROR,"Error PageNavigation: PSRAM alloc image buffer failed"); @@ -417,17 +432,30 @@ bool showValues = false; // Show values HDT, SOG, DBT in navigation map // Decode Base64 content to image size_t decodedSize = 0; - decoder.decodeBase64(b64, imageData, imgSize, decodedSize); + bool decodeOk = decoder.decodeBase64(b64, imageData, imgSize, decodedSize); + if (!decodeOk || decodedSize < requiredBytes){ + LOG_DEBUG(GwLog::ERROR, + "Error PageNavigation: decode failed (ok=%d, decoded=%u, required=%u)", + decodeOk ? 1 : 0, + (unsigned int)decodedSize, + (unsigned int)requiredBytes + ); + free(b64); + free(imageData); + return PAGE_UPDATE; + } // Copy actual navigation man to ackup map imageBackupWidth = imgWidth; imageBackupHeight = imgHeight; imageBackupSize = imgSize; - if (decodedSize > 0) { - memcpy(imageBackupData, imageData, decodedSize); - imageBackupSize = decodedSize; + if (decodedSize > 0 && imageBackupData != nullptr) { + size_t backupCapacity = (size_t)GxEPD_WIDTH * (size_t)GxEPD_HEIGHT; + size_t copySize = (decodedSize > backupCapacity) ? backupCapacity : decodedSize; + memcpy(imageBackupData, imageData, copySize); + imageBackupSize = copySize; } - hasImageBackup = true; + hasImageBackup = (imageBackupData != nullptr); lostCounter = 0; // Show image (navigation map)