refactor(arch): 精简架构去除样板代码并修复BLE OTA虚假ACK问题

- 移除OtaCoordinator中重复的状态查询锁操作,改为单次取值后比较
- 将GD32存储wrapper函数改为inline实现并移入头文件,删除对应的cpp实现
- HTTP路由注册改为路由表+循环注册,消除复制粘贴的URI注册代码
- OtaRelay事件分发中提取通用拒绝逻辑到commonReject helper函数
- SpiMaster中折叠加锁/无锁镜像函数,通过内部Impl实现统一路径
- HealthMonitor使用RAII LockGuard替代重复的mutex操作代码
- 修复BLE OTA中ESP32路径的虚假ACK问题,窗口边界ACK仅在实际写入时触发
- 修复BLE OTA中GD32路径的重复包ACK问题,重复包静默跳过不发送ACK
- 调整发送端首轮ACK超时从3000ms提升至5000ms,适配设备端flash写入速度
- 清理临时文件和无用的配置宏定义
- 在main.cpp中添加GD32版本探测逻辑
This commit is contained in:
小龙虾
2026-07-15 02:23:25 +08:00
parent 164855a36c
commit 5a89cec34b
25 changed files with 218 additions and 464 deletions
+28 -54
View File
@@ -33,6 +33,28 @@
#include "http_handlers.h"
// ----------------------------------------
// 文件作用域 static helper
// ----------------------------------------
/**
* @brief 清除指定 NVS 命名空间下的全部键(erase_all + commit + close)。
* 纯函数,内部不打日志,由调用方负责日志输出。
* @param ns NVS 命名空间字符串(例如 "nvs.net80211"、"phy")。
* @return ESP_OK 成功;否则返回 nvs_open 的错误码。
*/
static esp_err_t clearNvsNamespace(const char *ns)
{
nvs_handle_t h;
esp_err_t err = nvs_open(ns, NVS_READWRITE, &h);
if (err != ESP_OK) {
return err;
}
nvs_erase_all(h);
nvs_commit(h);
nvs_close(h);
return ESP_OK;
}
// ============================================================
/**
@@ -45,10 +67,6 @@ WifiOta& WifiOta::instance()
return inst;
}
/**
* @brief 预先声明:为 STA 模式配置静态 IP、网关和子网掩码。
*/
// ----------------------------------------
// STA 后台重连任务(避免在系统事件回调中调用 esp_wifi_connect 死锁)
// ----------------------------------------
@@ -150,9 +168,6 @@ void WifiOta::wifiEventHandler(void* arg, esp_event_base_t event_base,
inst.stateUnlock();
// ★ M2: 推送 WiFi 连接状态给 HealthMonitor(解耦监控层主动查询)
HealthMonitor::instance().setWifiConnected(true);
if (inst.m_staConnectedSem) {
xSemaphoreGive(inst.m_staConnectedSem);
}
break;
case WIFI_EVENT_STA_DISCONNECTED: {
@@ -298,8 +313,6 @@ esp_err_t WifiOta::initSta()
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
setStaticIp();
// ★ 冷启动时在 wifi_start 前增加延迟
// 长时间断电后首次上电,WiFi PHY 校准需要额外时间
// esp_wifi_start() 内部会触发 PHY 初始化和校准
@@ -325,8 +338,8 @@ esp_err_t WifiOta::initSta()
*/
esp_err_t WifiOta::waitStaConnected(char *ip_str, size_t ip_len)
{
SemaphoreHandle_t wait_sem = WIFI_STA_USE_STATIC_IP ? WifiOta::instance().m_staConnectedSem : WifiOta::instance().m_staGotIpSem;
const char *wait_name = WIFI_STA_USE_STATIC_IP ? "STA_CONNECTED" : "STA_GOT_IP";
SemaphoreHandle_t wait_sem = WifiOta::instance().m_staGotIpSem;
const char *wait_name = "STA_GOT_IP";
if (wait_sem == NULL) {
DEBUG_ERR("WIFI", "%s 信号量未创建", wait_name);
@@ -368,37 +381,6 @@ esp_err_t WifiOta::waitStaConnected(char *ip_str, size_t ip_len)
return ESP_ERR_TIMEOUT;
}
/**
* @brief 设置 STA 静态 IP
*/
void WifiOta::setStaticIp()
{
if (WIFI_STA_USE_STATIC_IP) {
esp_netif_t *sta_netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF");
if (sta_netif) {
DEBUG_INFO("WIFI", "STA 使用静态 IP 模式,停止 DHCP Client");
ESP_ERROR_CHECK(esp_netif_dhcpc_stop(sta_netif));
esp_netif_ip_info_t info;
memset(&info, 0, sizeof(info));
inet_pton(AF_INET, WIFI_STA_STATIC_IP, &info.ip);
inet_pton(AF_INET, WIFI_STA_STATIC_GW, &info.gw);
inet_pton(AF_INET, WIFI_STA_STATIC_NETMASK, &info.netmask);
ESP_ERROR_CHECK(esp_netif_set_ip_info(sta_netif, &info));
DEBUG_INFO("WIFI", "静态 IP 已设置: %s", WIFI_STA_STATIC_IP);
// 设置 DNS
esp_netif_dns_info_t dns_info;
memset(&dns_info, 0, sizeof(dns_info));
inet_pton(AF_INET, WIFI_STA_STATIC_DNS, &dns_info.ip.u_addr.ip4.addr);
ESP_ERROR_CHECK(esp_netif_set_dns_info(sta_netif, ESP_NETIF_DNS_MAIN, &dns_info));
DEBUG_INFO("WIFI", "DNS 已设置: %s", WIFI_STA_STATIC_DNS);
}
} else {
DEBUG_INFO("WIFI", "使用 DHCP 获取 IP");
}
}
// ----------------------------------------
// ESP32 OTA 内部函数
// 注:begin/write/finalize/abort 已抽离到 Esp32OtaCore(main/ota/esp32_ota_core.{h,cpp})
@@ -587,23 +569,16 @@ bool WifiOta::earlyInit()
// ★ 冷启动时强制清除 WiFi NVS 缓存,避免残留脏数据
// 长时间断电后 NVS 中的 WiFi 配置缓存可能不一致
if (WifiOta::instance().m_coldBoot) {
nvs_handle_t nvs_handle;
err = nvs_open("nvs.net80211", NVS_READWRITE, &nvs_handle);
// 清除 WiFi 驱动内部 NVS 缓存键
err = clearNvsNamespace("nvs.net80211");
if (err == ESP_OK) {
// 清除 WiFi 驱动内部 NVS 缓存键
nvs_erase_all(nvs_handle);
nvs_commit(nvs_handle);
nvs_close(nvs_handle);
DEBUG_DBG("WIFI", "冷启动: 已清除 WiFi NVS 缓存 (nvs.net80211)");
} else {
DEBUG_INFO("WIFI", "冷启动: 无 WiFi NVS 缓存分区,跳过清除");
}
// 同样清除 PHY 校准数据分区,强制下次全量校准
err = nvs_open("phy", NVS_READWRITE, &nvs_handle);
err = clearNvsNamespace("phy");
if (err == ESP_OK) {
nvs_erase_all(nvs_handle);
nvs_commit(nvs_handle);
nvs_close(nvs_handle);
DEBUG_DBG("WIFI", "冷启动: 已清除 PHY 校准缓存,将重新校准");
}
}
@@ -620,9 +595,8 @@ bool WifiOta::earlyInit()
}
}
WifiOta::instance().m_staConnectedSem = xSemaphoreCreateBinary();
WifiOta::instance().m_staGotIpSem = xSemaphoreCreateBinary();
if (!WifiOta::instance().m_staConnectedSem || !WifiOta::instance().m_staGotIpSem) {
if (!WifiOta::instance().m_staGotIpSem) {
DEBUG_ERR("WIFI", "创建信号量失败");
}