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:
@@ -38,6 +38,8 @@ typedef struct _alox_EchoPayload {
|
||||
typedef struct _alox_VersionResponse {
|
||||
uint32_t version;
|
||||
pb_callback_t git_hash;
|
||||
/* * Active OTA app partition label, e.g. "ota_0" or "ota_1". */
|
||||
pb_callback_t running_partition;
|
||||
} alox_VersionResponse;
|
||||
|
||||
typedef struct _alox_ClientInfo {
|
||||
@@ -92,23 +94,30 @@ typedef struct _alox_EspNowUnicastTestResponse {
|
||||
uint32_t seq;
|
||||
} alox_EspNowUnicastTestResponse;
|
||||
|
||||
/* Host → device: begin UART OTA (erase inactive OTA slot; device replies OTA_STATUS). */
|
||||
typedef struct _alox_OtaStartPayload {
|
||||
uint32_t total_size;
|
||||
uint32_t block_size;
|
||||
} alox_OtaStartPayload;
|
||||
|
||||
/* Host → device: firmware chunk (up to 200 bytes); device buffers 4 KiB before flash write. */
|
||||
typedef PB_BYTES_ARRAY_T(200) alox_OtaPayload_data_t;
|
||||
typedef struct _alox_OtaPayload {
|
||||
uint32_t block_id;
|
||||
uint32_t chunk_id;
|
||||
pb_callback_t data;
|
||||
uint32_t seq;
|
||||
alox_OtaPayload_data_t data;
|
||||
} alox_OtaPayload;
|
||||
|
||||
/* Host → device: no more payload; device flushes buffer and finalizes OTA. */
|
||||
typedef struct _alox_OtaEndPayload {
|
||||
uint32_t status;
|
||||
char dummy_field;
|
||||
} alox_OtaEndPayload;
|
||||
|
||||
/* Device → host status (also used as ACK after each 4 KiB written).
|
||||
status: 1=preparing, 2=ready, 3=block_ack, 4=success, 5=failed */
|
||||
typedef struct _alox_OtaStatusPayload {
|
||||
uint32_t status;
|
||||
uint32_t bytes_written;
|
||||
uint32_t target_slot;
|
||||
uint32_t error;
|
||||
} alox_OtaStatusPayload;
|
||||
|
||||
typedef struct _alox_UartMessage {
|
||||
@@ -163,7 +172,7 @@ extern "C" {
|
||||
#define alox_UartMessage_init_default {_alox_MessageType_MIN, 0, {alox_Ack_init_default}}
|
||||
#define alox_Ack_init_default {0}
|
||||
#define alox_EchoPayload_init_default {{{NULL}, NULL}}
|
||||
#define alox_VersionResponse_init_default {0, {{NULL}, NULL}}
|
||||
#define alox_VersionResponse_init_default {0, {{NULL}, NULL}, {{NULL}, NULL}}
|
||||
#define alox_ClientInfo_init_default {0, 0, 0, {{NULL}, NULL}, 0, 0, 0}
|
||||
#define alox_ClientInfoResponse_init_default {{{NULL}, NULL}}
|
||||
#define alox_ClientInput_init_default {0, 0, 0, 0}
|
||||
@@ -172,14 +181,14 @@ extern "C" {
|
||||
#define alox_AccelDeadzoneResponse_init_default {0, 0, 0, 0}
|
||||
#define alox_EspNowUnicastTestRequest_init_default {0, 0}
|
||||
#define alox_EspNowUnicastTestResponse_init_default {0, 0}
|
||||
#define alox_OtaStartPayload_init_default {0, 0}
|
||||
#define alox_OtaPayload_init_default {0, 0, {{NULL}, NULL}}
|
||||
#define alox_OtaStartPayload_init_default {0}
|
||||
#define alox_OtaPayload_init_default {0, {0, {0}}}
|
||||
#define alox_OtaEndPayload_init_default {0}
|
||||
#define alox_OtaStatusPayload_init_default {0}
|
||||
#define alox_OtaStatusPayload_init_default {0, 0, 0, 0}
|
||||
#define alox_UartMessage_init_zero {_alox_MessageType_MIN, 0, {alox_Ack_init_zero}}
|
||||
#define alox_Ack_init_zero {0}
|
||||
#define alox_EchoPayload_init_zero {{{NULL}, NULL}}
|
||||
#define alox_VersionResponse_init_zero {0, {{NULL}, NULL}}
|
||||
#define alox_VersionResponse_init_zero {0, {{NULL}, NULL}, {{NULL}, NULL}}
|
||||
#define alox_ClientInfo_init_zero {0, 0, 0, {{NULL}, NULL}, 0, 0, 0}
|
||||
#define alox_ClientInfoResponse_init_zero {{{NULL}, NULL}}
|
||||
#define alox_ClientInput_init_zero {0, 0, 0, 0}
|
||||
@@ -188,15 +197,16 @@ extern "C" {
|
||||
#define alox_AccelDeadzoneResponse_init_zero {0, 0, 0, 0}
|
||||
#define alox_EspNowUnicastTestRequest_init_zero {0, 0}
|
||||
#define alox_EspNowUnicastTestResponse_init_zero {0, 0}
|
||||
#define alox_OtaStartPayload_init_zero {0, 0}
|
||||
#define alox_OtaPayload_init_zero {0, 0, {{NULL}, NULL}}
|
||||
#define alox_OtaStartPayload_init_zero {0}
|
||||
#define alox_OtaPayload_init_zero {0, {0, {0}}}
|
||||
#define alox_OtaEndPayload_init_zero {0}
|
||||
#define alox_OtaStatusPayload_init_zero {0}
|
||||
#define alox_OtaStatusPayload_init_zero {0, 0, 0, 0}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define alox_EchoPayload_data_tag 1
|
||||
#define alox_VersionResponse_version_tag 1
|
||||
#define alox_VersionResponse_git_hash_tag 2
|
||||
#define alox_VersionResponse_running_partition_tag 3
|
||||
#define alox_ClientInfo_id_tag 1
|
||||
#define alox_ClientInfo_available_tag 2
|
||||
#define alox_ClientInfo_used_tag 3
|
||||
@@ -223,12 +233,12 @@ extern "C" {
|
||||
#define alox_EspNowUnicastTestResponse_success_tag 1
|
||||
#define alox_EspNowUnicastTestResponse_seq_tag 2
|
||||
#define alox_OtaStartPayload_total_size_tag 1
|
||||
#define alox_OtaStartPayload_block_size_tag 2
|
||||
#define alox_OtaPayload_block_id_tag 1
|
||||
#define alox_OtaPayload_chunk_id_tag 2
|
||||
#define alox_OtaPayload_data_tag 3
|
||||
#define alox_OtaEndPayload_status_tag 1
|
||||
#define alox_OtaPayload_seq_tag 1
|
||||
#define alox_OtaPayload_data_tag 2
|
||||
#define alox_OtaStatusPayload_status_tag 1
|
||||
#define alox_OtaStatusPayload_bytes_written_tag 2
|
||||
#define alox_OtaStatusPayload_target_slot_tag 3
|
||||
#define alox_OtaStatusPayload_error_tag 4
|
||||
#define alox_UartMessage_type_tag 1
|
||||
#define alox_UartMessage_ack_payload_tag 2
|
||||
#define alox_UartMessage_echo_payload_tag 3
|
||||
@@ -288,7 +298,8 @@ X(a, CALLBACK, SINGULAR, BYTES, data, 1)
|
||||
|
||||
#define alox_VersionResponse_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, version, 1) \
|
||||
X(a, CALLBACK, SINGULAR, STRING, git_hash, 2)
|
||||
X(a, CALLBACK, SINGULAR, STRING, git_hash, 2) \
|
||||
X(a, CALLBACK, SINGULAR, STRING, running_partition, 3)
|
||||
#define alox_VersionResponse_CALLBACK pb_default_field_callback
|
||||
#define alox_VersionResponse_DEFAULT NULL
|
||||
|
||||
@@ -352,25 +363,26 @@ X(a, STATIC, SINGULAR, UINT32, seq, 2)
|
||||
#define alox_EspNowUnicastTestResponse_DEFAULT NULL
|
||||
|
||||
#define alox_OtaStartPayload_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, total_size, 1) \
|
||||
X(a, STATIC, SINGULAR, UINT32, block_size, 2)
|
||||
X(a, STATIC, SINGULAR, UINT32, total_size, 1)
|
||||
#define alox_OtaStartPayload_CALLBACK NULL
|
||||
#define alox_OtaStartPayload_DEFAULT NULL
|
||||
|
||||
#define alox_OtaPayload_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, block_id, 1) \
|
||||
X(a, STATIC, SINGULAR, UINT32, chunk_id, 2) \
|
||||
X(a, CALLBACK, SINGULAR, BYTES, data, 3)
|
||||
#define alox_OtaPayload_CALLBACK pb_default_field_callback
|
||||
X(a, STATIC, SINGULAR, UINT32, seq, 1) \
|
||||
X(a, STATIC, SINGULAR, BYTES, data, 2)
|
||||
#define alox_OtaPayload_CALLBACK NULL
|
||||
#define alox_OtaPayload_DEFAULT NULL
|
||||
|
||||
#define alox_OtaEndPayload_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, status, 1)
|
||||
|
||||
#define alox_OtaEndPayload_CALLBACK NULL
|
||||
#define alox_OtaEndPayload_DEFAULT NULL
|
||||
|
||||
#define alox_OtaStatusPayload_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, status, 1)
|
||||
X(a, STATIC, SINGULAR, UINT32, status, 1) \
|
||||
X(a, STATIC, SINGULAR, UINT32, bytes_written, 2) \
|
||||
X(a, STATIC, SINGULAR, UINT32, target_slot, 3) \
|
||||
X(a, STATIC, SINGULAR, UINT32, error, 4)
|
||||
#define alox_OtaStatusPayload_CALLBACK NULL
|
||||
#define alox_OtaStatusPayload_DEFAULT NULL
|
||||
|
||||
@@ -417,16 +429,16 @@ extern const pb_msgdesc_t alox_OtaStatusPayload_msg;
|
||||
/* alox_ClientInfoResponse_size depends on runtime parameters */
|
||||
/* alox_ClientInputResponse_size depends on runtime parameters */
|
||||
/* alox_OtaPayload_size depends on runtime parameters */
|
||||
#define ALOX_MAIN_PROTO_UART_MESSAGES_PB_H_MAX_SIZE alox_ClientInput_size
|
||||
#define ALOX_MAIN_PROTO_UART_MESSAGES_PB_H_MAX_SIZE alox_OtaStatusPayload_size
|
||||
#define alox_AccelDeadzoneRequest_size 16
|
||||
#define alox_AccelDeadzoneResponse_size 20
|
||||
#define alox_Ack_size 0
|
||||
#define alox_ClientInput_size 22
|
||||
#define alox_EspNowUnicastTestRequest_size 12
|
||||
#define alox_EspNowUnicastTestResponse_size 8
|
||||
#define alox_OtaEndPayload_size 6
|
||||
#define alox_OtaStartPayload_size 12
|
||||
#define alox_OtaStatusPayload_size 6
|
||||
#define alox_OtaEndPayload_size 0
|
||||
#define alox_OtaStartPayload_size 6
|
||||
#define alox_OtaStatusPayload_size 24
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
Reference in New Issue
Block a user