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"
],
"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 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--;
}
}
}
+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.
//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 <esp_task_wdt.h>
// 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