Files
ESP32_COMM/main/relay/ota_relay.h
T
小龙虾 56f26fa0d1 feat(ota): 添加GD32 OTA转发进度追踪和重发机制
- 升级固件版本从0.2.10到0.2.11
- 新增全局变量g_relay_seq和g_relay_total_packets用于跟踪转发进度
- 实现OTA转发过程中的包重发逻辑,解决GD32 Flash缓冲区满时的问题
- 添加重试计数器,超过3次重发限制时标记为GD32错误
- 在system_status_handler中暴露转发序列号和总包数到API接口
- 优化前端UI显示,添加分阶段进度指示器(EPS32 OTA、GD32上传、GD32转发)
- 实现详细的转发进度百分比计算和状态反馈
- 移除未使用的AES解密函数以减少代码体积
- 修复注释中的标点符号错误(->替换为→)
- 更新CSS样式以支持新的进度显示需求
2026-05-31 01:45:53 +08:00

158 lines
5.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* ota_relay.h - OTA 中继核心状态机
* T2.3, T3.1 - T3.7
*/
#ifndef OTA_RELAY_H
#define OTA_RELAY_H
#include <stdint.h>
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
// T4.3: OTA 元数据结构,用于 NVS 存储
#define OTA_META_NVS_NAMESPACE "ota_meta"
#define OTA_META_NVS_KEY "meta"
typedef struct {
uint32_t total_size; // 固件总大小(字节)
uint32_t stored_size; // 当前已存储大小(字节)
uint32_t last_seq; // 最后成功存储的序列号
uint32_t chunk_count; // 预期总块数
uint8_t checksum[32]; // 固件 SHA256 校验(可选)
} ota_meta_t;
// OTA 中继状态(对应 GD32 四阶段协议)
typedef enum {
// 阶段0: 空闲
RELAY_IDLE = 0,
// 阶段1: 安全握手
RELAY_HANDSHAKE_IDLE, // 等待 HANDSHAKE_REQ
RELAY_HANDSHAKE_SENT, // 已发送 0x00 AC,等待 GD32 响应
RELAY_CHALLENGE_SENT, // 已发送 nonce_server (16B),等待响应
RELAY_CHALLENGE_RESPOND, // 已收到 GD32 握手数据包
RELAY_SESSION_KEY_SENT, // 已发送变换后的随机数,等待 0xBA C0
RELAY_AUTH_COMPLETE, // 已收到 0xBA C0,安全通道建立完成
// 阶段2: 传输准备
RELAY_SIZE_SENT, // 已发送固件大小(4B LE)
RELAY_SIZE_ACK, // 已收到 0xBA C0 + seq
// 阶段3: 数据传输
RELAY_RECEIVING, // 接收并存储固件到 Flash
RELAY_RELAY_ACTIVE, // 存储完成,开始向 GD32 转发
RELAY_PACKET_SENT, // 已发送 DATA_PACKET,等待 GD32 ACK
RELAY_PACKET_ACK_OK, // ACK 正常,继续下一包
RELAY_PACKET_ACK_RETRY, // ACK 要求重发,重新发送当前包
RELAY_RECEIVE_DONE, // 已发送 DATA_END,等待 TRANSFER_DONE
// 阶段4: 结束跳转
RELAY_TRANSFER_DONE, // 已收到 0xBA C0 + FF FF FF FF
RELAY_FINISH_SENT, // 已发送 0x0A AC,等待 GD32 确认
RELAY_DONE, // GD32 回复 0x0A AC,OTA 完成
RELAY_APP_VERIFY, // 等待 GD32 APP 启动并回复存活确认
// 错误状态
RELAY_ERROR = 0xFF
} relay_state_t;
// OTA 结果码
typedef enum {
OTA_RESULT_OK = 0,
OTA_RESULT_ERR_TIMEOUT = -1, // GD32 超时无响应
OTA_RESULT_ERR_CRC = -2, // CRC 校验失败
OTA_RESULT_ERR_AUTH = -3, // 认证失败
OTA_RESULT_ERR_STORAGE = -4, // Flash 存储错误
OTA_RESULT_ERR_GD32 = -5, // GD32 返回错误
OTA_RESULT_ERR_HEALTH = -6, // 健康状态异常中止
OTA_RESULT_ERR_USER_ABORT = -7 // 用户中止
} ota_result_t;
// 外部队列句柄(在 app_main 中创建)
extern QueueHandle_t g_ota_dispatch_queue; // 从 WiFi/BLE 到 OTA 中继
extern QueueHandle_t g_ota_result_queue; // OTA 结果到 WiFi/BLE
/**
* @brief OTA 中继任务入口,负责执行握手、认证、分包转发和结束流程。
* @param pvParameters FreeRTOS 任务参数,未使用。
*/
void ota_relay_task(void *pvParameters);
/**
* @brief 发起与 GD32 的握手流程,建立 OTA 传输前的安全会话。
* @return 操作结果码。
*/
ota_result_t ota_relay_start_handshake(void);
/**
* @brief 从 Flash 中读取已缓存固件并按协议转发给 GD32。
* @return 操作结果码。
*/
ota_result_t ota_relay_forward_firmware(void);
/**
* @brief 获取当前 OTA 中继状态机状态。
* @return 当前中继状态枚举值。
*/
relay_state_t ota_relay_get_state(void);
/**
* @brief 重置 OTA 中继状态机,清理当前状态以便重新开始流程。
*/
void ota_relay_reset(void);
/**
* @brief 向 OTA 缓存分区写入一段固件数据。
* @param offset 分区内写入偏移。
* @param data 待写入的数据指针。
* @param len 数据长度(字节)。
* @return ESP_OK 成功,其他失败。
*/
esp_err_t flash_write_chunk(uint32_t offset, const uint8_t *data, size_t len);
/**
* @brief 从 OTA 缓存分区读取一段固件数据。
* @param offset 分区内读取偏移。
* @param data 读取缓冲区指针。
* @param len 读取长度(字节)。
* @return ESP_OK 成功,其他失败。
*/
esp_err_t flash_read_chunk(uint32_t offset, uint8_t *data, size_t len);
/**
* @brief 从持久化文件中加载 OTA 元数据。
* @param meta 输出参数,加载后的元数据结构体。
* @return ESP_OK 成功,其他失败。
*/
esp_err_t meta_load(ota_meta_t *meta);
/**
* @brief 将 OTA 元数据保存到持久化文件。
* @param meta 待保存的元数据结构体。
* @return ESP_OK 成功,其他失败。
*/
esp_err_t meta_save(const ota_meta_t *meta);
/**
* @brief 更新已存储大小与最后分块序号等 OTA 进度信息。
* @param stored_size 已存储的固件大小(字节)。
* @param last_seq 最后成功的分块序号。
* @return ESP_OK 成功,其他失败。
*/
esp_err_t meta_update(uint32_t stored_size, uint32_t last_seq);
/**
* @brief 清空 OTA 元数据,通常在完成或中止后调用。
* @return ESP_OK 成功,其他失败。
*/
esp_err_t meta_clear(void);
// GD32 APP 存活标志(OTA 完成后由 APP PING 确认)
extern volatile bool g_gd32_app_alive;
// 当前中继状态(供健康监控外部访问)
extern relay_state_t g_relay_state;
extern uint32_t g_relay_seq;
extern uint32_t g_relay_total_packets;
#endif // OTA_RELAY_H