guard.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /*
  2. * Copyright (c) 2006-2026, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2026-03-20 RuoFeng first version
  9. */
  10. /*********************↓ define ↓************************/
  11. #define DBG_TAG "guard"
  12. #define DBG_LVL DBG_LOG
  13. /* Guard配置 */
  14. #define GUARD_THREAD_STACK_SIZE 1024
  15. #define GUARD_THREAD_PRIORITY 15 /* 低优先级,不影响业务 */
  16. #define GUARD_CHECK_INTERVAL 1000 /* 检查间隔1秒 */
  17. /* 网络监控配置 */
  18. #define NET_CHECK_INTERVAL 60 /* 每60秒检查一次网络 */
  19. #define NET_FAILURE_LIMIT 60 /* 连续失败60次触发重启(60分钟) */
  20. /*********************↑ define ↑************************/
  21. /*********************↓ include ↓************************/
  22. #include <rtthread.h>
  23. #include <rtdbg.h>
  24. #include "ym310_mqtt.h"
  25. #include "ecode.h"
  26. /*********************↑ include ↑************************/
  27. /*********************↓ extern ↓************************/
  28. extern void Recode_e_code(ecode_list code, uint16_t para, char *detail);
  29. extern uint8_t g_work_state;
  30. /*********************↑ extern ↑************************/
  31. /********************↓ static variables ↓***********************/
  32. static rt_thread_t s_guard_thread = RT_NULL;
  33. /* 网络监控状态 */
  34. static struct
  35. {
  36. rt_uint32_t consecutive_failures; /* 连续失败次数 */
  37. rt_uint32_t check_counter; /* 检查计数器 */
  38. rt_uint32_t last_connected_tick; /* 最后连接成功时间 */
  39. } s_net_monitor = {0};
  40. /* 重启统计 */
  41. static struct
  42. {
  43. rt_uint32_t total_reboots;
  44. char last_reason[32];
  45. } s_reboot_stats = {0};
  46. /********************↑ static variables ↑***********************/
  47. /********************↓ static functions ↓***********************/
  48. /**
  49. * 执行重启操作
  50. */
  51. static void guard_do_reboot(const char *reason)
  52. {
  53. // rt_base_t level;
  54. if(g_work_state == 1)
  55. {
  56. return ;
  57. }
  58. /* 记录重启信息 */
  59. // level = rt_hw_interrupt_disable();
  60. s_reboot_stats.total_reboots++;
  61. rt_strncpy(s_reboot_stats.last_reason, reason, sizeof(s_reboot_stats.last_reason) - 1);
  62. // level = rt_hw_interrupt_enable(level);
  63. /* 记录异常事件 */
  64. Recode_e_code(e_GUARD_NET, s_net_monitor.consecutive_failures, (char *)reason);
  65. /* 输出重启日志 */
  66. LOG_E("=========================================");
  67. LOG_E("GUARD REBOOT");
  68. LOG_E("Reason: %s", reason);
  69. LOG_E("Net failures: %d", s_net_monitor.consecutive_failures);
  70. LOG_E("Total reboots: %d", s_reboot_stats.total_reboots);
  71. LOG_E("=========================================");
  72. rt_thread_mdelay(500); /* 等待日志输出 */
  73. /* 执行系统重启 */
  74. rt_hw_cpu_reset();
  75. }
  76. /**
  77. * 网络连接检查
  78. */
  79. static void guard_check_network(void)
  80. {
  81. rt_bool_t connected;
  82. /* 每60秒检查一次 */
  83. s_net_monitor.check_counter++;
  84. if (s_net_monitor.check_counter < NET_CHECK_INTERVAL)
  85. {
  86. return;
  87. }
  88. s_net_monitor.check_counter = 0;
  89. /* 检查网络连接状态 */
  90. connected = ym310_mqtt_is_connected(0);
  91. if (connected)
  92. {
  93. /* 连接成功,重置计数器 */
  94. if (s_net_monitor.consecutive_failures > 0)
  95. {
  96. LOG_I("Network restored after %d failures", s_net_monitor.consecutive_failures);
  97. s_net_monitor.consecutive_failures = 0;
  98. s_net_monitor.last_connected_tick = rt_tick_get();
  99. }
  100. }
  101. else
  102. {
  103. /* 达到失败阈值,触发重启 */
  104. if (s_net_monitor.consecutive_failures >= NET_FAILURE_LIMIT)
  105. {
  106. LOG_E("Network failure threshold reached! System reboot...");
  107. guard_do_reboot("network timeout");
  108. }
  109. else
  110. {
  111. /* 连接失败,累加计数 */
  112. s_net_monitor.consecutive_failures++;
  113. LOG_W("Network check failed (%d/%d)",
  114. s_net_monitor.consecutive_failures, NET_FAILURE_LIMIT);
  115. }
  116. }
  117. }
  118. /**
  119. * 监控主循环
  120. */
  121. static void guard_thread_entry(void *param)
  122. {
  123. // LOG_I("Guard monitor started");
  124. while (1)
  125. {
  126. /* 执行网络监控 */
  127. guard_check_network();
  128. /* 休眠1秒 */
  129. rt_thread_mdelay(GUARD_CHECK_INTERVAL);
  130. }
  131. }
  132. /********************↑ static functions ↑***********************/
  133. /********************↓ 初始化/退出函数 ↓***********************/
  134. /**
  135. * 初始化Guard监控模块
  136. */
  137. static int guard_init(void)
  138. {
  139. // LOG_I("Initializing guard monitor...");
  140. /* 初始化网络监控状态 */
  141. rt_memset(&s_net_monitor, 0, sizeof(s_net_monitor));
  142. s_net_monitor.last_connected_tick = rt_tick_get();
  143. /* 创建监控线程 */
  144. s_guard_thread = rt_thread_create("guard",
  145. guard_thread_entry,
  146. RT_NULL,
  147. GUARD_THREAD_STACK_SIZE,
  148. GUARD_THREAD_PRIORITY,
  149. 10);
  150. if (s_guard_thread == RT_NULL)
  151. {
  152. LOG_E("Failed to create guard thread");
  153. return -RT_ERROR;
  154. }
  155. rt_thread_startup(s_guard_thread);
  156. // LOG_I("Guard monitor ready (net threshold: %d failures)", NET_FAILURE_LIMIT);
  157. return RT_EOK;
  158. }
  159. /**
  160. * 自动初始化(在系统启动后自动运行)
  161. */
  162. INIT_APP_EXPORT(guard_init);
  163. /********************↑ 初始化/退出函数 ↑***********************/
  164. #ifdef RT_USING_FINSH
  165. #include <finsh.h>
  166. /**
  167. * 查看Guard状态(调试用)
  168. */
  169. static void guard_status(int argc, char **argv)
  170. {
  171. rt_uint32_t uptime = rt_tick_get() * 1000 / RT_TICK_PER_SECOND;
  172. rt_uint32_t hours = uptime / 3600000;
  173. rt_uint32_t mins = (uptime % 3600000) / 60000;
  174. rt_kprintf("\n========== GUARD STATUS ==========\n");
  175. rt_kprintf("Uptime: %dh %dm\n", hours, mins);
  176. rt_kprintf("Net failures: %d/%d\n",
  177. s_net_monitor.consecutive_failures, NET_FAILURE_LIMIT);
  178. rt_kprintf("Total reboots: %d\n", s_reboot_stats.total_reboots);
  179. if (s_reboot_stats.total_reboots > 0)
  180. {
  181. rt_kprintf("Last reboot: %s\n", s_reboot_stats.last_reason);
  182. }
  183. rt_kprintf("==================================\n");
  184. }
  185. FINSH_FUNCTION_EXPORT(guard_status, show guard monitor status);
  186. #endif /* RT_USING_FINSH */