refactor(ota): 移除ESP32 OTA架构中的高危设计问题并优化状态管理

- 移除OtaRelay职责过载问题,将状态查询统一收口到OtaCoordinator::getSnapshot()
- 新增OtaSnapshot结构体,一次性获取完整的OTA系统状态快照,避免分散读取
- 将GD32 APP探测逻辑从system_status_handler中分离,提供独立的/system/probe端点
- 修复并发安全隐患,确保processEvent()读取relayState时持有锁保护
- 优化SPI通信相关代码结构,提升系统稳定性

BREAKING CHANGE: 移除了原有的分散状态查询接口,统一使用快照方式获取状态
This commit is contained in:
小龙虾
2026-06-23 00:05:56 +08:00
parent 1491e9a3de
commit 7a41eac526
11 changed files with 236 additions and 189 deletions
+37
View File
@@ -123,6 +123,18 @@ void OtaRelay::getGd32Version(gd32_version_t *out)
*out = gd32Version;
}
RelaySnapshot OtaRelay::getSnapshot()
{
StateLockGuard lock;
RelaySnapshot s;
s.state = relayState;
s.seq = relaySeq;
s.total_packets = relayTotalPackets;
s.gd32_app_alive = gd32AppAlive;
s.version = gd32Version;
return s;
}
void OtaRelay::setState(relay_state_t s)
{
StateLockGuard lock;
@@ -1241,6 +1253,31 @@ void OtaRelay::taskEntry(void *pvParameters)
return;
}
// ★ 启动时初始 GD32 探测:读取 GD32 APP 版本号与存活状态
// GD32 APP 启动需要一定时间,给其 3 秒准备窗口后发起探测
{
DEBUG_INFO("OTA", "启动初始 GD32 探测...");
vTaskDelay(pdMS_TO_TICKS(3000)); // 等待 GD32 APP 就绪
uint32_t uptime = 0;
gd32_version_t ping_ver = {};
esp_err_t ping_err = SpiMaster::instance().appPing(2000, &uptime, &ping_ver);
if (ping_err == ESP_OK) {
StateLockGuard lock;
gd32AppAlive = true;
gd32Version = ping_ver;
DEBUG_INFO("OTA", "启动 GD32 探测成功: uptime=%" PRIu32 "s, "
"APP=v%d.%d.%d.%d, BOOT=v%d.%d.%d.%d",
uptime,
ping_ver.app_major, ping_ver.app_minor,
ping_ver.app_patch, ping_ver.app_build,
ping_ver.boot_major, ping_ver.boot_minor,
ping_ver.boot_patch, ping_ver.boot_build);
} else {
DEBUG_WARN("OTA", "启动 GD32 探测失败: %s (GD32 可能未就绪)",
esp_err_to_name(ping_err));
}
}
while (1) {
uint32_t msg = 0;
BaseType_t ret = xQueueReceive(dispatchQueue, &msg, portMAX_DELAY);