feat(vd960Loop): 看门狗升级双保险喂狗模式 + 超时对齐 V4B(1.64s)
对照 DLD154V4B V2.10(同款 AT32F421): - 原直喂模式缺 ISR 活性检测: TMR15 ISR 死但主循环活 -> 看门狗永不复位(假活) - 升级: TMR15 ISR 5ms 递增 g_wdg_counter + 主循环 poll_wdg() 500ms 才 reload - 超时 3s(div64/rld1875) -> 1.64s(div16枚举/rld4095) - wdt_feed 定义移至 TaskLoop.c 改名 poll_wdg, 与 V4B 同构 - 修正 main.c 注释矛盾(4687 vs 1875); 沿用 WDT_CLK_DIV_16 枚举写法避免 V4B 同源传值 bug - 隔离测试 3 项断言全过(分频16/超时1638ms>500ms/10s喂20次/ISR死不喂)
This commit is contained in:
@@ -4,6 +4,45 @@
|
||||
|
||||
---
|
||||
|
||||
## 2026-08-28 — 看门狗升级:双保险喂狗模式 + 超时对齐 V4B(1.64s)
|
||||
|
||||
### 背景
|
||||
|
||||
与 DLD154V4B(同款 AT32F421)看门狗实现对照后发现三个问题:
|
||||
|
||||
| 问题 | 说明 |
|
||||
|------|------|
|
||||
| **直喂模式缺 ISR 活性检测** | 原实现主循环每 10ms 无条件 `wdt_feed()`——TMR15 ISR 死掉但主循环活着时,看门狗照样被喂,系统"假活"(时序状态机全停但永不复位) |
|
||||
| **超时 3s 偏长** | `div=64, rld=1875` → 3s;V4B 已用 1.64s,复位自愈更快 |
|
||||
| **注释矛盾** | `main.c` 注释写"重载值=4687 超时≈3秒"(4687 是 7.5s 的算法),实际 1875→3s |
|
||||
|
||||
### 改动(对齐 DLD154V4B V2.10)
|
||||
|
||||
```c
|
||||
// TaskLoop.h
|
||||
#define WDT_COUNTER_LIMIT 100 // 喂狗周期 500ms (TMR15 5ms × 100)
|
||||
#define WDT_DIV 2 // IWDT 分频枚举值: 2 = WDT_CLK_DIV_16 (实际分频 16)
|
||||
#define WDT_RLD 4095 // 12bit 重装载 → 超时 ≈ 1.64s
|
||||
```
|
||||
|
||||
| 文件 | 变更 |
|
||||
|------|------|
|
||||
| `src/main.c` | `wdt_init()`:`WDT_CLK_DIV_64/1875` → `WDT_CLK_DIV_16/4095`(超时 3s→1.64s);`wdt_feed` 定义删除(移至 TaskLoop.c);注释修正 |
|
||||
| `src/TaskLoop.c` | +`g_wdg_counter` + `poll_wdg()`(500ms 才 reload);TMR15 ISR 5ms 递增;调用点 `wdt_feed()`→`poll_wdg()` |
|
||||
| `inc/TaskLoop.h` | +WDT 宏 + `poll_wdg` 声明 + `g_wdg_counter` extern(删 `wdt_feed`) |
|
||||
|
||||
### 验证
|
||||
|
||||
- 隔离测试(host gcc mock 3bit 寄存器语义)3 项断言全过:分频 16/重载 4095/超时 1638ms > 500ms 喂狗周期、10s 喂狗 20 次(500ms 精确)、ISR 死不喂狗
|
||||
- 双保险语义:ISR 死 → 计数不涨 → 永不喂狗;主循环死 → poll_wdg 不执行 → 超时复位
|
||||
- 待现场验证:LSI 实际频率偏差对复位时间的影响
|
||||
|
||||
### ⚠ 踩坑提醒(V4B 同源事故)
|
||||
|
||||
`wdt_divider_set()` 参数是**枚举值**不是分频数值(`WDT_CLK_DIV_16=0x02`,寄存器只取低 3 位)——V4B 曾把 `WDT_DIV=16` 当数值传入 → 实际分频 4 → 超时 410ms < 500ms 喂狗周期 → **不断复位重启**。本次 vd960Loop 直接沿用枚举写法,避免同坑。
|
||||
|
||||
---
|
||||
|
||||
## 2026-08-27 — LOOP_MEASURE_BASE 归一化基数上报(协议 V1.09)
|
||||
|
||||
### 背景
|
||||
|
||||
@@ -41,6 +41,15 @@
|
||||
#define FREEZE_TIMEOUT 1000 // 冻结超时: ~10s @ 10ms/tick
|
||||
#define FREEZE_STABILITY_RATE 2 // 稳定性窗口: 参考值的 ±2%
|
||||
|
||||
/*===========================================================================
|
||||
* 看门狗 (IWDT) - 对齐 DLD154V4B V2.10
|
||||
* 双保险模式: TMR15 ISR 5ms 递增 g_wdg_counter, 主循环 poll_wdg() 每 500ms 喂狗
|
||||
* 超时 = WDT_DIV 枚举分频 x (WDT_RLD+1) / LSI(约40kHz) 约 1.64s
|
||||
*===========================================================================*/
|
||||
#define WDT_COUNTER_LIMIT 100 // 喂狗周期 500ms (TMR15 5ms x 100)
|
||||
#define WDT_DIV 2 // IWDT 分频枚举值: 2 = WDT_CLK_DIV_16 (实际分频 16; 勿传 16!)
|
||||
#define WDT_RLD 4095 // 12bit 重装载 -> 超时约 1.64s
|
||||
|
||||
/*===========================================================================
|
||||
* 离开检测: 1 = 平坦性三条件 (CN200910309382), 0 = cnt_release 防抖
|
||||
*===========================================================================*/
|
||||
@@ -228,7 +237,8 @@ uint8_t update_moving_average(uint32_t* p_sum, uint16_t* p_cnt,
|
||||
void set_loops_relay_on(uint8_t loop_num);
|
||||
void set_loops_relay_off(uint8_t loop_num);
|
||||
|
||||
void wdt_feed(void);
|
||||
void poll_wdg(void);
|
||||
extern volatile uint16_t g_wdg_counter; // 看门狗活性计数 (TMR15 5ms 递增)
|
||||
|
||||
extern TaskHandle_t usart_task_handler;
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ Loop154_States g_loop_states = {0};
|
||||
uint32_t g_sys_freq = 0;
|
||||
uint8_t g_input_div = 1;
|
||||
uint32_t g_safe_max_cnt = LC_HOLD_TIME;
|
||||
volatile uint16_t g_wdg_counter = 0; // 看门狗活性计数 (TMR15 ISR 5ms 递增)
|
||||
|
||||
/*===========================================================================
|
||||
* 一阶 IIR 低通滤波器(对齐 DLD154V4B)
|
||||
@@ -252,6 +253,9 @@ void TMR15_GLOBAL_IRQHandler(void)
|
||||
|
||||
if (tmr_interrupt_flag_get(TMR15, TMR_OVF_FLAG) != RESET) {
|
||||
|
||||
/*--- 看门狗活性计数 (5ms) ---*/
|
||||
g_wdg_counter++;
|
||||
|
||||
/*--- 50ms tick 分频 ---*/
|
||||
TM1cnt++;
|
||||
if (TM1cnt >= 10) {
|
||||
@@ -657,6 +661,20 @@ void vd1_task_per_channel(Loop154_Unit *unit)
|
||||
|
||||
/*===========================================================================
|
||||
* loop_task_function — FreeRTOS 主任务(对齐 DLD154V4B main 循环)
|
||||
/*===========================================================================
|
||||
* 看门狗喂狗 (双保险, 对齐 DLD154V4B V2.10)
|
||||
* TMR15 ISR 5ms 递增 g_wdg_counter; 计数达 100 (500ms) 才 reload
|
||||
* ISR 死 -> 计数不涨 -> 永不喂狗; 主循环死 -> 本函数不执行 -> 超时复位
|
||||
*===========================================================================*/
|
||||
void poll_wdg(void)
|
||||
{
|
||||
if (g_wdg_counter >= WDT_COUNTER_LIMIT) { // 100 x 5ms = 500ms
|
||||
g_wdg_counter = 0;
|
||||
wdt_counter_reload();
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
* 10ms 周期,独立处理每路线圈。
|
||||
*===========================================================================*/
|
||||
void loop_task_function(void *pvParameters)
|
||||
@@ -705,7 +723,7 @@ void loop_task_function(void *pvParameters)
|
||||
}
|
||||
}
|
||||
|
||||
wdt_feed();
|
||||
poll_wdg();
|
||||
vTaskDelay(10); // 10ms tick, M4 优化: 双路 IIR + 进入确认 + 斜率限幅
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,9 +59,8 @@ __IO uint32_t TimingDelayDec;
|
||||
TaskHandle_t loop_task_handler;
|
||||
|
||||
// 看门狗相关
|
||||
#define WDT_TIMEOUT_MS 3000 // 看门狗超时时间 3秒
|
||||
#define WDT_TIMEOUT_MS 1600 // 看门狗超时时间: IWDT div16 rld4095, LSI约40kHz -> ~1.64s
|
||||
void wdt_init(void);
|
||||
void wdt_feed(void);
|
||||
|
||||
tmr_output_config_type tmr_oc_init_structure;
|
||||
|
||||
@@ -104,20 +103,19 @@ void InitPkgUart(Pkg_Uart * pkg){
|
||||
* @param none
|
||||
* @retval none
|
||||
* @note 超时时间 = (预分频系数 × 重载值) / LSI频率
|
||||
* LSI频率约 40kHz,预分频64,重载值=4687,超时≈ 3秒
|
||||
* LSI频率约 40kHz,预分频16(枚举 WDT_CLK_DIV_16),重载值=4095,超时≈ 1.64秒
|
||||
*/
|
||||
void wdt_init(void)
|
||||
{
|
||||
// 使能看门狗寄存器写访问
|
||||
wdt_register_write_enable(TRUE);
|
||||
|
||||
// 设置预分频系数为 64
|
||||
wdt_divider_set(WDT_CLK_DIV_64);
|
||||
// 设置预分频: 必须用枚举 WDT_CLK_DIV_16 (=0x02), 勿传数值 16! (V4B 踩坑)
|
||||
wdt_divider_set(WDT_CLK_DIV_16);
|
||||
|
||||
// 设置重载值
|
||||
// 超时时间 = (64 × 4687) / 40000 ≈ 7.5秒
|
||||
// 如果需要 3秒: (64 × 1875) / 40000 = 3秒
|
||||
wdt_reload_value_set(1875);
|
||||
// 设置重载值 4095 (12bit 最大)
|
||||
// 超时时间 = (16 × 4096) / 40000 ≈ 1.64秒
|
||||
wdt_reload_value_set(4095);
|
||||
|
||||
// 重载计数器
|
||||
wdt_counter_reload();
|
||||
@@ -128,15 +126,6 @@ void wdt_init(void)
|
||||
PRINT("Watchdog initialized, timeout: %d ms\n", WDT_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 喂狗(重载看门狗计数器)
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void wdt_feed(void)
|
||||
{
|
||||
wdt_counter_reload();
|
||||
}
|
||||
|
||||
uint16_t timer_period = 0;
|
||||
uint16_t channel1_pulse = 0;
|
||||
|
||||
Reference in New Issue
Block a user