mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2026-02-07 16:17:38 +03:00
Add watchdog resets and write buffer to Calibre Wireless mode
Apply the same stability fixes from WebSocket upload to Calibre: - Add esp_task_wdt.h include and watchdog resets throughout - Increase receive buffer from 1KB to 4KB for better throughput - Add 4KB write buffer for batched SD writes (reduces write calls) - Reset watchdog during file creation, network reads, and SD writes - Reset watchdog every 16 iterations in JSON message reading loop - Clean up write buffer on exit and error conditions
This commit is contained in:
parent
6e78a7037d
commit
de730ca130
@ -16,6 +16,45 @@
|
||||
namespace {
|
||||
constexpr uint16_t UDP_PORTS[] = {54982, 48123, 39001, 44044, 59678};
|
||||
constexpr uint16_t LOCAL_UDP_PORT = 8134; // Port to receive responses
|
||||
|
||||
// Write buffer for batched SD writes (improves throughput by reducing write calls)
|
||||
constexpr size_t WRITE_BUFFER_SIZE = 4096; // 4KB buffer
|
||||
static uint8_t writeBuffer[WRITE_BUFFER_SIZE];
|
||||
static size_t writeBufferPos = 0;
|
||||
static File* currentWriteFile = nullptr;
|
||||
|
||||
static bool flushWriteBuffer() {
|
||||
if (writeBufferPos > 0 && currentWriteFile && *currentWriteFile) {
|
||||
esp_task_wdt_reset();
|
||||
const size_t written = currentWriteFile->write(writeBuffer, writeBufferPos);
|
||||
esp_task_wdt_reset();
|
||||
if (written != writeBufferPos) {
|
||||
writeBufferPos = 0;
|
||||
return false;
|
||||
}
|
||||
writeBufferPos = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool bufferedWrite(const uint8_t* data, size_t len) {
|
||||
while (len > 0) {
|
||||
const size_t space = WRITE_BUFFER_SIZE - writeBufferPos;
|
||||
const size_t toCopy = std::min(space, len);
|
||||
|
||||
memcpy(writeBuffer + writeBufferPos, data, toCopy);
|
||||
writeBufferPos += toCopy;
|
||||
data += toCopy;
|
||||
len -= toCopy;
|
||||
|
||||
if (writeBufferPos >= WRITE_BUFFER_SIZE) {
|
||||
if (!flushWriteBuffer()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void CalibreWirelessActivity::displayTaskTrampoline(void* param) {
|
||||
@ -80,7 +119,9 @@ void CalibreWirelessActivity::onExit() {
|
||||
tcpClient.stop();
|
||||
}
|
||||
|
||||
// Close any open file to prevent corruption
|
||||
// Flush write buffer and close any open file to prevent corruption
|
||||
flushWriteBuffer();
|
||||
currentWriteFile = nullptr;
|
||||
if (currentFile) {
|
||||
Serial.printf("[%lu] [CAL] Closing open file...\n", millis());
|
||||
currentFile.flush();
|
||||
@ -374,6 +415,7 @@ bool CalibreWirelessActivity::readJsonMessage(std::string& message) {
|
||||
}
|
||||
// Read in chunks
|
||||
char buf[1024];
|
||||
int iterations = 0;
|
||||
while (available > 0) {
|
||||
int toRead = std::min(available, static_cast<int>(sizeof(buf)));
|
||||
int bytesRead = tcpClient.read(reinterpret_cast<uint8_t*>(buf), toRead);
|
||||
@ -383,6 +425,10 @@ bool CalibreWirelessActivity::readJsonMessage(std::string& message) {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
// Reset watchdog every 16 iterations to prevent timeout during large reads
|
||||
if ((++iterations & 0xF) == 0) {
|
||||
esp_task_wdt_reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -655,12 +701,18 @@ void CalibreWirelessActivity::handleSendBook(const std::string& data) {
|
||||
setState(WirelessState::RECEIVING);
|
||||
setStatus("Receiving: " + filename);
|
||||
|
||||
// Open file for writing
|
||||
// Open file for writing - reset watchdog as FAT allocation can be slow
|
||||
esp_task_wdt_reset();
|
||||
if (!SdMan.openFileForWrite("CAL", currentFilename.c_str(), currentFile)) {
|
||||
setError("Failed to create file");
|
||||
sendJsonResponse(OpCode::ERROR, "{\"message\":\"Failed to create file\"}");
|
||||
return;
|
||||
}
|
||||
esp_task_wdt_reset();
|
||||
|
||||
// Initialize write buffer
|
||||
currentWriteFile = ¤tFile;
|
||||
writeBufferPos = 0;
|
||||
|
||||
// Send OK to start receiving binary data
|
||||
sendJsonResponse(OpCode::OK, "{}");
|
||||
@ -672,11 +724,12 @@ void CalibreWirelessActivity::handleSendBook(const std::string& data) {
|
||||
// Check if recvBuffer has leftover data (binary file data that arrived with the JSON)
|
||||
if (!recvBuffer.empty()) {
|
||||
size_t toWrite = std::min(recvBuffer.size(), binaryBytesRemaining);
|
||||
size_t written = currentFile.write(reinterpret_cast<const uint8_t*>(recvBuffer.data()), toWrite);
|
||||
bytesReceived += written;
|
||||
binaryBytesRemaining -= written;
|
||||
recvBuffer = recvBuffer.substr(toWrite);
|
||||
updateRequired = true;
|
||||
if (bufferedWrite(reinterpret_cast<const uint8_t*>(recvBuffer.data()), toWrite)) {
|
||||
bytesReceived += toWrite;
|
||||
binaryBytesRemaining -= toWrite;
|
||||
recvBuffer = recvBuffer.substr(toWrite);
|
||||
updateRequired = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -708,6 +761,8 @@ void CalibreWirelessActivity::receiveBinaryData() {
|
||||
if (available == 0) {
|
||||
// Check if connection is still alive
|
||||
if (!tcpClient.connected()) {
|
||||
flushWriteBuffer();
|
||||
currentWriteFile = nullptr;
|
||||
currentFile.close();
|
||||
inBinaryMode = false;
|
||||
setError("Transfer interrupted");
|
||||
@ -715,18 +770,34 @@ void CalibreWirelessActivity::receiveBinaryData() {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t buffer[1024];
|
||||
// Use 4KB buffer for network reads
|
||||
uint8_t buffer[4096];
|
||||
const size_t toRead = std::min(sizeof(buffer), binaryBytesRemaining);
|
||||
|
||||
// Reset watchdog before network read
|
||||
esp_task_wdt_reset();
|
||||
const size_t bytesRead = tcpClient.read(buffer, toRead);
|
||||
|
||||
if (bytesRead > 0) {
|
||||
currentFile.write(buffer, bytesRead);
|
||||
// Use buffered write for better throughput
|
||||
if (!bufferedWrite(buffer, bytesRead)) {
|
||||
flushWriteBuffer();
|
||||
currentWriteFile = nullptr;
|
||||
currentFile.close();
|
||||
inBinaryMode = false;
|
||||
setError("Write error");
|
||||
return;
|
||||
}
|
||||
|
||||
bytesReceived += bytesRead;
|
||||
binaryBytesRemaining -= bytesRead;
|
||||
updateRequired = true;
|
||||
|
||||
if (binaryBytesRemaining == 0) {
|
||||
// Transfer complete
|
||||
// Transfer complete - flush remaining buffer
|
||||
esp_task_wdt_reset();
|
||||
flushWriteBuffer();
|
||||
currentWriteFile = nullptr;
|
||||
currentFile.flush();
|
||||
currentFile.close();
|
||||
inBinaryMode = false;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user