Add UART OTA upload with A/B partition support.

Firmware buffers 200-byte chunks into 4 KiB blocks for esp_ota_write; goTool
uploads with per-block ACK flow control and larger UART buffers to avoid stalls.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-19 00:39:59 +02:00
co-authored by Cursor
parent 1ad527119d
commit 59ca269407
20 changed files with 806 additions and 101 deletions
+17 -9
View File
@@ -1,5 +1,7 @@
syntax = "proto3";
import "nanopb.proto";
package alox;
enum MessageType {
@@ -46,6 +48,8 @@ message EchoPayload {
message VersionResponse {
uint32 version = 1;
string git_hash = 2;
/** Active OTA app partition label, e.g. "ota_0" or "ota_1". */
string running_partition = 3;
}
message ClientInfo {
@@ -100,21 +104,25 @@ message EspNowUnicastTestResponse {
uint32 seq = 2;
}
// Host → device: begin UART OTA (erase inactive OTA slot; device replies OTA_STATUS).
message OtaStartPayload {
uint32 total_size = 1;
uint32 block_size = 2;
}
// Host → device: firmware chunk (up to 200 bytes); device buffers 4 KiB before flash write.
message OtaPayload {
uint32 block_id = 1;
uint32 chunk_id = 2;
bytes data = 3;
uint32 seq = 1;
bytes data = 2 [(nanopb).max_size = 200];
}
message OtaEndPayload {
uint32 status = 1;
}
// Host → device: no more payload; device flushes buffer and finalizes OTA.
message OtaEndPayload {}
message OtaStatusPayload {
uint32 status = 1;
// Device → host status (also used as ACK after each 4 KiB written).
// status: 1=preparing, 2=ready, 3=block_ack, 4=success, 5=failed
message OtaStatusPayload {
uint32 status = 1;
uint32 bytes_written = 2;
uint32 target_slot = 3;
uint32 error = 4;
}