feat(vd960DBN): 硬件 IWDG 看门狗 + 平台响应超时重启
设计:
1. 硬件 IWDG: LSI≈40kHz, Prescaler=256, Reload=625 → ~4s 超时
主循环 iot_mqtt_poll() 每轮喂狗, 防死循环/硬故障
2. 平台响应看门狗: 3×心跳周期(180s)内无平台回复 → NVIC_SystemReset
_iot_last_recv_ms 刷新点:
- iot_handle_publish() — 收到平台任意 PUBLISH 命令
- iot_evt_handle_ack() — event_report 的 ACK
- iot_handle_suback() — 刚连上 READY 时初始化计时
3. 仅在 IOT_STATE_READY 时检查 (未连上不触发)
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#include "simple_json.h"
|
||||
#include "tcp_json_srv.h"
|
||||
#include "storage.h"
|
||||
#include "ch32v20x_iwdg.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
@@ -41,6 +42,7 @@ static uint32_t _iot_last_heartbeat = 0; // 上次心跳时刻 (ms)
|
||||
static uint32_t _iot_reconnect_deadline = 0;
|
||||
static uint32_t _iot_reconnect_backoff = 0;
|
||||
static uint32_t _iot_connect_start = 0; // TCP connect 开始时刻
|
||||
static uint32_t _iot_last_recv_ms = 0; // 上次收到平台回复时刻 (看门狗追踪)
|
||||
|
||||
/*===========================================================================
|
||||
* 传感器数据缓存 & 上报间隔控制
|
||||
@@ -207,6 +209,7 @@ void iot_evt_handle_ack(uint32_t msg_id, int code) {
|
||||
return;
|
||||
}
|
||||
/* 确认成功 → 弹出本包事件 */
|
||||
_iot_last_recv_ms = mstick(); // 看门狗: 平台对 event_report 的 ACK 也算响应
|
||||
_evt_head = (_evt_head + _evt_pend_n) % IOT_EVT_QUEUE_DEPTH;
|
||||
_evt_count -= _evt_pend_n;
|
||||
PRINT("EVT: ack ok, %d events dequeued (left=%d)\n", _evt_pend_n, _evt_count);
|
||||
@@ -395,6 +398,8 @@ static void iot_handle_publish(const char *topic, uint8_t *payload, int payload_
|
||||
|
||||
PRINT("IOT: PUBLISH topic=%s payload=%s\n", topic, json);
|
||||
|
||||
_iot_last_recv_ms = mstick(); // 看门狗: 收到平台任意消息即刷新
|
||||
|
||||
/* 提取 msg_id 和 cmd */
|
||||
char tmp[256];
|
||||
uint32_t msg_id = 0;
|
||||
@@ -550,6 +555,7 @@ static void iot_handle_suback(void) {
|
||||
PRINT("IOT: ← SUBACK, topics subscribed\n");
|
||||
g_iot_state = IOT_STATE_READY;
|
||||
_iot_reconnect_backoff = 0; // 连接成功, 重置退避
|
||||
_iot_last_recv_ms = mstick(); // 看门狗: 刚连上, 重置平台响应计时
|
||||
|
||||
// V1.03: 订阅成功后发布 initialize 告知服务器上线 (IoT 路径)
|
||||
iot_send_initialize();
|
||||
@@ -898,10 +904,48 @@ void iot_mqtt_handle_sock_int(uint8_t socketid, uint8_t intstat) {
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
* 看门狗 — 硬件 IWDG + 平台响应超时
|
||||
* IWDG: ~4s LSI超时, 主循环喂狗, 防死循环/硬故障
|
||||
* 平台狗: 3×心跳周期(180s)无平台回复 → NVIC_SystemReset
|
||||
*===========================================================================*/
|
||||
|
||||
/* IWDG 初始化: LSI≈40kHz, Prescaler=256 → 156Hz tick, Reload=625 → 4s 超时 */
|
||||
void iot_watchdog_init(void) {
|
||||
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
|
||||
IWDG_SetPrescaler(IWDG_Prescaler_256);
|
||||
IWDG_SetReload(625); // 625 × (256/40000) ≈ 4.0s
|
||||
IWDG_ReloadCounter();
|
||||
IWDG_Enable();
|
||||
PRINT("IOT: IWDG init ok, timeout≈4s\n");
|
||||
}
|
||||
|
||||
/* 喂狗 — 主循环每轮调用 */
|
||||
void iot_watchdog_kick(void) {
|
||||
IWDG_ReloadCounter();
|
||||
}
|
||||
|
||||
/* 平台响应超时检查 — iot_mqtt_poll 中调用 */
|
||||
void iot_watchdog_check(void) {
|
||||
if (g_iot_state != IOT_STATE_READY) return;
|
||||
uint32_t now = mstick();
|
||||
if (now - _iot_last_recv_ms > IOT_MQTT_WDT_TIMEOUT_MS) {
|
||||
PRINT("IOT: WATCHDOG no platform reply for %lu ms (>%u ms), resetting...\n",
|
||||
(unsigned long)(now - _iot_last_recv_ms), IOT_MQTT_WDT_TIMEOUT_MS);
|
||||
/* 不再喂狗, IWDG 4s 后自动复位; 或直接 NVIC_SystemReset */
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
* 主循环轮询
|
||||
*===========================================================================*/
|
||||
void iot_mqtt_poll(void) {
|
||||
iot_watchdog_kick(); // 喂硬件 IWDG
|
||||
|
||||
/* 平台响应超时检查 */
|
||||
iot_watchdog_check();
|
||||
|
||||
/* 断线重连 */
|
||||
if (g_iot_state == IOT_STATE_DISCONNECTED && g_iot_socket == 0xFF) {
|
||||
if (_iot_reconnect_deadline == 0 || mstick() > _iot_reconnect_deadline) {
|
||||
@@ -974,4 +1018,7 @@ void iot_mqtt_init(void) {
|
||||
_iot_reconnect_backoff = 0;
|
||||
_iot_reconnect_deadline = mstick() + 2000; // 启动后 2s 开始首次连接
|
||||
g_iot_state = IOT_STATE_DISCONNECTED;
|
||||
|
||||
/* 初始化硬件看门狗 IWDG (LSI≈40kHz, 4s 超时, 主循环喂狗) */
|
||||
iot_watchdog_init();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user