From 18f7ffe7dc365d587c2c5cace8767486b3afea7a Mon Sep 17 00:00:00 2001 From: "torok.istvan" Date: Fri, 2 Oct 2026 04:15:24 +0200 Subject: [PATCH] fix(system): enhance system stability, watchdog, and safe shutdown - Increase F9PSerialReadTask stack size to 8192 to prevent stack overflows - Add timeout to BluetoothSerial flush() to avoid infinite blocking loops - Implement Task Watchdog Timer (TWDT) for F9PSerialReadTask for auto-recovery - Add power-fail interrupt handling via GPIO 27 to safely close SD card logs - Enable hardware reset reason logging to SD card on startup --- .vscode/extensions.json | 3 +- lib/BluetoothSerial/BluetoothSerial.cpp | 7 ++- src/main.cpp | 81 +++++++++++++++++++------ 3 files changed, 70 insertions(+), 21 deletions(-) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 080e70d..a91ca8f 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -5,6 +5,7 @@ "platformio.platformio-ide" ], "unwantedRecommendations": [ - "ms-vscode.cpptools-extension-pack" + "ms-vscode.cpptools-extension-pack", + "pioarduino.pioarduino-ide" ] } diff --git a/lib/BluetoothSerial/BluetoothSerial.cpp b/lib/BluetoothSerial/BluetoothSerial.cpp index 24d83be..4a1f22b 100644 --- a/lib/BluetoothSerial/BluetoothSerial.cpp +++ b/lib/BluetoothSerial/BluetoothSerial.cpp @@ -30,7 +30,8 @@ const char * _spp_server_name = "ESP32SPP"; //#define RX_QUEUE_SIZE 512 //Original //#define TX_QUEUE_SIZE 32 -#define SPP_TX_QUEUE_TIMEOUT 1000 +// #define SPP_TX_QUEUE_TIMEOUT 1000 +#define SPP_TX_QUEUE_TIMEOUT 10 #define SPP_TX_DONE_TIMEOUT 1000 #define SPP_CONGESTED_TIMEOUT 1000 @@ -763,8 +764,10 @@ size_t BluetoothSerial::write(const uint8_t *buffer, size_t size) void BluetoothSerial::flush() { if (_spp_tx_queue != NULL){ - while(uxQueueMessagesWaiting(_spp_tx_queue) > 0){ + int timeout = 20; + while(uxQueueMessagesWaiting(_spp_tx_queue) > 0 && timeout > 0){ delay(100); + timeout--; } } } diff --git a/src/main.cpp b/src/main.cpp index 0f2029f..db0fb3e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -284,7 +284,8 @@ TaskHandle_t pinUART2TaskHandle = NULL; //Dummy task to start UART2 on core 0. volatile bool uart2pinned = false; //This variable is touched by core 0 but checked by core 1. Must be volatile. //Reduced stack size from 10,000 to 2,000 to make room for WiFi/NTRIP server capabilities -const int readTaskStackSize = 2500; +// const int readTaskStackSize = 2500; +const int readTaskStackSize = 8192; //Veremméret növelése a fagyások elkerülésére const int writeTaskStackSize = 2000; bool zedUartPassed = false; //Goes true during testing if ESP can communicate with ZED over UART @@ -292,7 +293,15 @@ bool zedUartPassed = false; //Goes true during testing if ESP can communicate wi volatile int counter = 0; long lastTime = 0; +const int ignitionPin = 27; +volatile bool powerIsFailing = false; + +void IRAM_ATTR powerFailInterrupt(){ + powerIsFailing = true; +} + #include "bluetoothSelect.h" +#include // BluetoothSerial SerialBT; BTSerialInterface *bluetoothSerial; @@ -874,6 +883,24 @@ void setup() oled.display(); } + esp_err_t wdt_result = esp_task_wdt_init(10, true); + if(wdt_result==ESP_OK){ + oled.setCursor(0,33); // Start at top-left corner + oled.println(F("WDT started ...")); + oled.display(); + } + else { + oled.setCursor(0,33); // Start at top-left corner + oled.println(F("WDT initialization error ...")); + oled.display(); + } + + pinMode(ignitionPin, INPUT_PULLUP); // Configure the ignition pin with an internal pull-up resistor + attachInterrupt(digitalPinToInterrupt(ignitionPin), powerFailInterrupt, RISING); // Attach an interrupt to the ignition pin to detect power failure + oled.setCursor(0,44); // Start at top-left corner + oled.println(F("Interrupt attached ...")); + oled.display(); + beginBoard(); beginGNSS(); @@ -927,6 +954,18 @@ void setup() void loop() { + //Külső 12V lekapcsolásának a figyelése + if(powerIsFailing){ + if(online.logging==true){ + endLogging(false, false); + } + while (1) + { + delay(1); + } + + } + int lastUpdateTimeOnOled=0; if (online.gnss == true) { @@ -1985,6 +2024,9 @@ void F9PSerialReadTask(void *e) int btConnected; //Is the RTK in a state to send Bluetooth data? int newBytesToRecord; //Size of data from GNSS + // feliratkozás a task watchdog-ra + esp_task_wdt_add(NULL); + while (true) { while (serialGNSS.available()) @@ -2179,6 +2221,9 @@ void F9PSerialReadTask(void *e) delay(1); taskYIELD(); + + // Watchdog törlése, a taszk nem fagyott le + esp_task_wdt_reset(); } } @@ -2620,25 +2665,25 @@ void beginLogging(const char *customFileName) if (startLogTime_minutes == 0) startLogTime_minutes = millis() / 1000L / 60; //Add NMEA txt message with restart reason - // char rstReason[30]; - // switch (esp_reset_reason()) - // { - // case ESP_RST_UNKNOWN: strcpy(rstReason, "ESP_RST_UNKNOWN"); break; - // case ESP_RST_POWERON : strcpy(rstReason, "ESP_RST_POWERON"); break; - // case ESP_RST_SW : strcpy(rstReason, "ESP_RST_SW"); break; - // case ESP_RST_PANIC : strcpy(rstReason, "ESP_RST_PANIC"); break; - // case ESP_RST_INT_WDT : strcpy(rstReason, "ESP_RST_INT_WDT"); break; - // case ESP_RST_TASK_WDT : strcpy(rstReason, "ESP_RST_TASK_WDT"); break; - // case ESP_RST_WDT : strcpy(rstReason, "ESP_RST_WDT"); break; - // case ESP_RST_DEEPSLEEP : strcpy(rstReason, "ESP_RST_DEEPSLEEP"); break; - // case ESP_RST_BROWNOUT : strcpy(rstReason, "ESP_RST_BROWNOUT"); break; - // case ESP_RST_SDIO : strcpy(rstReason, "ESP_RST_SDIO"); break; - // default : strcpy(rstReason, "Unknown"); - // } + char rstReason[30]; + switch (esp_reset_reason()) + { + case ESP_RST_UNKNOWN: strcpy(rstReason, "ESP_RST_UNKNOWN"); break; + case ESP_RST_POWERON : strcpy(rstReason, "ESP_RST_POWERON"); break; + case ESP_RST_SW : strcpy(rstReason, "ESP_RST_SW"); break; + case ESP_RST_PANIC : strcpy(rstReason, "ESP_RST_PANIC"); break; + case ESP_RST_INT_WDT : strcpy(rstReason, "ESP_RST_INT_WDT"); break; + case ESP_RST_TASK_WDT : strcpy(rstReason, "ESP_RST_TASK_WDT"); break; + case ESP_RST_WDT : strcpy(rstReason, "ESP_RST_WDT"); break; + case ESP_RST_DEEPSLEEP : strcpy(rstReason, "ESP_RST_DEEPSLEEP"); break; + case ESP_RST_BROWNOUT : strcpy(rstReason, "ESP_RST_BROWNOUT"); break; + case ESP_RST_SDIO : strcpy(rstReason, "ESP_RST_SDIO"); break; + default : strcpy(rstReason, "Unknown"); + } char nmeaMessage[82]; //Max NMEA sentence length is 82 - // createNMEASentence(CUSTOM_NMEA_TYPE_RESET_REASON, nmeaMessage, rstReason); //textID, buffer, text - // ubxFile->println(nmeaMessage); + createNMEASentence(CUSTOM_NMEA_TYPE_RESET_REASON, nmeaMessage, rstReason); //textID, buffer, text + ubxFile->println(nmeaMessage); //Record system firmware versions and info to log