diff --git a/docs/devlog.md b/docs/devlog.md index 58d3776..99b2ba2 100644 --- a/docs/devlog.md +++ b/docs/devlog.md @@ -35,6 +35,16 @@ V4B 是全产品线唯一**无看门狗**的型号(对比:M1H 有 WDT_CONTR - 隔离测试(host gcc mock wdt_* 驱动)5 项断言全过:init 配置、10s 喂狗 20 次(500ms 精确)、ISR 死不喂狗、边界 99/100 tick - 待现场验证:实际复位时间(LSI 实际频率),用 `RST_REASON` 类机制确认复位源 +### ⚠ 现场发现并修复:WDT_DIV 传值 bug(V2.10.1) + +**现象**:现场实测 `WDT_COUNTER_LIMIT=100`(500ms 喂狗)不断复位重启,改为 50(250ms)才正常。 + +**根因**:`wdt_divider_set()` 参数是**枚举值**不是分频数值——`WDT_CLK_DIV_16 = 0x02`,寄存器只取低 3 位。宏误写 `WDT_DIV=16`(0b10000)→ 寄存器写入 0 = `WDT_CLK_DIV_4` → **实际分频 4,实际超时 410ms < 喂狗周期 500ms** → 每次喂狗前已超时,不断复位。 + +**修复**:`#define WDT_DIV 2`(枚举值)+ 调用处显式 `(wdt_division_type)` 转换;隔离测试升级 mock 为"寄存器 3bit 截断 + 反推实际分频",复现 bug 机制并断言修复后超时 1638ms > 500ms。 + +**对照教训**:vd960Loop 原实现用 `wdt_divider_set(WDT_CLK_DIV_64)` 枚举写法 ✓ 无此问题——**AT32 WDT 分频参数一律用枚举常量,勿传数值**。 + --- ## 2026-08-28 — 平坦性离开判定默认关闭(现场实测不理想) @@ -601,7 +611,7 @@ if (dev >= dlt_ORG × 4) { | 版本 | 时间 | 说明 | |------|------|------| -| V2.10 | 2026-08-28 | 新增 IWDT 硬件看门狗(超时≈1.64s,双保险喂狗) | +| V2.10 | 2026-08-28 | 新增 IWDT 硬件看门狗(超时≈1.64s,双保险喂狗);修复 WDT_DIV 分频枚举传值 bug(勿传 16,用 WDT_CLK_DIV_16) | | V2.9 | 2026-08-28 | 平坦性离开判定默认关闭(现场实测不理想),切回简单 cnt_release 防抖 | | V2.8 | 2026-08-27 | 灵敏度最高档 SENS=3 阈值 10→20、离开 9→14(防误触发);清理 g_input_div 重复定义 | | V2.7 | 2026-06-30 | 验收标准 + 发展路线图文档 | diff --git a/docs/technical-spec.md b/docs/technical-spec.md index e37f02b..da0d52e 100644 --- a/docs/technical-spec.md +++ b/docs/technical-spec.md @@ -687,7 +687,7 @@ DLD154V4B/ // 看门狗参数 (IWDT, V2.10 新增) #define WDT_COUNTER_LIMIT 100 // 喂狗周期 500ms (TMR15 5ms × 100) -#define WDT_DIV 16 // LSI 分频 +#define WDT_DIV 2 // IWDT 分频枚举值: 2 = WDT_CLK_DIV_16 (实际分频 16, 勿传 16!) #define WDT_RLD 4095 // 12bit 重装载 → 超时 ≈ 1.64s ``` @@ -697,7 +697,7 @@ AT32F421 独立看门狗(IWDT),双保险喂狗模式(对齐 DLD154Pro V3 | 环节 | 实现 | |------|------| -| 使能 | `main()` 中 `wdt_init()`:分频 16 + 重装载 4095 + 立即喂一次 | +| 使能 | `main()` 中 `wdt_init()`:分频 16(枚举 `WDT_CLK_DIV_16`)+ 重装载 4095 + 立即喂一次 | | 超时 | ≈ 1.64s(LSI≈40kHz,`16×4096/40k`) | | 活性计数 | TMR15 ISR 每 5ms `g_wdg_counter++` | | 喂狗 | 主循环每轮 `poll_wdg()`:计数达 100(500ms)才 `wdt_counter_reload()` | diff --git a/utilities/at32f421_freertos_demo/inc/TaskLoop.h b/utilities/at32f421_freertos_demo/inc/TaskLoop.h index d9d1fc2..94046cd 100644 --- a/utilities/at32f421_freertos_demo/inc/TaskLoop.h +++ b/utilities/at32f421_freertos_demo/inc/TaskLoop.h @@ -52,7 +52,7 @@ * 超时 = WDT_DIV x (WDT_RLD+1) / LSI(约40kHz) 约 1.64s *===========================================================================*/ #define WDT_COUNTER_LIMIT 100 // 喂狗周期 500ms (TMR15 5ms x 100) -#define WDT_DIV 16 // LSI 分频 +#define WDT_DIV 2 // IWDT 分频枚举值: 2 = WDT_CLK_DIV_16 (实际分频 16; 勿传 16!) #define WDT_RLD 4095 // 12bit 重装载 -> 超时约 1.64s #define WINDOW_ORIGIN 500 // 基线跟踪窗口 (500 × 10ms = 5s) diff --git a/utilities/at32f421_freertos_demo/src/TaskLoop.c b/utilities/at32f421_freertos_demo/src/TaskLoop.c index 931f68a..0354d69 100644 --- a/utilities/at32f421_freertos_demo/src/TaskLoop.c +++ b/utilities/at32f421_freertos_demo/src/TaskLoop.c @@ -318,7 +318,7 @@ void poll_yellow_led(void) void wdt_init(void) { wdt_register_write_enable(TRUE); - wdt_divider_set(WDT_DIV); + wdt_divider_set((wdt_division_type)WDT_DIV); // WDT_DIV=2 -> WDT_CLK_DIV_16 wdt_reload_value_set(WDT_RLD); wdt_enable(); wdt_counter_reload(); // 使能后立即喂一次, 给 FreeRTOS 启动留足时间