feat: 添加健康监控系统并重构代码结构

- 新增health_monitor模块,包含温度、电压、WiFi RSSI监控功能
- 移除旧的app_main.h/app_main.c和debug模块,将调试日志移动到monitor目录
- 在main.cpp中替换system_monitor_task为health_monitor_task
- 更新CMakeLists.txt依赖项,添加esp_driver_tsens和esp_driver_uart
- 修改WiFi配置参数,更新SSID和密码设置方式
- 在Python工具中修复OTA客户端重新连接逻辑
- 调整任务优先级分配,统一使用核心0以适配ESP32-C3单核架构
This commit is contained in:
小龙虾
2026-04-27 02:34:47 +08:00
parent bcfe130451
commit 7bb28cee1e
32 changed files with 177 additions and 191 deletions
+111
View File
@@ -0,0 +1,111 @@
/*
* debug_log.c - WiFi 调试日志输出实现
*
* 通过 UDP socket 发送调试日志到上位机
* 上位机需监听 <DEBUG_LOG_IP>:<DEBUG_LOG_PORT>
*/
#include <string.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_err.h"
#include "esp_netif_types.h"
#include "debug_log.h"
static const char *TAG = "DEBUG_LOG";
debug_log_level_t g_debug_log_level = DEBUG_LOG_ALL;
static int s_udp_sock = -1;
static struct sockaddr_in s_debug_addr;
static bool s_initialized = false;
// 初始化 UDP socket
esp_err_t debug_log_init(void)
{
if (s_initialized) {
return ESP_OK;
}
// 创建 UDP socket
s_udp_sock = socket(AF_INET, SOCK_DGRAM, 0);
if (s_udp_sock < 0) {
ESP_LOGE(TAG, "创建 UDP socket 失败");
return ESP_FAIL;
}
// 设置目标地址
memset(&s_debug_addr, 0, sizeof(s_debug_addr));
s_debug_addr.sin_family = AF_INET;
s_debug_addr.sin_port = htons(DEBUG_LOG_PORT);
s_debug_addr.sin_addr.s_addr = inet_addr(DEBUG_LOG_IP);
s_initialized = true;
ESP_LOGI(TAG, "调试日志已初始化,上位机 IP=%s:%d", DEBUG_LOG_IP, DEBUG_LOG_PORT);
return ESP_OK;
}
// 发送原始数据到上位机
esp_err_t debug_log_send(const uint8_t *data, size_t len)
{
if (!s_initialized || s_udp_sock < 0) {
return ESP_ERR_INVALID_STATE;
}
if (len > 1024) {
len = 1024; // 限制单次发送大小
}
int ret = sendto(s_udp_sock, data, len, 0,
(struct sockaddr *)&s_debug_addr, sizeof(s_debug_addr));
if (ret < 0) {
// 静默失败,避免影响正常流程
return ESP_FAIL;
}
return ESP_OK;
}
// 格式化日志输出
void debug_log(debug_log_level_t level, const char *tag, const char *fmt, ...)
{
if (!s_initialized) {
debug_log_init();
}
if (level > g_debug_log_level) {
return;
}
// 格式化日志头
char prefix[32];
const char *level_str;
switch (level) {
case DEBUG_LOG_ERR: level_str = "E"; break;
case DEBUG_LOG_WARN: level_str = "W"; break;
case DEBUG_LOG_INFO: level_str = "I"; break;
case DEBUG_LOG_DBG: level_str = "D"; break;
default: level_str = "?"; break;
}
snprintf(prefix, sizeof(prefix), "[%s][%s]", level_str, tag);
// 格式化消息体
va_list args;
va_start(args, fmt);
char msg[512];
vsnprintf(msg, sizeof(msg), fmt, args);
va_end(args);
// 组装完整日志帧
char log_buf[600];
int total = snprintf(log_buf, sizeof(log_buf), "%s %s\n", prefix, msg);
// 发送(末尾 \n 会被保留)
debug_log_send((const uint8_t *)log_buf, total);
}
+45
View File
@@ -0,0 +1,45 @@
/*
* debug_log.h - WiFi 调试日志输出
*
* 通过 UDP socket 将调试信息发送到上位机
* 上位机监听 <udp_ip>/<udp_port> 接收日志
*/
#ifndef DEBUG_LOG_H
#define DEBUG_LOG_H
#include <stdint.h>
#include <stdarg.h>
#include "esp_err.h"
#include "app_config.h"
// 调试日志配置(DEBUG_LOG_IP/PORT/ENABLED 已在 app_config.h 中定义)
// 日志级别
typedef enum {
DEBUG_LOG_NONE = 0,
DEBUG_LOG_ERR = 1, // 错误
DEBUG_LOG_WARN = 2, // 警告
DEBUG_LOG_INFO = 3, // 信息
DEBUG_LOG_DBG = 4, // 调试
DEBUG_LOG_ALL = 5 // 全部
} debug_log_level_t;
// 当前日志级别(运行时可改)
extern debug_log_level_t g_debug_log_level;
// 初始化调试日志系统(启动 UDP 客户端)
esp_err_t debug_log_init(void);
// 发送原始数据到上位机
esp_err_t debug_log_send(const uint8_t *data, size_t len);
// 格式化日志输出(类似 printf)
void debug_log(debug_log_level_t level, const char *tag, const char *fmt, ...);
// 宏定义方便调用
#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__)
#define DEBUG_DBG(tag, fmt, ...) debug_log(DEBUG_LOG_DBG, tag, fmt, ##__VA_ARGS__)
#endif // DEBUG_LOG_H
+118 -22
View File
@@ -1,11 +1,16 @@
/*
* health_monitor.c - 系统健康监控实现
* health_monitor.cpp - 系统健康监控
* 包含:健康状态管理 + WiFi RSSI 监控 + 温度监控 + 电压监控
*/
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp_wifi.h"
#include "esp_timer.h"
#include "esp_err.h"
#include "driver/temperature_sensor.h"
#include "health_monitor.h"
#include "debug_log.h"
@@ -13,7 +18,11 @@
health_state_t g_health_state = SYS_NORMAL;
static SemaphoreHandle_t g_health_mutex = NULL;
static temperature_sensor_handle_t s_temp_handle = NULL;
// ----------------------------------------
// 健康状态管理
// ----------------------------------------
void health_monitor_init(void)
{
g_health_mutex = xSemaphoreCreateMutex();
@@ -22,7 +31,113 @@ void health_monitor_init(void)
}
}
// 每次向 GD32 发送 DATA_PACKET 前的健康检查
health_state_t health_get_current(void)
{
health_state_t state;
if (g_health_mutex) {
xSemaphoreTake(g_health_mutex, portMAX_DELAY);
}
state = g_health_state;
if (g_health_mutex) {
xSemaphoreGive(g_health_mutex);
}
return state;
}
// ----------------------------------------
// 温度监控(定时器回调)
// ----------------------------------------
static void temp_monitor_callback(void *arg)
{
float temp = 0.0f;
esp_err_t err = temperature_sensor_get_celsius(s_temp_handle, &temp);
if (err != ESP_OK) {
DEBUG_WARN("TEMP", "读取温度失败: %s", esp_err_to_name(err));
return;
}
DEBUG_DBG("TEMP", "芯片温度: %.1f°C", temp);
if (temp >= TEMP_CRITICAL) {
g_health_state = SYS_SAFE_SHUTDOWN;
DEBUG_ERR("TEMP", "危险: 温度 %.1f°C >= %d°C,触发安全关机", temp, TEMP_CRITICAL);
} else if (temp >= TEMP_WARNING) {
if (g_health_state < SYS_WARNING) {
g_health_state = SYS_WARNING;
DEBUG_WARN("TEMP", "警告: 温度 %.1f°C >= %d°C", temp, TEMP_WARNING);
}
}
}
// ----------------------------------------
// 电压监控(启动时调用一次)
// ----------------------------------------
static void voltage_monitor_callback(void *arg)
{
float voltage = 3.30f; // ESP32-C3 无内置电压传感器,使用估算
DEBUG_DBG("VOLT", "VDD 电压: %.2fV (估算)", voltage);
if (voltage < 2.3f) {
g_health_state = SYS_SAFE_SHUTDOWN;
DEBUG_ERR("VOLT", "危险: 电压 %.2fV < 2.3V,触发安全关机", voltage);
} else if (voltage < 2.5f) {
if (g_health_state < SYS_WARNING) {
g_health_state = SYS_WARNING;
DEBUG_WARN("VOLT", "警告: 电压 %.2fV < 2.5V", voltage);
}
}
}
// ----------------------------------------
// 温度电压监控任务入口
// ----------------------------------------
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) {
DEBUG_ERR("MON", "温度传感器初始化失败: %s", esp_err_to_name(err));
} else {
ESP_ERROR_CHECK(temperature_sensor_enable(s_temp_handle));
DEBUG_INFO("MON", "温度传感器已启用 (范围 20°C ~ 80°C)");
}
// 定时器,每5秒读取一次温度
esp_timer_handle_t temp_timer;
esp_timer_create_args_t timer_args = {};
timer_args.callback = &temp_monitor_callback;
timer_args.arg = nullptr;
timer_args.name = "temp_monitor";
timer_args.dispatch_method = ESP_TIMER_TASK;
timer_args.skip_unhandled_events = false;
esp_timer_create(&timer_args, &temp_timer);
esp_timer_start_periodic(temp_timer, 5 * 1000000); // 5秒
// 启动时检查一次电压
voltage_monitor_callback(NULL);
// 每5秒打印一次健康状态
while (1) {
DEBUG_INFO("MON", "健康状态: %d, 空闲堆: %lu",
g_health_state, esp_get_free_heap_size());
vTaskDelay(pdMS_TO_TICKS(5000));
}
}
// ----------------------------------------
// 健康事件日志
// ----------------------------------------
void health_log_event(const char *event, int value)
{
DEBUG_WARN("HEALTH", "[健康日志] %s: %d", event, value);
}
// ----------------------------------------
// OTA 传输前的健康检查
// ----------------------------------------
health_status_t health_check_before_ota(void)
{
health_status_t status = HEALTH_MON_OK;
@@ -50,25 +165,6 @@ health_status_t health_check_before_ota(void)
return status;
}
health_state_t health_get_current(void)
{
health_state_t state;
if (g_health_mutex) {
xSemaphoreTake(g_health_mutex, portMAX_DELAY);
}
state = g_health_state;
if (g_health_mutex) {
xSemaphoreGive(g_health_mutex);
}
return state;
}
// 健康事件的 Flash 日志写入
void health_log_event(const char *event, int value)
{
DEBUG_WARN("HEALTH", "[健康日志] %s: %d", event, value);
}
health_status_t health_update_from_wifi_rssi(int8_t rssi)
{
if (rssi < WIFI_RSSI_CRITICAL) {
@@ -89,4 +185,4 @@ health_status_t health_update_from_wifi_rssi(int8_t rssi)
}
return HEALTH_MON_OK;
}
}
+7 -8
View File
@@ -1,8 +1,7 @@
/*
* health_monitor.h - 系统健康监控头文件
*/
#ifndef HEALTH_MONITOR_H
#define HEALTH_MONITOR_H
#pragma once
#include <stdint.h>
#include "app_config.h"
@@ -30,9 +29,9 @@ extern health_state_t g_health_state;
#define WIFI_RSSI_WEAK WIFI_RSSI_CRITICAL
// 函数声明
extern health_status_t health_check_before_ota(void);
extern void health_log_event(const char *event, int value);
extern health_state_t health_get_current(void);
extern health_status_t health_update_from_wifi_rssi(int8_t rssi);
#endif // HEALTH_MONITOR_H
void health_monitor_init(void);
void health_monitor_task(void *pvParameters);
health_status_t health_check_before_ota(void);
void health_log_event(const char *event, int value);
health_state_t health_get_current(void);
health_status_t health_update_from_wifi_rssi(int8_t rssi);