touch: OTA update no longer trips the task watchdog while it waits (#689)

otaWorkerRun streamed the image with Update.writeStream(), which reads
through Stream::timedRead: that spins without yielding until HTTPClient's
20 s timeout. The OTA runs on the core-0 tile worker, so a slow start starved
IDLE0 and the 5 s task watchdog rebooted the device: "stuck at 0%, then a
restart" on a T-Deck Plus (#689). The image is now copied by hand through an
internal 4 KB buffer, waiting with vTaskDelay and yielding after every block,
giving up after 15 s without data (the same loop as the SD download).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kaj SchittecatandClaude Opus 5.5 committed 2026-10-18 14:38:11 +02:00
1 parent 5833e00d25
commit 35f462ecc8
1 file changed
+32 -1
+32 -1
View File
@@ -34691,8 +34691,39 @@ static void otaWorkerRun(WiFiClient& client, HTTPClient& http) {
Update.onProgress([](size_t done, size_t total) {
s_ota_pct = total ? (int)((uint64_t)done * 100 / total) : 0;
});
// Copy by hand, yielding, instead of Update.writeStream(): that reads through
// Stream::timedRead, which spins without yielding until http's 20 s timeout, so a
// slow start starved IDLE0 on this core-0 worker and the 5 s task watchdog
// rebooted the device, "stuck at 0%, then a restart" (#689). Same loop as the SD
// download below: wait with vTaskDelay, give up after 15 s without data.
auto* stream = http.getStreamPtr(); // NetworkClient* on arduino 3.x (P4: C6Client behind it)
const size_t written = stream ? Update.writeStream(*stream) : 0;
size_t written = 0;
{
size_t bufsz = 4096;
uint8_t* buf = (uint8_t*)heap_caps_malloc(bufsz, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
if (!buf) { bufsz = 1024; buf = (uint8_t*)heap_caps_malloc(bufsz, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); }
unsigned long last_data = millis();
while (buf && stream && written < (size_t)len) {
const int avail = stream->available();
if (avail <= 0) {
if (!http.connected() || (millis() - last_data) > 15000) break;
vTaskDelay(pdMS_TO_TICKS(10));
continue;
}
const size_t want = ((size_t)avail > bufsz) ? bufsz : (size_t)avail;
const int n = stream->read(buf, want);
if (n <= 0) {
if ((millis() - last_data) > 15000) break;
vTaskDelay(pdMS_TO_TICKS(5));
continue;
}
last_data = millis();
if (Update.write(buf, (size_t)n) != (size_t)n) break; // flash write failed: reported below
written += (size_t)n;
vTaskDelay(1); // let IDLE0 (and Wi-Fi) run between blocks
}
if (buf) heap_caps_free(buf);
}
http.end();
if (written != (size_t)len) {
snprintf(s_ota_msg, sizeof s_ota_msg, "short read %u/%d", (unsigned)written, len);