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
This commit is contained in:
2026-10-02 04:15:24 +02:00
parent 2f43b3e089
commit 18f7ffe7dc
3 changed files with 70 additions and 21 deletions
+2 -1
View File
@@ -5,6 +5,7 @@
"platformio.platformio-ide" "platformio.platformio-ide"
], ],
"unwantedRecommendations": [ "unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack" "ms-vscode.cpptools-extension-pack",
"pioarduino.pioarduino-ide"
] ]
} }
+5 -2
View File
@@ -30,7 +30,8 @@ const char * _spp_server_name = "ESP32SPP";
//#define RX_QUEUE_SIZE 512 //Original //#define RX_QUEUE_SIZE 512 //Original
//#define TX_QUEUE_SIZE 32 //#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_TX_DONE_TIMEOUT 1000
#define SPP_CONGESTED_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() void BluetoothSerial::flush()
{ {
if (_spp_tx_queue != NULL){ if (_spp_tx_queue != NULL){
while(uxQueueMessagesWaiting(_spp_tx_queue) > 0){ int timeout = 20;
while(uxQueueMessagesWaiting(_spp_tx_queue) > 0 && timeout > 0){
delay(100); delay(100);
timeout--;
} }
} }
} }
+63 -18
View File
@@ -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. 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 //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; const int writeTaskStackSize = 2000;
bool zedUartPassed = false; //Goes true during testing if ESP can communicate with ZED over UART 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; volatile int counter = 0;
long lastTime = 0; long lastTime = 0;
const int ignitionPin = 27;
volatile bool powerIsFailing = false;
void IRAM_ATTR powerFailInterrupt(){
powerIsFailing = true;
}
#include "bluetoothSelect.h" #include "bluetoothSelect.h"
#include <esp_task_wdt.h>
// BluetoothSerial SerialBT; // BluetoothSerial SerialBT;
BTSerialInterface *bluetoothSerial; BTSerialInterface *bluetoothSerial;
@@ -874,6 +883,24 @@ void setup()
oled.display(); 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(); beginBoard();
beginGNSS(); beginGNSS();
@@ -927,6 +954,18 @@ void setup()
void loop() 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; int lastUpdateTimeOnOled=0;
if (online.gnss == true) 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 btConnected; //Is the RTK in a state to send Bluetooth data?
int newBytesToRecord; //Size of data from GNSS int newBytesToRecord; //Size of data from GNSS
// feliratkozás a task watchdog-ra
esp_task_wdt_add(NULL);
while (true) while (true)
{ {
while (serialGNSS.available()) while (serialGNSS.available())
@@ -2179,6 +2221,9 @@ void F9PSerialReadTask(void *e)
delay(1); delay(1);
taskYIELD(); 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; if (startLogTime_minutes == 0) startLogTime_minutes = millis() / 1000L / 60;
//Add NMEA txt message with restart reason //Add NMEA txt message with restart reason
// char rstReason[30]; char rstReason[30];
// switch (esp_reset_reason()) switch (esp_reset_reason())
// { {
// case ESP_RST_UNKNOWN: strcpy(rstReason, "ESP_RST_UNKNOWN"); break; case ESP_RST_UNKNOWN: strcpy(rstReason, "ESP_RST_UNKNOWN"); break;
// case ESP_RST_POWERON : strcpy(rstReason, "ESP_RST_POWERON"); break; case ESP_RST_POWERON : strcpy(rstReason, "ESP_RST_POWERON"); break;
// case ESP_RST_SW : strcpy(rstReason, "ESP_RST_SW"); break; case ESP_RST_SW : strcpy(rstReason, "ESP_RST_SW"); break;
// case ESP_RST_PANIC : strcpy(rstReason, "ESP_RST_PANIC"); 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_INT_WDT : strcpy(rstReason, "ESP_RST_INT_WDT"); break;
// case ESP_RST_TASK_WDT : strcpy(rstReason, "ESP_RST_TASK_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_WDT : strcpy(rstReason, "ESP_RST_WDT"); break;
// case ESP_RST_DEEPSLEEP : strcpy(rstReason, "ESP_RST_DEEPSLEEP"); break; case ESP_RST_DEEPSLEEP : strcpy(rstReason, "ESP_RST_DEEPSLEEP"); break;
// case ESP_RST_BROWNOUT : strcpy(rstReason, "ESP_RST_BROWNOUT"); break; case ESP_RST_BROWNOUT : strcpy(rstReason, "ESP_RST_BROWNOUT"); break;
// case ESP_RST_SDIO : strcpy(rstReason, "ESP_RST_SDIO"); break; case ESP_RST_SDIO : strcpy(rstReason, "ESP_RST_SDIO"); break;
// default : strcpy(rstReason, "Unknown"); default : strcpy(rstReason, "Unknown");
// } }
char nmeaMessage[82]; //Max NMEA sentence length is 82 char nmeaMessage[82]; //Max NMEA sentence length is 82
// createNMEASentence(CUSTOM_NMEA_TYPE_RESET_REASON, nmeaMessage, rstReason); //textID, buffer, text createNMEASentence(CUSTOM_NMEA_TYPE_RESET_REASON, nmeaMessage, rstReason); //textID, buffer, text
// ubxFile->println(nmeaMessage); ubxFile->println(nmeaMessage);
//Record system firmware versions and info to log //Record system firmware versions and info to log