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:
+59
-15
@@ -1,16 +1,18 @@
|
||||
/*
|
||||
* debug_log.c - WiFi 调试日志输出实现
|
||||
* debug_log.c - 调试日志输出实现
|
||||
*
|
||||
* 日志会同时写入三处:
|
||||
* 1. UART0 串口(本地串口调试)
|
||||
* 2. UDP 单播到指定上位机(独立 UDP 调试接收端可选)
|
||||
* 3. 内部环形缓冲区(供 HTTP /logs 拉取,WebUI 实际使用这一条)
|
||||
*
|
||||
* 通过 UDP socket 将调试日志发送到上位机
|
||||
* 上位机需监听 <DEBUG_LOG_IP>:<DEBUG_LOG_PORT>
|
||||
*
|
||||
* 支持双通道输出:UDP + UART0 串口
|
||||
* UART0: TX=GPIO21, RX=GPIO20, 115200 波特率
|
||||
* UDP: <DEBUG_LOG_IP>:<DEBUG_LOG_PORT>
|
||||
*
|
||||
* 时序说明:
|
||||
* esp_netif_init() 创建 tcpip 线程后才可安全使用 socket
|
||||
* 本模块在首次 debug_log_send() 时才创建 socket(延迟创建)
|
||||
* WiFi 连接前 sendto() 会失败(无路由),日志仅走 UART
|
||||
* WiFi 连接前 sendto() 会失败(无路由),日志仍可写入 UART 与 HTTP 日志缓冲
|
||||
* WiFi 连接后 UDP 立即生效,无需额外操作
|
||||
*/
|
||||
#include <string.h>
|
||||
@@ -28,10 +30,14 @@
|
||||
|
||||
static const char *TAG = "DEBUG_LOG";
|
||||
|
||||
/** @brief 当前调试日志过滤级别,运行时可动态调整。 */
|
||||
debug_log_level_t g_debug_log_level = DEBUG_LOG_ALL;
|
||||
|
||||
/** @brief UDP 调试日志 socket 句柄,首次发送时延迟创建。 */
|
||||
static int s_udp_sock = -1;
|
||||
/** @brief UDP 调试日志目标地址。 */
|
||||
static struct sockaddr_in s_debug_addr;
|
||||
/** @brief 日志模块初始化标志。 */
|
||||
static bool s_initialized = false;
|
||||
|
||||
// ============================================================
|
||||
@@ -43,9 +49,13 @@ static char s_log_ring[LOG_RING_SLOTS][LOG_RING_SIZE];
|
||||
static int s_log_ring_lens[LOG_RING_SLOTS];
|
||||
static int s_log_ring_head = 0; // 下次写入位置
|
||||
static int s_log_ring_count = 0; // 已存条数(超过 LOG_RING_SLOTS 后不再增长,覆盖旧数据)
|
||||
/** @brief 环形缓冲区互斥锁,保护多线程并发读写。 */
|
||||
static SemaphoreHandle_t s_log_ring_mutex = NULL;
|
||||
|
||||
// 获取日志缓冲区中的条数
|
||||
/**
|
||||
* @brief 获取日志缓冲区中的条数
|
||||
* @return 当前日志条数。
|
||||
*/
|
||||
int debug_log_ring_count(void)
|
||||
{
|
||||
if (!s_log_ring_mutex) return 0;
|
||||
@@ -94,7 +104,6 @@ char *debug_log_ring_drain_json(int *out_len)
|
||||
|
||||
if (i > 0) json[pos++] = ',';
|
||||
|
||||
// JSON 转义日志内容
|
||||
pos += snprintf(json + pos, buf_size - pos, "\"");
|
||||
for (int j = 0; j < len && pos < (int)buf_size - 10; j++) {
|
||||
char c = s_log_ring[idx][j];
|
||||
@@ -116,6 +125,7 @@ char *debug_log_ring_drain_json(int *out_len)
|
||||
|
||||
// 清空缓冲区
|
||||
s_log_ring_head = 0;
|
||||
/** @brief 环形缓冲区中已存储的日志条数。 */
|
||||
s_log_ring_count = 0;
|
||||
|
||||
xSemaphoreGive(s_log_ring_mutex);
|
||||
@@ -124,7 +134,11 @@ char *debug_log_ring_drain_json(int *out_len)
|
||||
return json;
|
||||
}
|
||||
|
||||
// 写入一条日志到环形缓冲区
|
||||
/**
|
||||
* @brief 写入一条日志到环形缓冲区
|
||||
* @param data
|
||||
* @param len
|
||||
*/
|
||||
static void log_ring_push(const char *data, int len)
|
||||
{
|
||||
if (!s_log_ring_mutex || len <= 0) return;
|
||||
@@ -138,6 +152,7 @@ static void log_ring_push(const char *data, int len)
|
||||
s_log_ring[s_log_ring_head][copy_len] = '\0';
|
||||
s_log_ring_lens[s_log_ring_head] = copy_len;
|
||||
|
||||
/** @brief 环形缓冲区下一个写入位置。 */
|
||||
s_log_ring_head = (s_log_ring_head + 1) % LOG_RING_SLOTS;
|
||||
if (s_log_ring_count < LOG_RING_SLOTS) s_log_ring_count++;
|
||||
|
||||
@@ -146,12 +161,16 @@ static void log_ring_push(const char *data, int len)
|
||||
|
||||
// UART0 状态
|
||||
static bool s_uart_initialized = false;
|
||||
/** @brief 调试串口使用的 UART 端口号。 */
|
||||
static uart_port_t s_uart_port = UART_NUM_0;
|
||||
|
||||
// ============================================================
|
||||
// UART0 串口调试
|
||||
// ============================================================
|
||||
|
||||
/**
|
||||
* @brief 初始化 UART0 调试串口,配置波特率和引脚映射。
|
||||
* @return ESP_OK 成功,其他失败。
|
||||
*/
|
||||
esp_err_t uart_debug_init(void)
|
||||
{
|
||||
if (s_uart_initialized) {
|
||||
@@ -187,6 +206,7 @@ esp_err_t uart_debug_init(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** @brief UART0 初始化标志。 */
|
||||
s_uart_initialized = true;
|
||||
ESP_LOGI(TAG, "UART0 调试输出已初始化 (TX=GPIO%d, RX=GPIO%d, %d baud)",
|
||||
UART_DEBUG_TX_GPIO, UART_DEBUG_RX_GPIO, UART_DEBUG_BAUD_RATE);
|
||||
@@ -194,6 +214,12 @@ esp_err_t uart_debug_init(void)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 通过 UART0 发送一段原始字节数据。
|
||||
* @param data 待发送的数据指针。
|
||||
* @param len 数据长度。
|
||||
* @return ESP_OK 成功,其他失败。
|
||||
*/
|
||||
esp_err_t uart_debug_send(const uint8_t *data, size_t len)
|
||||
{
|
||||
if (!s_uart_initialized) {
|
||||
@@ -212,7 +238,10 @@ esp_err_t uart_debug_send(const uint8_t *data, size_t len)
|
||||
// UDP 调试日志
|
||||
// ============================================================
|
||||
|
||||
// 初始化(UART 立即可用,UDP socket 延迟到首次发送时创建)
|
||||
/**
|
||||
* @brief 初始化(UART 立即可用,UDP socket 延迟到首次发送时创建)
|
||||
* @return ESP_OK 成功,其他失败。
|
||||
*/
|
||||
esp_err_t debug_log_init(void)
|
||||
{
|
||||
if (s_initialized) {
|
||||
@@ -221,7 +250,7 @@ esp_err_t debug_log_init(void)
|
||||
|
||||
uart_debug_init();
|
||||
|
||||
// 日志环形缓冲区互斥锁
|
||||
/** @brief 环形缓冲区互斥锁,保护多线程并发读写。 */
|
||||
s_log_ring_mutex = xSemaphoreCreateMutex();
|
||||
|
||||
// 目标地址:单播到上位机
|
||||
@@ -230,19 +259,24 @@ esp_err_t debug_log_init(void)
|
||||
s_debug_addr.sin_port = htons(DEBUG_LOG_PORT);
|
||||
s_debug_addr.sin_addr.s_addr = inet_addr(DEBUG_LOG_IP);
|
||||
|
||||
/** @brief 日志模块初始化标志。 */
|
||||
s_initialized = true;
|
||||
ESP_LOGI(TAG, "调试日志已初始化,上位机 %s:%d", DEBUG_LOG_IP, DEBUG_LOG_PORT);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// 延迟创建 UDP socket(首次发送时调用)
|
||||
/**
|
||||
* @brief 延迟创建 UDP socket(首次发送时调用)
|
||||
* @return
|
||||
*/
|
||||
static esp_err_t ensure_udp_socket(void)
|
||||
{
|
||||
if (s_udp_sock >= 0) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/** @brief UDP 调试日志 socket 句柄,首次发送时延迟创建。 */
|
||||
s_udp_sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s_udp_sock < 0) {
|
||||
ESP_LOGE(TAG, "创建 UDP socket 失败");
|
||||
@@ -253,7 +287,12 @@ static esp_err_t ensure_udp_socket(void)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// 发送原始数据(UDP 单播 + UART 双通道)
|
||||
/**
|
||||
* @brief 发送原始数据(UDP 单播 + UART 双通道)
|
||||
* @param data 日志数据指针。
|
||||
* @param len 数据长度。
|
||||
* @return ESP_OK 成功,其他失败。
|
||||
*/
|
||||
esp_err_t debug_log_send(const uint8_t *data, size_t len)
|
||||
{
|
||||
esp_err_t udp_ret = ESP_FAIL;
|
||||
@@ -289,7 +328,12 @@ esp_err_t debug_log_send(const uint8_t *data, size_t len)
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
// 格式化日志输出
|
||||
/**
|
||||
* @brief 格式化日志输出
|
||||
* @param level 日志级别。
|
||||
* @param tag 日志标签。
|
||||
* @param fmt 格式化字符串。
|
||||
*/
|
||||
void debug_log(debug_log_level_t level, const char *tag, const char *fmt, ...)
|
||||
{
|
||||
if (!s_initialized) {
|
||||
|
||||
+40
-11
@@ -1,10 +1,14 @@
|
||||
/*
|
||||
* debug_log.h - WiFi 调试日志输出
|
||||
* debug_log.h - 调试日志输出
|
||||
*
|
||||
* 通过 UDP socket 将调试日志发送到上位机
|
||||
* 上位机监听 <DEBUG_LOG_PORT> 接收日志
|
||||
* 当前日志会并行写入:
|
||||
* - UART0 串口
|
||||
* - UDP 单播(独立调试接收端可选)
|
||||
* - 环形缓冲区,供 HTTP /logs 拉取
|
||||
*
|
||||
* 注意:当前 tools/WebUI 日志面板走的是 HTTP /logs,
|
||||
* 不是直接监听 UDP 6666。
|
||||
*
|
||||
* 支持双通道输出:UDP + UART0 串口
|
||||
* UART0: TX=GPIO21, RX=GPIO20, 115200 波特率
|
||||
*/
|
||||
#ifndef DEBUG_LOG_H
|
||||
@@ -35,26 +39,51 @@ typedef enum {
|
||||
// 当前日志级别(运行时可改)
|
||||
extern debug_log_level_t g_debug_log_level;
|
||||
|
||||
// 初始化调试日志系统(启动 UDP 客户端 + UART0)
|
||||
/**
|
||||
* @brief 初始化日志系统,包括 UART 输出、UDP 目标和内部缓冲区。
|
||||
* @return ESP_OK 成功,其他失败。
|
||||
*/
|
||||
esp_err_t debug_log_init(void);
|
||||
|
||||
// UART0 串口调试初始化
|
||||
/**
|
||||
* @brief 初始化 UART0 调试串口。
|
||||
* @return ESP_OK 成功,其他失败。
|
||||
*/
|
||||
esp_err_t uart_debug_init(void);
|
||||
|
||||
// UART0 串口发送
|
||||
/**
|
||||
* @brief 通过 UART0 直接发送一段原始字节数据。
|
||||
* @param data 待发送的数据指针。
|
||||
* @param len 数据长度。
|
||||
* @return ESP_OK 成功,其他失败。
|
||||
*/
|
||||
esp_err_t uart_debug_send(const uint8_t *data, size_t len);
|
||||
|
||||
// 发送原始数据到上位机
|
||||
/**
|
||||
* @brief 发送原始日志数据到底层输出通道。
|
||||
* @param data 日志数据指针。
|
||||
* @param len 数据长度。
|
||||
* @return ESP_OK 成功,其他失败。
|
||||
*/
|
||||
esp_err_t debug_log_send(const uint8_t *data, size_t len);
|
||||
|
||||
// 格式化日志输出(类似 printf)
|
||||
/**
|
||||
* @brief 按日志级别与标签格式化输出一条日志。
|
||||
* @param level 日志级别。
|
||||
* @param tag 日志标签。
|
||||
* @param fmt 格式化字符串。
|
||||
*/
|
||||
void debug_log(debug_log_level_t level, const char *tag, const char *fmt, ...);
|
||||
|
||||
// 日志环形缓冲区(供 HTTP /logs 拉取)
|
||||
/**
|
||||
* @brief 获取当前环形日志缓冲区中的日志条数。
|
||||
* @return 当前日志条数。
|
||||
*/
|
||||
int debug_log_ring_count(void);
|
||||
|
||||
// 读取并清空环形日志缓冲区,返回 JSON 数组字符串,需由调用者 free。
|
||||
char *debug_log_ring_drain_json(int *out_len); // 调用者 free
|
||||
|
||||
// 宏定义方便调用
|
||||
#define DEBUG_ERR(tag, fmt, ...) debug_log(DEBUG_LOG_ERR, tag, fmt, ##__VA_ARGS__)
|
||||
#define DEBUG_WARN(tag, fmt, ...) debug_log(DEBUG_LOG_WARN, tag, fmt, ##__VA_ARGS__)
|
||||
#define DEBUG_INFO(tag, fmt, ...) debug_log(DEBUG_LOG_INFO, tag, fmt, ##__VA_ARGS__)
|
||||
|
||||
@@ -15,24 +15,36 @@
|
||||
#include "health_monitor.h"
|
||||
#include "debug_log.h"
|
||||
|
||||
/** @brief 全局健康状态,受互斥锁保护。 */
|
||||
health_state_t g_health_state = SYS_NORMAL;
|
||||
|
||||
/** @brief 健康状态互斥锁。 */
|
||||
static SemaphoreHandle_t g_health_mutex = NULL;
|
||||
/** @brief 内置温度传感器句柄。 */
|
||||
static temperature_sensor_handle_t s_temp_handle = NULL;
|
||||
/** @brief 最近一次采样的芯片温度(摄氏度)。 */
|
||||
static float s_last_temperature = 0.0f;
|
||||
/** @brief 最近一次估算的系统电压(伏特)。 */
|
||||
static float s_last_voltage = 3.30f;
|
||||
|
||||
// ----------------------------------------
|
||||
// 健康状态管理
|
||||
// ----------------------------------------
|
||||
/**
|
||||
* @brief 初始化健康监控模块,创建互斥锁和基础状态。
|
||||
*/
|
||||
void health_monitor_init(void)
|
||||
{
|
||||
/** @brief 健康状态互斥锁。 */
|
||||
g_health_mutex = xSemaphoreCreateMutex();
|
||||
if (g_health_mutex == NULL) {
|
||||
DEBUG_ERR("HEALTH", "创建健康状态互斥锁失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取当前系统健康状态。
|
||||
* @return 当前健康状态枚举值。
|
||||
*/
|
||||
health_state_t health_get_current(void)
|
||||
{
|
||||
health_state_t state;
|
||||
@@ -46,19 +58,32 @@ health_state_t health_get_current(void)
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 返回最近一次采样到的芯片温度(摄氏度)。
|
||||
* @return 最近一次温度采样值(摄氏度)。
|
||||
*/
|
||||
float health_get_last_temperature(void)
|
||||
{
|
||||
/** @brief 最近一次采样的芯片温度(摄氏度)。 */
|
||||
return s_last_temperature;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 返回最近一次记录的系统电压估算值。
|
||||
* @return 最近一次电压估算值(伏特)。
|
||||
*/
|
||||
float health_get_last_voltage(void)
|
||||
{
|
||||
/** @brief 最近一次估算的系统电压(伏特)。 */
|
||||
return s_last_voltage;
|
||||
}
|
||||
|
||||
// ----------------------------------------
|
||||
// 温度监控(定时器回调)
|
||||
// ----------------------------------------
|
||||
/**
|
||||
* @brief 温度定时回调,采样并根据阈值更新健康状态。
|
||||
* @param arg
|
||||
*/
|
||||
static void temp_monitor_callback(void *arg)
|
||||
{
|
||||
float temp = 0.0f;
|
||||
@@ -68,14 +93,17 @@ static void temp_monitor_callback(void *arg)
|
||||
return;
|
||||
}
|
||||
|
||||
/** @brief 最近一次采样的芯片温度(摄氏度)。 */
|
||||
s_last_temperature = temp;
|
||||
|
||||
if (temp >= TEMP_CRITICAL) {
|
||||
/** @brief 全局健康状态,受互斥锁保护。 */
|
||||
g_health_state = SYS_SAFE_SHUTDOWN;
|
||||
DEBUG_ERR("TEMP", "!!! 危险 !!! 温度 %.1f°C >= %d°C,触发安全关机", temp, TEMP_CRITICAL);
|
||||
DEBUG_ERR("TEMP", "健康状态变更为: SYS_SAFE_SHUTDOWN");
|
||||
} else if (temp >= TEMP_WARNING) {
|
||||
if (g_health_state < SYS_WARNING) {
|
||||
/** @brief 全局健康状态,受互斥锁保护。 */
|
||||
g_health_state = SYS_WARNING;
|
||||
DEBUG_WARN("TEMP", "警告: 温度 %.1f°C >= %d°C", temp, TEMP_WARNING);
|
||||
DEBUG_WARN("TEMP", "健康状态变更为: SYS_WARNING");
|
||||
@@ -85,18 +113,24 @@ static void temp_monitor_callback(void *arg)
|
||||
|
||||
// ----------------------------------------
|
||||
// 电压监控(启动时调用一次)
|
||||
// ----------------------------------------
|
||||
/**
|
||||
* @brief 电压定时回调,采样估算电压并根据阈值更新健康状态。
|
||||
* @param arg
|
||||
*/
|
||||
static void voltage_monitor_callback(void *arg)
|
||||
{
|
||||
float voltage = 3.30f; // ESP32-C3 无内置电压传感器,使用估算
|
||||
/** @brief 最近一次估算的系统电压(伏特)。 */
|
||||
s_last_voltage = voltage;
|
||||
|
||||
if (voltage < 2.3f) {
|
||||
/** @brief 全局健康状态,受互斥锁保护。 */
|
||||
g_health_state = SYS_SAFE_SHUTDOWN;
|
||||
DEBUG_ERR("VOLT", "!!! 危险 !!! 电压 %.2fV < 2.3V,触发安全关机", voltage);
|
||||
DEBUG_ERR("VOLT", "健康状态变更为: SYS_SAFE_SHUTDOWN");
|
||||
} else if (voltage < 2.5f) {
|
||||
if (g_health_state < SYS_WARNING) {
|
||||
/** @brief 全局健康状态,受互斥锁保护。 */
|
||||
g_health_state = SYS_WARNING;
|
||||
DEBUG_WARN("VOLT", "警告: 电压 %.2fV < 2.5V", voltage);
|
||||
DEBUG_WARN("VOLT", "健康状态变更为: SYS_WARNING");
|
||||
@@ -106,12 +140,14 @@ static void voltage_monitor_callback(void *arg)
|
||||
|
||||
// ----------------------------------------
|
||||
// 温度电压监控任务入口
|
||||
// ----------------------------------------
|
||||
/**
|
||||
* @brief 启动温度和电压监控定时器,周期性巡检系统健康。
|
||||
* @param pvParameters FreeRTOS 任务参数,未使用。
|
||||
*/
|
||||
void health_monitor_task(void *pvParameters)
|
||||
{
|
||||
DEBUG_INFO("MON", "=== 健康监控任务启动 ===");
|
||||
|
||||
// 初始化内置温度传感器(测量范围 20°C ~ 80°C)
|
||||
temperature_sensor_config_t temp_config = TEMPERATURE_SENSOR_CONFIG_DEFAULT(20, 80);
|
||||
esp_err_t err = temperature_sensor_install(&temp_config, &s_temp_handle);
|
||||
if (err != ESP_OK) {
|
||||
@@ -134,7 +170,6 @@ void health_monitor_task(void *pvParameters)
|
||||
|
||||
DEBUG_INFO("MON", "温度监控定时器已启动 (间隔 1 秒)");
|
||||
|
||||
// 启动时检查一次电压
|
||||
voltage_monitor_callback(NULL);
|
||||
|
||||
// 每1秒刷新一次估算电压
|
||||
@@ -165,7 +200,11 @@ void health_monitor_task(void *pvParameters)
|
||||
|
||||
// ----------------------------------------
|
||||
// 健康事件日志
|
||||
// ----------------------------------------
|
||||
/**
|
||||
* @brief 记录一条健康监控事件日志。
|
||||
* @param event 事件名称字符串。
|
||||
* @param value 事件关联的数值。
|
||||
*/
|
||||
void health_log_event(const char *event, int value)
|
||||
{
|
||||
DEBUG_INFO("HEALTH", "[健康事件] %s: %d", event, value);
|
||||
@@ -173,7 +212,10 @@ void health_log_event(const char *event, int value)
|
||||
|
||||
// ----------------------------------------
|
||||
// OTA 传输前的健康检查
|
||||
// ----------------------------------------
|
||||
/**
|
||||
* @brief OTA 传输前执行健康检查,决定是否允许传输。
|
||||
* @return 健康检查结果,决定是否允许 OTA。
|
||||
*/
|
||||
health_status_t health_check_before_ota(void)
|
||||
{
|
||||
health_status_t status = HEALTH_MON_OK;
|
||||
@@ -192,6 +234,7 @@ health_status_t health_check_before_ota(void)
|
||||
wifi_ap_record_t ap_info;
|
||||
if (esp_wifi_sta_get_ap_info(&ap_info) == ESP_OK) {
|
||||
if (ap_info.rssi < WIFI_RSSI_CRITICAL) {
|
||||
/** @brief 全局健康状态,受互斥锁保护。 */
|
||||
g_health_state = SYS_CRITICAL;
|
||||
DEBUG_WARN("HEALTH", "OTA 前检查: WiFi RSSI %d < %d (危险阈值)",
|
||||
ap_info.rssi, WIFI_RSSI_CRITICAL);
|
||||
@@ -212,15 +255,22 @@ health_status_t health_check_before_ota(void)
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 根据 WiFi RSSI 更新健康状态并返回检查结果。
|
||||
* @param rssi 当前 WiFi 信号强度(dBm)。
|
||||
* @return 健康检查结果。
|
||||
*/
|
||||
health_status_t health_update_from_wifi_rssi(int8_t rssi)
|
||||
{
|
||||
if (rssi < WIFI_RSSI_CRITICAL) {
|
||||
/** @brief 全局健康状态,受互斥锁保护。 */
|
||||
g_health_state = SYS_CRITICAL;
|
||||
DEBUG_WARN("HEALTH", "WiFi RSSI 危险: %d dBm < %d dBm", rssi, WIFI_RSSI_CRITICAL);
|
||||
health_log_event("WIFI危险", rssi);
|
||||
return HEALTH_MON_CRITICAL;
|
||||
} else if (rssi < WIFI_RSSI_NORMAL) {
|
||||
if (g_health_state < SYS_WARNING) {
|
||||
/** @brief 全局健康状态,受互斥锁保护。 */
|
||||
g_health_state = SYS_WARNING;
|
||||
DEBUG_WARN("HEALTH", "WiFi RSSI 警告: %d dBm < %d dBm", rssi, WIFI_RSSI_NORMAL);
|
||||
health_log_event("WIFI警告", rssi);
|
||||
@@ -229,6 +279,7 @@ health_status_t health_update_from_wifi_rssi(int8_t rssi)
|
||||
}
|
||||
|
||||
if (g_health_state == SYS_WARNING && rssi >= WIFI_RSSI_NORMAL) {
|
||||
/** @brief 全局健康状态,受互斥锁保护。 */
|
||||
g_health_state = SYS_NORMAL;
|
||||
DEBUG_INFO("HEALTH", "WiFi RSSI 恢复: %d dBm >= %d dBm", rssi, WIFI_RSSI_NORMAL);
|
||||
health_log_event("WIFI恢复", rssi);
|
||||
|
||||
@@ -28,12 +28,51 @@ extern health_state_t g_health_state;
|
||||
#define WIFI_RSSI_NORMAL WIFI_RSSI_WARNING
|
||||
#define WIFI_RSSI_WEAK WIFI_RSSI_CRITICAL
|
||||
|
||||
// 函数声明
|
||||
/**
|
||||
* @brief 初始化健康监控模块,创建内部互斥锁与基础状态。
|
||||
*/
|
||||
void health_monitor_init(void);
|
||||
|
||||
/**
|
||||
* @brief 健康监控任务入口,负责启动温度/电压定时检测并周期性巡检系统状态。
|
||||
* @param pvParameters FreeRTOS 任务参数,未使用。
|
||||
*/
|
||||
void health_monitor_task(void *pvParameters);
|
||||
|
||||
/**
|
||||
* @brief 在 OTA 传输开始前执行健康检查,返回当前是否允许传输。
|
||||
* @return 健康检查结果,决定是否允许 OTA。
|
||||
*/
|
||||
health_status_t health_check_before_ota(void);
|
||||
|
||||
/**
|
||||
* @brief 记录一条健康相关事件日志,便于故障追踪与状态回溯。
|
||||
* @param event 事件名称字符串。
|
||||
* @param value 事件关联的数值。
|
||||
*/
|
||||
void health_log_event(const char *event, int value);
|
||||
|
||||
/**
|
||||
* @brief 获取当前系统健康状态。
|
||||
* @return 当前健康状态枚举值。
|
||||
*/
|
||||
health_state_t health_get_current(void);
|
||||
|
||||
/**
|
||||
* @brief 根据最新 WiFi RSSI 更新健康状态,并返回对应健康检查结果。
|
||||
* @param rssi 当前 WiFi 信号强度(dBm)。
|
||||
* @return 健康检查结果。
|
||||
*/
|
||||
health_status_t health_update_from_wifi_rssi(int8_t rssi);
|
||||
|
||||
/**
|
||||
* @brief 获取最近一次采样到的芯片温度(摄氏度)。
|
||||
* @return 最近一次温度采样值(摄氏度)。
|
||||
*/
|
||||
float health_get_last_temperature(void);
|
||||
|
||||
/**
|
||||
* @brief 获取最近一次记录的系统电压估算值(伏特)。
|
||||
* @return 最近一次电压估算值(伏特)。
|
||||
*/
|
||||
float health_get_last_voltage(void);
|
||||
|
||||
Reference in New Issue
Block a user