/* * Copyright (c) 2006-2026, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2026-03-20 RuoFeng first version */ /*********************↓ define ↓************************/ #define DBG_TAG "guard" #define DBG_LVL DBG_LOG /* Guard配置 */ #define GUARD_THREAD_STACK_SIZE 1024 #define GUARD_THREAD_PRIORITY 15 /* 低优先级,不影响业务 */ #define GUARD_CHECK_INTERVAL 1000 /* 检查间隔1秒 */ /* 网络监控配置 */ #define NET_CHECK_INTERVAL 60 /* 每60秒检查一次网络 */ #define NET_FAILURE_LIMIT 60 /* 连续失败60次触发重启(60分钟) */ /*********************↑ define ↑************************/ /*********************↓ include ↓************************/ #include #include #include "ym310_mqtt.h" #include "ecode.h" /*********************↑ include ↑************************/ /*********************↓ extern ↓************************/ extern void Recode_e_code(ecode_list code, uint16_t para, char *detail); extern uint8_t g_work_state; /*********************↑ extern ↑************************/ /********************↓ static variables ↓***********************/ static rt_thread_t s_guard_thread = RT_NULL; /* 网络监控状态 */ static struct { rt_uint32_t consecutive_failures; /* 连续失败次数 */ rt_uint32_t check_counter; /* 检查计数器 */ rt_uint32_t last_connected_tick; /* 最后连接成功时间 */ } s_net_monitor = {0}; /* 重启统计 */ static struct { rt_uint32_t total_reboots; char last_reason[32]; } s_reboot_stats = {0}; /********************↑ static variables ↑***********************/ /********************↓ static functions ↓***********************/ /** * 执行重启操作 */ static void guard_do_reboot(const char *reason) { // rt_base_t level; if(g_work_state == 1) { return ; } /* 记录重启信息 */ // level = rt_hw_interrupt_disable(); s_reboot_stats.total_reboots++; rt_strncpy(s_reboot_stats.last_reason, reason, sizeof(s_reboot_stats.last_reason) - 1); // level = rt_hw_interrupt_enable(level); /* 记录异常事件 */ Recode_e_code(e_GUARD_NET, s_net_monitor.consecutive_failures, (char *)reason); /* 输出重启日志 */ LOG_E("========================================="); LOG_E("GUARD REBOOT"); LOG_E("Reason: %s", reason); LOG_E("Net failures: %d", s_net_monitor.consecutive_failures); LOG_E("Total reboots: %d", s_reboot_stats.total_reboots); LOG_E("========================================="); rt_thread_mdelay(500); /* 等待日志输出 */ /* 执行系统重启 */ rt_hw_cpu_reset(); } /** * 网络连接检查 */ static void guard_check_network(void) { rt_bool_t connected; /* 每60秒检查一次 */ s_net_monitor.check_counter++; if (s_net_monitor.check_counter < NET_CHECK_INTERVAL) { return; } s_net_monitor.check_counter = 0; /* 检查网络连接状态 */ connected = ym310_mqtt_is_connected(0); if (connected) { /* 连接成功,重置计数器 */ if (s_net_monitor.consecutive_failures > 0) { LOG_I("Network restored after %d failures", s_net_monitor.consecutive_failures); s_net_monitor.consecutive_failures = 0; s_net_monitor.last_connected_tick = rt_tick_get(); } } else { /* 达到失败阈值,触发重启 */ if (s_net_monitor.consecutive_failures >= NET_FAILURE_LIMIT) { LOG_E("Network failure threshold reached! System reboot..."); guard_do_reboot("network timeout"); } else { /* 连接失败,累加计数 */ s_net_monitor.consecutive_failures++; LOG_W("Network check failed (%d/%d)", s_net_monitor.consecutive_failures, NET_FAILURE_LIMIT); } } } /** * 监控主循环 */ static void guard_thread_entry(void *param) { // LOG_I("Guard monitor started"); while (1) { /* 执行网络监控 */ guard_check_network(); /* 休眠1秒 */ rt_thread_mdelay(GUARD_CHECK_INTERVAL); } } /********************↑ static functions ↑***********************/ /********************↓ 初始化/退出函数 ↓***********************/ /** * 初始化Guard监控模块 */ static int guard_init(void) { // LOG_I("Initializing guard monitor..."); /* 初始化网络监控状态 */ rt_memset(&s_net_monitor, 0, sizeof(s_net_monitor)); s_net_monitor.last_connected_tick = rt_tick_get(); /* 创建监控线程 */ s_guard_thread = rt_thread_create("guard", guard_thread_entry, RT_NULL, GUARD_THREAD_STACK_SIZE, GUARD_THREAD_PRIORITY, 10); if (s_guard_thread == RT_NULL) { LOG_E("Failed to create guard thread"); return -RT_ERROR; } rt_thread_startup(s_guard_thread); // LOG_I("Guard monitor ready (net threshold: %d failures)", NET_FAILURE_LIMIT); return RT_EOK; } /** * 自动初始化(在系统启动后自动运行) */ INIT_APP_EXPORT(guard_init); /********************↑ 初始化/退出函数 ↑***********************/ #ifdef RT_USING_FINSH #include /** * 查看Guard状态(调试用) */ static void guard_status(int argc, char **argv) { rt_uint32_t uptime = rt_tick_get() * 1000 / RT_TICK_PER_SECOND; rt_uint32_t hours = uptime / 3600000; rt_uint32_t mins = (uptime % 3600000) / 60000; rt_kprintf("\n========== GUARD STATUS ==========\n"); rt_kprintf("Uptime: %dh %dm\n", hours, mins); rt_kprintf("Net failures: %d/%d\n", s_net_monitor.consecutive_failures, NET_FAILURE_LIMIT); rt_kprintf("Total reboots: %d\n", s_reboot_stats.total_reboots); if (s_reboot_stats.total_reboots > 0) { rt_kprintf("Last reboot: %s\n", s_reboot_stats.last_reason); } rt_kprintf("==================================\n"); } FINSH_FUNCTION_EXPORT(guard_status, show guard monitor status); #endif /* RT_USING_FINSH */