mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2026-02-06 23:57:39 +03:00
Merge pull request #2 from swwilshub/claude/fix-wifi-lockup-GwiXb
Fix watchdog crashes during file uploads
This commit is contained in:
commit
3f6724d6a5
@ -4,6 +4,7 @@
|
|||||||
#include <ESPmDNS.h>
|
#include <ESPmDNS.h>
|
||||||
#include <GfxRenderer.h>
|
#include <GfxRenderer.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
|
#include <esp_task_wdt.h>
|
||||||
#include <qrcode.h>
|
#include <qrcode.h>
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
@ -316,20 +317,18 @@ void CrossPointWebServerActivity::loop() {
|
|||||||
timeSinceLastHandleClient);
|
timeSinceLastHandleClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Time-based processing: handle requests for up to 50ms per loop iteration
|
// Process HTTP requests with watchdog safety
|
||||||
// This is more efficient than a fixed iteration count because:
|
// Use iteration-based approach with watchdog resets to prevent crashes
|
||||||
// 1. Processes more data when available (during uploads)
|
// Higher iteration count improves throughput during uploads
|
||||||
// 2. Returns quickly when idle (no wasted spinning)
|
constexpr int MAX_ITERATIONS = 200;
|
||||||
// 3. yield() between calls lets WiFi stack receive more data
|
for (int i = 0; i < MAX_ITERATIONS && webServer->isRunning(); i++) {
|
||||||
constexpr unsigned long TIME_BUDGET_MS = 50;
|
|
||||||
const unsigned long handleStart = millis();
|
|
||||||
|
|
||||||
while (webServer->isRunning() && (millis() - handleStart) < TIME_BUDGET_MS) {
|
|
||||||
webServer->handleClient();
|
webServer->handleClient();
|
||||||
// Yield between calls to let WiFi stack process incoming packets
|
// Yield every iteration to let WiFi stack receive more packets
|
||||||
// This is critical for throughput - without it, TCP flow control
|
|
||||||
// throttles the sender because our receive buffer fills up
|
|
||||||
yield();
|
yield();
|
||||||
|
// Reset watchdog every 50 iterations to prevent timeout during uploads
|
||||||
|
if ((i & 0x3F) == 0) { // Every 64 iterations
|
||||||
|
esp_task_wdt_reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lastHandleClientTime = millis();
|
lastHandleClientTime = millis();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -304,8 +304,9 @@ static bool uploadSuccess = false;
|
|||||||
static String uploadError = "";
|
static String uploadError = "";
|
||||||
|
|
||||||
// Upload write buffer - batches small writes into larger SD card operations
|
// Upload write buffer - batches small writes into larger SD card operations
|
||||||
// This improves throughput by reducing the number of SD write syscalls
|
// 4KB is a good balance: large enough to reduce syscall overhead, small enough
|
||||||
constexpr size_t UPLOAD_BUFFER_SIZE = 8192; // 8KB buffer
|
// to keep individual write times short and avoid watchdog issues
|
||||||
|
constexpr size_t UPLOAD_BUFFER_SIZE = 4096; // 4KB buffer
|
||||||
static uint8_t uploadBuffer[UPLOAD_BUFFER_SIZE];
|
static uint8_t uploadBuffer[UPLOAD_BUFFER_SIZE];
|
||||||
static size_t uploadBufferPos = 0;
|
static size_t uploadBufferPos = 0;
|
||||||
|
|
||||||
@ -316,10 +317,12 @@ static size_t writeCount = 0;
|
|||||||
|
|
||||||
static bool flushUploadBuffer() {
|
static bool flushUploadBuffer() {
|
||||||
if (uploadBufferPos > 0 && uploadFile) {
|
if (uploadBufferPos > 0 && uploadFile) {
|
||||||
|
esp_task_wdt_reset(); // Reset watchdog before potentially slow SD write
|
||||||
const unsigned long writeStart = millis();
|
const unsigned long writeStart = millis();
|
||||||
const size_t written = uploadFile.write(uploadBuffer, uploadBufferPos);
|
const size_t written = uploadFile.write(uploadBuffer, uploadBufferPos);
|
||||||
totalWriteTime += millis() - writeStart;
|
totalWriteTime += millis() - writeStart;
|
||||||
writeCount++;
|
writeCount++;
|
||||||
|
esp_task_wdt_reset(); // Reset watchdog after SD write
|
||||||
|
|
||||||
if (written != uploadBufferPos) {
|
if (written != uploadBufferPos) {
|
||||||
Serial.printf("[%lu] [WEB] [UPLOAD] Buffer flush failed: expected %d, wrote %d\n", millis(), uploadBufferPos,
|
Serial.printf("[%lu] [WEB] [UPLOAD] Buffer flush failed: expected %d, wrote %d\n", millis(), uploadBufferPos,
|
||||||
@ -385,12 +388,14 @@ void CrossPointWebServer::handleUpload() const {
|
|||||||
SdMan.remove(filePath.c_str());
|
SdMan.remove(filePath.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open file for writing
|
// Open file for writing - this can be slow due to FAT cluster allocation
|
||||||
|
esp_task_wdt_reset();
|
||||||
if (!SdMan.openFileForWrite("WEB", filePath, uploadFile)) {
|
if (!SdMan.openFileForWrite("WEB", filePath, uploadFile)) {
|
||||||
uploadError = "Failed to create file on SD card";
|
uploadError = "Failed to create file on SD card";
|
||||||
Serial.printf("[%lu] [WEB] [UPLOAD] FAILED to create file: %s\n", millis(), filePath.c_str());
|
Serial.printf("[%lu] [WEB] [UPLOAD] FAILED to create file: %s\n", millis(), filePath.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
esp_task_wdt_reset();
|
||||||
|
|
||||||
Serial.printf("[%lu] [WEB] [UPLOAD] File created successfully: %s\n", millis(), filePath.c_str());
|
Serial.printf("[%lu] [WEB] [UPLOAD] File created successfully: %s\n", millis(), filePath.c_str());
|
||||||
} else if (upload.status == UPLOAD_FILE_WRITE) {
|
} else if (upload.status == UPLOAD_FILE_WRITE) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user