mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2026-02-08 00:27:39 +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 {
|
namespace {
|
||||||
constexpr uint16_t UDP_PORTS[] = {54982, 48123, 39001, 44044, 59678};
|
constexpr uint16_t UDP_PORTS[] = {54982, 48123, 39001, 44044, 59678};
|
||||||
constexpr uint16_t LOCAL_UDP_PORT = 8134; // Port to receive responses
|
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
|
} // namespace
|
||||||
|
|
||||||
void CalibreWirelessActivity::displayTaskTrampoline(void* param) {
|
void CalibreWirelessActivity::displayTaskTrampoline(void* param) {
|
||||||
@ -80,7 +119,9 @@ void CalibreWirelessActivity::onExit() {
|
|||||||
tcpClient.stop();
|
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) {
|
if (currentFile) {
|
||||||
Serial.printf("[%lu] [CAL] Closing open file...\n", millis());
|
Serial.printf("[%lu] [CAL] Closing open file...\n", millis());
|
||||||
currentFile.flush();
|
currentFile.flush();
|
||||||
@ -374,6 +415,7 @@ bool CalibreWirelessActivity::readJsonMessage(std::string& message) {
|
|||||||
}
|
}
|
||||||
// Read in chunks
|
// Read in chunks
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
|
int iterations = 0;
|
||||||
while (available > 0) {
|
while (available > 0) {
|
||||||
int toRead = std::min(available, static_cast<int>(sizeof(buf)));
|
int toRead = std::min(available, static_cast<int>(sizeof(buf)));
|
||||||
int bytesRead = tcpClient.read(reinterpret_cast<uint8_t*>(buf), toRead);
|
int bytesRead = tcpClient.read(reinterpret_cast<uint8_t*>(buf), toRead);
|
||||||
@ -383,6 +425,10 @@ bool CalibreWirelessActivity::readJsonMessage(std::string& message) {
|
|||||||
} else {
|
} else {
|
||||||
break;
|
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);
|
setState(WirelessState::RECEIVING);
|
||||||
setStatus("Receiving: " + filename);
|
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)) {
|
if (!SdMan.openFileForWrite("CAL", currentFilename.c_str(), currentFile)) {
|
||||||
setError("Failed to create file");
|
setError("Failed to create file");
|
||||||
sendJsonResponse(OpCode::ERROR, "{\"message\":\"Failed to create file\"}");
|
sendJsonResponse(OpCode::ERROR, "{\"message\":\"Failed to create file\"}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
esp_task_wdt_reset();
|
||||||
|
|
||||||
|
// Initialize write buffer
|
||||||
|
currentWriteFile = ¤tFile;
|
||||||
|
writeBufferPos = 0;
|
||||||
|
|
||||||
// Send OK to start receiving binary data
|
// Send OK to start receiving binary data
|
||||||
sendJsonResponse(OpCode::OK, "{}");
|
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)
|
// Check if recvBuffer has leftover data (binary file data that arrived with the JSON)
|
||||||
if (!recvBuffer.empty()) {
|
if (!recvBuffer.empty()) {
|
||||||
size_t toWrite = std::min(recvBuffer.size(), binaryBytesRemaining);
|
size_t toWrite = std::min(recvBuffer.size(), binaryBytesRemaining);
|
||||||
size_t written = currentFile.write(reinterpret_cast<const uint8_t*>(recvBuffer.data()), toWrite);
|
if (bufferedWrite(reinterpret_cast<const uint8_t*>(recvBuffer.data()), toWrite)) {
|
||||||
bytesReceived += written;
|
bytesReceived += toWrite;
|
||||||
binaryBytesRemaining -= written;
|
binaryBytesRemaining -= toWrite;
|
||||||
recvBuffer = recvBuffer.substr(toWrite);
|
recvBuffer = recvBuffer.substr(toWrite);
|
||||||
updateRequired = true;
|
updateRequired = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -708,6 +761,8 @@ void CalibreWirelessActivity::receiveBinaryData() {
|
|||||||
if (available == 0) {
|
if (available == 0) {
|
||||||
// Check if connection is still alive
|
// Check if connection is still alive
|
||||||
if (!tcpClient.connected()) {
|
if (!tcpClient.connected()) {
|
||||||
|
flushWriteBuffer();
|
||||||
|
currentWriteFile = nullptr;
|
||||||
currentFile.close();
|
currentFile.close();
|
||||||
inBinaryMode = false;
|
inBinaryMode = false;
|
||||||
setError("Transfer interrupted");
|
setError("Transfer interrupted");
|
||||||
@ -715,18 +770,34 @@ void CalibreWirelessActivity::receiveBinaryData() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t buffer[1024];
|
// Use 4KB buffer for network reads
|
||||||
|
uint8_t buffer[4096];
|
||||||
const size_t toRead = std::min(sizeof(buffer), binaryBytesRemaining);
|
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);
|
const size_t bytesRead = tcpClient.read(buffer, toRead);
|
||||||
|
|
||||||
if (bytesRead > 0) {
|
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;
|
bytesReceived += bytesRead;
|
||||||
binaryBytesRemaining -= bytesRead;
|
binaryBytesRemaining -= bytesRead;
|
||||||
updateRequired = true;
|
updateRequired = true;
|
||||||
|
|
||||||
if (binaryBytesRemaining == 0) {
|
if (binaryBytesRemaining == 0) {
|
||||||
// Transfer complete
|
// Transfer complete - flush remaining buffer
|
||||||
|
esp_task_wdt_reset();
|
||||||
|
flushWriteBuffer();
|
||||||
|
currentWriteFile = nullptr;
|
||||||
currentFile.flush();
|
currentFile.flush();
|
||||||
currentFile.close();
|
currentFile.close();
|
||||||
inBinaryMode = false;
|
inBinaryMode = false;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user