Files
ESP32_COMM/main/monitor/health_monitor.h
T
小龙虾 51c89b3065 feat(ota): 实现GD32 OTA包间背压机制,优化传输节奏控制
移除固定的包间延迟配置 `OTA_PACKET_DELAY_MS`,采用基于SPI Link v2
CREDIT背压的动态节奏控制,在SpiMaster中通过remoteCredit==0时wait/拒发
实现流量控制,提高OTA传输稳定性。

refactor(stack): 统一任务栈大小配置并添加CPU统计功能

- 在app_config.h中集中定义所有任务栈大小常量,基于实测水位优化分配
- 新增monitor/cpu_stats.cpp组件,提供1Hz FreeRTOS CPU占用采样
- 更新main.cpp中的任务创建使用新的栈大小常量
- 调整health_monitor和ota_relay等任务的栈分配

perf(ota): 改进ESP32和GD32 OTA分区预擦策略

- ESP32 OTA从边写边擦改为整分区预擦模式,避免写入时的扇区擦除阻塞
- GD32 OTA在prepare阶段进行整分区预擦,提升后续写入吞吐量
- 优化OTA协调器状态管理,修复FINALIZING状态残留问题

fix(log): 改进UDP日志发送的堆内存管理

- 当堆内存不足时记录UDP发送跳过的告警信息到ring buffer
- 降低UDP发送跳过的内存阈值从10KB到6KB
- 降低日志排水最小内存阈值从8KB到4KB

docs(readme): 更新OTA配置参数文档说明

移除已废弃的OTA_PACKET_DELAY_MS参数,更新包间节奏控制说明为
基于CREDIT背压机制的描述。
2026-07-16 01:24:12 +08:00

126 lines
4.2 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.
/*
* health_monitor.h - 系统健康监控头文件
*
* HealthMonitor 类封装健康状态管理、温度监控和 WiFi RSSI 监控。
*/
#pragma once
#include <stdint.h>
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "freertos/task.h"
#include "driver/temperature_sensor.h"
#include "esp_timer.h"
#include "app_config.h"
// T9.3: 健康状态等级
typedef enum {
SYS_NORMAL = 0, // 正常
SYS_WARNING = 1, // 警告
SYS_CRITICAL = 2, // 危险
SYS_SAFE_SHUTDOWN = 3 // 安全关机
} health_state_t;
/** @brief 健康监控模块内部状态码,用于函数返回值。 */
typedef enum {
HEALTH_MON_OK = 0, ///< 健康检查通过
HEALTH_MON_WARNING = 1, ///< 健康检查警告(可继续)
HEALTH_MON_CRITICAL = 2, ///< 健康检查危险(建议中止)
HEALTH_MON_SHUTDOWN = 3 ///< 需要安全关机
} health_status_t;
// WiFi RSSI 阈值(来自 app_config.h)
#define WIFI_RSSI_NORMAL WIFI_RSSI_WARNING ///< WiFi 信号正常阈值(别名)
/**
* @brief 系统健康监控类(单例)
*
* 封装健康状态管理、温度定时监控和 WiFi RSSI 监控。
*/
class HealthMonitor {
public:
/**
* @brief 获取 HealthMonitor 单例实例。
* @return HealthMonitor 引用。
*/
static HealthMonitor& instance();
/** @brief 初始化健康监控模块,创建内部互斥锁与基础状态。 */
void init();
/** @brief 健康监控 FreeRTOS 任务入口。 */
static void taskEntry(void *pvParameters);
/** @brief OTA 传输前执行健康检查。 */
health_status_t checkBeforeOta();
/** @brief OTA 中继转发阶段执行健康检查(跳过 WiFi 检查)。 */
health_status_t checkBeforeOtaRelay();
/** @brief 获取当前系统健康状态(线程安全)。 */
health_state_t getCurrent();
/** @brief 根据 WiFi RSSI 更新健康状态。 */
health_status_t updateFromWifiRssi(int8_t rssi);
/** @brief 获取最近一次芯片温度。 */
float getLastTemperature();
/** @brief 获取最近一次 WiFi RSSI 及其年龄。 */
bool getLastWifiRssi(int8_t *out_rssi, uint32_t *out_age_ms);
/** @brief 获取健康监控任务句柄。 */
TaskHandle_t getTaskHandle() const { return m_taskHandle; }
/**
* @brief 由 WiFi 事件回调推送连接状态(避免 HealthMonitor → WifiOta 依赖)。
* WiFi 连接/断开时由 wifi_ota 事件处理器主动调用,
* HealthMonitor 无需主动查询 WifiOta::isConnected()。
* @param connected true=已连接,false=断开。
*/
void setWifiConnected(bool connected);
private:
/** @brief 加锁读取健康状态。 */
health_state_t getState();
/** @brief 加锁设置健康状态。 */
void setState(health_state_t newState);
HealthMonitor() = default;
~HealthMonitor() = default;
HealthMonitor(const HealthMonitor&) = delete;
HealthMonitor& operator=(const HealthMonitor&) = delete;
SemaphoreHandle_t m_mutex = NULL;
temperature_sensor_handle_t m_tempHandle = NULL;
// 温度监控 esp_timer 句柄存为成员,避免任务被删除后定时器仍在运行、
// 回调继续访问 instance() 成员。
esp_timer_handle_t m_tempTimer = nullptr;
health_state_t m_healthState = SYS_NORMAL;
float m_lastTemperature = 0.0f;
int8_t m_lastWifiRssi = -127;
int64_t m_lastWifiRssiMs = 0;
TaskHandle_t m_taskHandle = NULL;
// m_wifiConnected 由 m_mutex 保护(setWifiConnected 写 / checkBeforeOta 读)。
bool m_wifiConnected = false; ///< WiFi 连接状态(由 WiFi 事件推送)
static void tempMonitorCallback(void *arg);
// RAII 锁守卫(与 SpiMaster::LockGuard 风格一致)
class LockGuard {
public:
explicit LockGuard(SemaphoreHandle_t mutex) : m_lock(mutex) {
if (m_lock) { xSemaphoreTake(m_lock, portMAX_DELAY); }
}
~LockGuard() {
if (m_lock) { xSemaphoreGive(m_lock); }
}
LockGuard(const LockGuard&) = delete;
LockGuard& operator=(const LockGuard&) = delete;
private:
SemaphoreHandle_t m_lock;
};
};