docs(readme): 更新调试日志与上位机通信说明

更新了 README.md 中关于调试日志与上位机通信的部分,详细说明了当
前通信架构分为两类:
1. 业务通信:HTTP 接口用于 WebUI 与 ESP32 通信
2. 调试镜像:UART0 + UDP 用于独立调试接收器

明确区分了 WebUI 使用的 HTTP 接口功能,并移除了不再需要的心跳包
说明。

refactor(health): 移除健康监控模块的备份文件

删除了 _assistant_backups 目录中的 health_monitor.cpp 和
health_monitor.h 备份文件,清理项目结构。
This commit is contained in:
小龙虾
2026-05-05 04:48:31 +08:00
parent 478e5e5a31
commit f598b9acb3
20 changed files with 955 additions and 1420 deletions
+125 -16
View File
@@ -17,21 +17,54 @@
#include "health_monitor.h"
#include "monitor/debug_log.h"
/** @brief 当前 OTA 中继状态机状态。 */
relay_state_t g_relay_state = RELAY_IDLE;
static const esp_partition_t *g_gd32_partition = NULL;
/** @brief OTA 认证会话上下文,包含会话密钥和 IV。 */
static session_ctx_t g_session_ctx;
/** @brief OTA 命令分发队列,从 WiFi/BLE 任务接收指令。 */
QueueHandle_t g_ota_dispatch_queue = NULL;
/** @brief OTA 结果回传队列,将执行结果返回给调用方。 */
QueueHandle_t g_ota_result_queue = NULL;
/**
* @brief OTA 握手阶段:向 GD32 发送握手请求并等待进入认证流程。
* @return 操作结果码。
*/
static ota_result_t send_handshake_req(void);
/**
* @brief 认证阶段:生成随机数并完成与 GD32 的双向认证。
* @return 操作结果码。
*/
static ota_result_t send_nonce_and_authenticate(void);
/**
* @brief 向 GD32 发送待升级固件的总大小。
* @param size 固件总字节数。
* @return 操作结果码。
*/
static ota_result_t send_firmware_size(uint32_t size);
/**
* @brief 从 Flash 逐包读取固件并中继转发给 GD32。
* @return 操作结果码。
*/
static ota_result_t relay_packets_from_flash(void);
/**
* @brief OTA 收尾阶段:发送结束命令并等待 GD32 确认。
* @return 操作结果码。
*/
static ota_result_t finish_ota(void);
// 从 Flash 加载元数据
/**
* @brief 从 Flash 加载元数据
* @param meta 输出参数,加载后的元数据结构体。
* @return ESP_OK 成功,其他失败。
*/
esp_err_t meta_load(ota_meta_t *meta)
{
if (!meta) return ESP_ERR_INVALID_ARG;
@@ -73,7 +106,11 @@ esp_err_t meta_load(ota_meta_t *meta)
return ESP_OK;
}
// 保存元数据到 Flash
/**
* @brief 保存元数据到 Flash
* @param meta 待保存的元数据结构体。
* @return ESP_OK 成功,其他失败。
*/
esp_err_t meta_save(const ota_meta_t *meta)
{
if (!meta) return ESP_ERR_INVALID_ARG;
@@ -98,7 +135,12 @@ esp_err_t meta_save(const ota_meta_t *meta)
return ESP_OK;
}
// 传输过程中更新元数据
/**
* @brief 传输过程中更新元数据
* @param stored_size 已存储的固件大小(字节)。
* @param last_seq 最后成功的分块序号。
* @return ESP_OK 成功,其他失败。
*/
esp_err_t meta_update(uint32_t stored_size, uint32_t last_seq)
{
ota_meta_t meta;
@@ -111,7 +153,10 @@ esp_err_t meta_update(uint32_t stored_size, uint32_t last_seq)
return meta_save(&meta);
}
// OTA 完成后或中止时清除元数据
/**
* @brief OTA 完成后或中止时清除元数据
* @return ESP_OK 成功,其他失败。
*/
esp_err_t meta_clear(void)
{
DEBUG_INFO("OTA", "清除 OTA 元数据");
@@ -119,7 +164,13 @@ esp_err_t meta_clear(void)
return meta_save(&meta);
}
// Flash 写入接口
/**
* @brief Flash 写入接口
* @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)
{
if (!g_gd32_partition) {
@@ -134,6 +185,13 @@ esp_err_t flash_write_chunk(uint32_t offset, const uint8_t *data, size_t len)
return esp_partition_write(g_gd32_partition, offset, data, 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)
{
if (!g_gd32_partition) {
@@ -148,7 +206,10 @@ esp_err_t flash_read_chunk(uint32_t offset, uint8_t *data, size_t len)
return esp_partition_read(g_gd32_partition, offset, data, len);
}
// 阶段1 - 发起与 GD32 的握手
/**
* @brief 阶段1 - 发起与 GD32 的握手
* @return 操作结果码。
*/
static ota_result_t send_handshake_req(void)
{
DEBUG_INFO("OTA", "=== 阶段1: 握手开始 ===");
@@ -160,6 +221,7 @@ static ota_result_t send_handshake_req(void)
uint8_t payload[] = {0x00, 0xAC};
frame_build(CMD_HANDSHAKE_REQ, payload, sizeof(payload), tx_frame);
/** @brief 当前 OTA 中继状态机状态。 */
g_relay_state = RELAY_HANDSHAKE_SENT;
DEBUG_INFO("OTA", "状态: RELAY_HANDSHAKE_SENT");
@@ -167,6 +229,7 @@ static ota_result_t send_handshake_req(void)
rx_frame, sizeof(rx_frame), 3000);
if (err != ESP_OK) {
DEBUG_ERR("OTA", "HANDSHAKE_REQ 失败, err=%d", err);
/** @brief 当前 OTA 中继状态机状态。 */
g_relay_state = RELAY_ERROR;
return OTA_RESULT_ERR_TIMEOUT;
}
@@ -177,7 +240,10 @@ static ota_result_t send_handshake_req(void)
return OTA_RESULT_OK;
}
// 发送随机数并与 GD32 相互认证
/**
* @brief 发送随机数并与 GD32 相互认证
* @return 操作结果码。
*/
static ota_result_t send_nonce_and_authenticate(void)
{
uint8_t tx_frame[64];
@@ -192,6 +258,7 @@ static ota_result_t send_nonce_and_authenticate(void)
DEBUG_INFO("OTA", "--- 认证步骤 1: 发送 CHALLENGE ---");
DEBUG_INFO("OTA", "发送 nonce_server (16B), timestamp=0x%08X", timestamp);
/** @brief 当前 OTA 中继状态机状态。 */
g_relay_state = RELAY_CHALLENGE_SENT;
DEBUG_INFO("OTA", "状态: RELAY_CHALLENGE_SENT");
@@ -201,10 +268,12 @@ static ota_result_t send_nonce_and_authenticate(void)
rx_frame, sizeof(rx_frame), 5000);
if (err != ESP_OK) {
DEBUG_ERR("OTA", "CHALLENGE 发送失败, err=%d", err);
/** @brief 当前 OTA 中继状态机状态。 */
g_relay_state = RELAY_ERROR;
return OTA_RESULT_ERR_TIMEOUT;
}
/** @brief 当前 OTA 中继状态机状态。 */
g_relay_state = RELAY_CHALLENGE_RESPOND;
DEBUG_INFO("OTA", "已收到 GD32 握手数据包");
DEBUG_INFO("OTA", "状态: RELAY_CHALLENGE_RESPOND");
@@ -215,6 +284,7 @@ static ota_result_t send_nonce_and_authenticate(void)
DEBUG_INFO("OTA", "--- 认证步骤 2: 发送 SESSION_KEY ---");
DEBUG_INFO("OTA", "发送变换后的随机数 (16B)");
/** @brief 当前 OTA 中继状态机状态。 */
g_relay_state = RELAY_SESSION_KEY_SENT;
DEBUG_INFO("OTA", "状态: RELAY_SESSION_KEY_SENT");
@@ -223,10 +293,12 @@ static ota_result_t send_nonce_and_authenticate(void)
rx_frame, sizeof(rx_frame), 3000);
if (err2 != ESP_OK) {
DEBUG_ERR("OTA", "SESSION_KEY 发送失败, err=%d", err2);
/** @brief 当前 OTA 中继状态机状态。 */
g_relay_state = RELAY_ERROR;
return OTA_RESULT_ERR_TIMEOUT;
}
/** @brief 当前 OTA 中继状态机状态。 */
g_relay_state = RELAY_AUTH_COMPLETE;
DEBUG_INFO("OTA", "状态: RELAY_AUTH_COMPLETE");
DEBUG_INFO("OTA", "=== 阶段1 认证完成: 安全通道已建立 ===");
@@ -237,7 +309,11 @@ static ota_result_t send_nonce_and_authenticate(void)
return OTA_RESULT_OK;
}
// 向 GD32 发送固件总大小
/**
* @brief 向 GD32 发送固件总大小
* @param size 固件总字节数。
* @return 操作结果码。
*/
static ota_result_t send_firmware_size(uint32_t size)
{
uint8_t tx_frame[32];
@@ -252,6 +328,7 @@ static ota_result_t send_firmware_size(uint32_t size)
size_payload[2] = (uint8_t)((size >> 16) & 0xFF);
size_payload[3] = (uint8_t)((size >> 24) & 0xFF);
/** @brief 当前 OTA 中继状态机状态。 */
g_relay_state = RELAY_SIZE_SENT;
DEBUG_INFO("OTA", "状态: RELAY_SIZE_SENT");
@@ -260,18 +337,23 @@ static ota_result_t send_firmware_size(uint32_t size)
rx_frame, sizeof(rx_frame), 3000);
if (err != ESP_OK) {
DEBUG_ERR("OTA", "SEND_SIZE 失败, err=%d", err);
/** @brief 当前 OTA 中继状态机状态。 */
g_relay_state = RELAY_ERROR;
return OTA_RESULT_ERR_TIMEOUT;
}
DEBUG_INFO("OTA", "大小已发送: %u 字节,等待 GD32 确认...", size);
/** @brief 当前 OTA 中继状态机状态。 */
g_relay_state = RELAY_SIZE_ACK;
DEBUG_INFO("OTA", "状态: RELAY_SIZE_ACK");
return OTA_RESULT_OK;
}
// 从 Flash 向 GD32 转发存储的固件(48B/包)
/**
* @brief 从 Flash 向 GD32 转发存储的固件(48B/包)
* @return 操作结果码。
*/
static ota_result_t relay_packets_from_flash(void)
{
DEBUG_INFO("OTA", "=== 阶段3: 从 Flash 转发固件 ===");
@@ -290,10 +372,10 @@ static ota_result_t relay_packets_from_flash(void)
DEBUG_INFO("OTA", "总包数: %u, 每包 48 字节", total_packets);
DEBUG_INFO("OTA", "状态: RELAY_RELAY_ACTIVE");
/** @brief 当前 OTA 中继状态机状态。 */
g_relay_state = RELAY_RELAY_ACTIVE;
for (uint32_t seq = 0; seq < total_packets; seq++) {
// 发送每个包前检查健康状态
health_status_t health = health_check_before_ota();
if (health == HEALTH_MON_SHUTDOWN || health == HEALTH_MON_CRITICAL) {
DEBUG_ERR("OTA", "健康检查危险,中止 OTA");
@@ -318,6 +400,7 @@ static ota_result_t relay_packets_from_flash(void)
tx_buf[2 + chunk_size] = (uint8_t)(crc & 0xFF);
tx_buf[2 + chunk_size + 1] = (uint8_t)((crc >> 8) & 0xFF);
/** @brief 当前 OTA 中继状态机状态。 */
g_relay_state = RELAY_PACKET_SENT;
uint8_t cmd = (seq == total_packets - 1) ? CMD_DATA_END : CMD_DATA_PACKET;
@@ -331,6 +414,7 @@ static ota_result_t relay_packets_from_flash(void)
}
flash_offset += chunk_size;
/** @brief 当前 OTA 中继状态机状态。 */
g_relay_state = RELAY_PACKET_ACK_OK;
// 每 10% 记录一次进度
@@ -341,12 +425,16 @@ static ota_result_t relay_packets_from_flash(void)
}
}
/** @brief 当前 OTA 中继状态机状态。 */
g_relay_state = RELAY_RECEIVE_DONE;
DEBUG_INFO("OTA", "状态: RELAY_RECEIVE_DONE");
return result;
}
// 结束 OTA - 发送 0x0A AC 并清理
/**
* @brief 结束 OTA - 发送 0x0A AC 并清理
* @return 操作结果码。
*/
static ota_result_t finish_ota(void)
{
DEBUG_INFO("OTA", "=== 阶段4: 结束 OTA ===");
@@ -358,6 +446,7 @@ static ota_result_t finish_ota(void)
uint8_t payload[] = {0x0A, 0xAC};
frame_build(CMD_FINISH_OTA, payload, sizeof(payload), tx_frame);
/** @brief 当前 OTA 中继状态机状态。 */
g_relay_state = RELAY_FINISH_SENT;
DEBUG_INFO("OTA", "状态: RELAY_FINISH_SENT");
@@ -365,6 +454,7 @@ static ota_result_t finish_ota(void)
rx_frame, sizeof(rx_frame), 5000);
if (err != ESP_OK) {
DEBUG_ERR("OTA", "FINISH_OTA 失败, err=%d", err);
/** @brief 当前 OTA 中继状态机状态。 */
g_relay_state = RELAY_ERROR;
return OTA_RESULT_ERR_TIMEOUT;
}
@@ -374,6 +464,7 @@ static ota_result_t finish_ota(void)
session_key_clear(&g_session_ctx);
memset(&g_session_ctx, 0, sizeof(session_ctx_t));
/** @brief 当前 OTA 中继状态机状态。 */
g_relay_state = RELAY_DONE;
DEBUG_INFO("OTA", "状态: RELAY_DONE");
DEBUG_INFO("OTA", "=== OTA 完成 ===");
@@ -383,7 +474,10 @@ static ota_result_t finish_ota(void)
return OTA_RESULT_OK;
}
// 启动完整 OTA 流程的主入口
/**
* @brief 启动完整 OTA 流程的主入口
* @return 操作结果码。
*/
ota_result_t ota_relay_start_handshake(void)
{
ota_result_t res;
@@ -407,7 +501,10 @@ ota_result_t ota_relay_start_handshake(void)
return res;
}
// 从 Flash 向 GD32 转发固件
/**
* @brief 从 Flash 向 GD32 转发固件
* @return 操作结果码。
*/
ota_result_t ota_relay_forward_firmware(void)
{
ota_meta_t meta;
@@ -435,25 +532,37 @@ ota_result_t ota_relay_forward_firmware(void)
return res;
}
// 获取当前状态
/**
* @brief 获取当前状态
* @return 当前中继状态枚举值。
*/
relay_state_t ota_relay_get_state(void)
{
/** @brief 当前 OTA 中继状态机状态。 */
return g_relay_state;
}
// 重置状态机
/**
* @brief 重置状态机
*/
void ota_relay_reset(void)
{
/** @brief 当前 OTA 中继状态机状态。 */
g_relay_state = RELAY_IDLE;
session_key_clear(&g_session_ctx);
}
// OTA 中继 FreeRTOS 任务
/**
* @brief OTA 中继 FreeRTOS 任务
* @param pvParameters FreeRTOS 任务参数,未使用。
*/
void ota_relay_task(void *pvParameters)
{
DEBUG_INFO("OTA", "OTA 中继任务启动");
/** @brief OTA 命令分发队列,从 WiFi/BLE 任务接收指令。 */
g_ota_dispatch_queue = xQueueCreate(4, sizeof(uint32_t));
/** @brief OTA 结果回传队列,将执行结果返回给调用方。 */
g_ota_result_queue = xQueueCreate(4, sizeof(uint32_t));
uint32_t msg;
+57 -7
View File
@@ -70,29 +70,79 @@ typedef enum {
extern QueueHandle_t g_ota_dispatch_queue; // 从 WiFi/BLE 到 OTA 中继
extern QueueHandle_t g_ota_result_queue; // OTA 结果到 WiFi/BLE
// OTA 中继任务入口
/**
* @brief OTA 中继任务入口,负责执行握手、认证、分包转发和结束流程。
* @param pvParameters FreeRTOS 任务参数,未使用。
*/
void ota_relay_task(void *pvParameters);
// T2.3: 发起与 GD32 的握手
/**
* @brief 发起与 GD32 的握手流程,建立 OTA 传输前的安全会话。
* @return 操作结果码。
*/
ota_result_t ota_relay_start_handshake(void);
// T3.4: 从 Flash 向 GD32 转发存储的固件(48B/包)
/**
* @brief 从 Flash 中读取已缓存固件并按协议转发给 GD32。
* @return 操作结果码。
*/
ota_result_t ota_relay_forward_firmware(void);
// T3.7: 获取当前中继状态
/**
* @brief 获取当前 OTA 中继状态机状态。
* @return 当前中继状态枚举值。
*/
relay_state_t ota_relay_get_state(void);
// T3.7: 重置中继状态机
/**
* @brief 重置 OTA 中继状态机,清理当前状态以便重新开始流程。
*/
void ota_relay_reset(void);
// T4.2: Flash 写入接口
/**
* @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);
// T3.3: 元数据文件管理
/**
* @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);
// 当前中继状态(供健康监控外部访问)