feat(DLD154V4B): V2.10 新增 IWDT 硬件看门狗(超时≈1.64s,双保险喂狗)

- 对齐 DLD154Pro V3.03 方案: TMR15 ISR 5ms 递增 g_wdg_counter,
  主循环 poll_wdg() 每 500ms 喂狗, 超时 16×4096/40k ≈ 1.64s
- 双保险: ISR 死→计数不涨→永不喂狗; 主循环死→poll_wdg 不执行→复位
- main() 使能后立即喂一次, 给 FreeRTOS 启动留足时间
- 隔离测试 5 项断言全过 (init 配置/10s 喂狗 20 次/ISR 死不喂/边界 99-100 tick)
- 文档同步: technical-spec(架构图+§13.1 机制) / release-notes(V2.10)
  / product-manual(特性+版本) / roadmap / devlog
This commit is contained in:
wangfq
2026-08-28 08:56:33 +08:00
parent 859842aba0
commit 8f43f8f1c9
8 changed files with 117 additions and 4 deletions
+34
View File
@@ -4,6 +4,39 @@
---
## 2026-08-28 — 新增 IWDT 硬件看门狗(V2.10
### 背景
V4B 是全产品线唯一**无看门狗**的型号(对比:M1H 有 WDT_CONTR、PD132 系有 IWDG/WWDG、154Pro V3.03 有 WWDG 558ms)。现场若主循环卡死/FreeRTOS 调度异常,表现为"假活"——指示灯正常但检测逻辑已死,只能断电恢复。
### 实现(对齐 154Pro V3.03 双保险模式)
```c
// main(): wdt_init() — IWDT 分频16 + 重装载4095, 使能后立即喂一次
// TMR15 ISR: g_wdg_counter++ (5ms)
// 主循环: poll_wdg() — 计数达 100 (500ms) 才 wdt_counter_reload()
```
- **超时** ≈ 1.64sLSI≈40kHz16×4096/40k),喂狗周期 500ms,余量 >3×
- **双保险语义**:ISR 死 → 计数不涨 → 永不喂狗;主循环死 → poll_wdg 不执行 → 超时复位
- FreeRTOS 调度失败/任务创建失败 → 无人喂狗 → 复位(避免"假活"
### 涉及文件
| 文件 | 变更 |
|------|------|
| `src/main.c` | `Timr6_Init()` 后调 `wdt_init()` |
| `src/TaskLoop.c` | +`g_wdg_counter` + `wdt_init()` + `poll_wdg()`;TMR15 ISR 计数;主循环喂狗 |
| `inc/TaskLoop.h` | +WDT 宏 + extern + 函数声明 |
### 验证
- 隔离测试(host gcc mock wdt_* 驱动)5 项断言全过:init 配置、10s 喂狗 20 次(500ms 精确)、ISR 死不喂狗、边界 99/100 tick
- 待现场验证:实际复位时间(LSI 实际频率),用 `RST_REASON` 类机制确认复位源
---
## 2026-08-28 — 平坦性离开判定默认关闭(现场实测不理想)
### 背景
@@ -568,6 +601,7 @@ if (dev >= dlt_ORG × 4) {
| 版本 | 时间 | 说明 |
|------|------|------|
| V2.10 | 2026-08-28 | 新增 IWDT 硬件看门狗(超时≈1.64s,双保险喂狗) |
| 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 | 验收标准 + 发展路线图文档 |
+2
View File
@@ -18,6 +18,7 @@ DLD154V4B 是一款基于 ARM Cortex-M4 微控制器的**单通道环形线圈
- **诊断黄灯**:断开/重连次数编码闪烁,现场故障一目了然
- **灵敏度 4 级可调**:通过 DIP 开关配置,0.031% ~ 0.33% 频率变化检测
- **双输出模式**:存在输出 / 脉冲输出可选
- **看门狗自恢复**:硬件 IWDT(超时≈1.64s),系统异常自动复位,现场免维护
- **宽频率范围**:支持 30 ~ 200 kHz 线圈频率
### 1.2 适用场景
@@ -245,6 +246,7 @@ DLD154V4B 是一款基于 ARM Cortex-M4 微控制器的**单通道环形线圈
| V2.7 | 2026-06-30 | 验收标准 + 发展路线图文档 |
| V2.8 | 2026-08-27 | 灵敏度最高档 SENS=3 阈值 10→20、离开 9→14(防误触发) |
| V2.9 | 2026-08-28 | 平坦性离开判定默认关闭(现场实测不理想),切回简单防抖 |
| V2.10 | 2026-08-28 | 新增 IWDT 硬件看门狗(超时≈1.64s,双保险喂狗) |
---
+11 -1
View File
@@ -1,6 +1,6 @@
# DLD154V4B 产品发布说明
> 固件版本 **V2.9** | 发布日期 2026-08-28
> 固件版本 **V2.10** | 发布日期 2026-08-28
> 单路线圈车辆检测器 · ARM Cortex-M4 · 单路 IIR + 智能基线
---
@@ -76,6 +76,14 @@ if ((Origin - dlt_ORG) < CAPVD) { // 回升至距基线不足 dlt
| **基线冻结超时** | 无(永久冻结) | 稳定 10s 后自动更新 | 环境变化免复位 |
| **冻结稳定性检查** | — | ±2% 窗口验证 | 防止波动值被判为新常态 |
### 6. 硬件看门狗自恢复(V2.10)
AT32F421 独立看门狗(IWDT),超时 ≈1.64s,**双保险喂狗**:
- TMR15 ISR 每 5ms 递增活性计数;主循环 `poll_wdg()` 每 500ms 喂狗
- ISR 死 / 主循环卡死 / FreeRTOS 调度失败 → 无人喂狗 → 自动复位,系统自恢复
- 现场免人工干预,杜绝"假活"(指示灯亮但逻辑已死)
---
## 技术规格速览
@@ -94,6 +102,7 @@ if ((Origin - dlt_ORG) < CAPVD) { // 回升至距基线不足 dlt
| 调试口 | TTL 电平 Tx (9600,8N1) |
| 供电 | DC 10~30V 宽压,< 2W |
| 温度 | -40°C ~ +85°C |
| 看门狗 | **IWDT 硬件看门狗,超时 ≈1.64s**(双保险喂狗,V2.10 新增) |
| CPU 占用 | < 5% @120MHz |
| 基线冻结超时 | 10s(稳定后自动恢复) |
@@ -139,6 +148,7 @@ if ((Origin - dlt_ORG) < CAPVD) { // 回升至距基线不足 dlt
| V2.7 | 06-30 | 验收标准 + 发展路线图文档 |
| V2.8 | 08-27 | 灵敏度最高档 SENS=3 阈值 10→20、离开 9→14(防误触发) |
| **V2.9** | **08-28** | **平坦性离开判定默认关闭(现场实测不理想),切回简单 cnt_release 防抖** |
| **V2.10** | **08-28** | **新增 IWDT 硬件看门狗(超时≈1.64s,双保险喂狗)** |
---
+2 -1
View File
@@ -10,7 +10,7 @@
|------|------|------|------|-------|---------|---------|---------|
| M1H | 8051 12MHz | CD4060 ÷32 | 50ms | 162ms | 单次阈值 | 单次阈值 | 拨码 |
| TLD-110 | 8051 | CD4060 ÷32 | 50ms | 162ms | 单次阈值 | 单次阈值 | 拨码 |
| **V4B V2.9** | M4 120MHz | TIM3 ÷2 | **10ms** | **32ms** | **3次确认+斜率限幅** | **简单防抖(平坦性默认关)** | 拨码 |
| **V4B V2.10** | M4 120MHz | TIM3 ÷2 | **10ms** | **32ms** | **3次确认+斜率限幅** | **简单防抖(平坦性默认关)** | 拨码 |
### 1.1 V4B 相比 M1H 的核心突破
@@ -23,6 +23,7 @@
| 离开判定 | 单阈值 | **滞回 + 3 次确认(平坦性可选,默认关)** | 防瞬态误落杆 |
| 基线保护 | 无(有车也跟踪) | **冻结 + 10s 超时 + 稳定性检查** | 防污染 + 不死锁 |
| 线圈诊断 | 无 | **黄灯断开次数编码** | 现场可排障 |
| 看门狗 | WDT_CONTR | **IWDT 1.64s 双保险喂狗**V2.10 | 防"假活",现场免维护 |
| 代码量 | ~1200 行 (未精简) | **~945 行** | 功能更多,代码更少 |
---
+26 -2
View File
@@ -42,8 +42,9 @@ FreeRTOS Kernel (CMSIS-RTOS v2)
│ ├── poll_green_led() — 绿灯驱动
│ └── poll_yellow_led() — 黄灯故障编码
├── TMR3_ISR() — 线圈频率捕获
├── TMR15_ISR() — 5ms 系统 tick (LED 驱动)
── TMR14_PWM() — 红灯呼吸
├── TMR15_ISR() — 5ms 系统 tick (LED 驱动 + 看门狗活性计数)
── TMR14_PWM() — 红灯呼吸
└── IWDT — 硬件看门狗 (超时≈1.64s, main 使能, 主循环 poll_wdg 喂狗)
```
---
@@ -683,8 +684,31 @@ DLD154V4B/
#define ENTRY_CONFIRM 3 // 进入确认: 连续 N 次低于阈值
#define FREEZE_TIMEOUT 1000 // 冻结超时: ~10s @ 10ms/tick
#define FREEZE_STABILITY_RATE 2 // 稳定性窗口: 参考值的 ±2%
// 看门狗参数 (IWDT, V2.10 新增)
#define WDT_COUNTER_LIMIT 100 // 喂狗周期 500ms (TMR15 5ms × 100)
#define WDT_DIV 16 // LSI 分频
#define WDT_RLD 4095 // 12bit 重装载 → 超时 ≈ 1.64s
```
### 13.1 看门狗机制(IWDTV2.10 新增)
AT32F421 独立看门狗(IWDT),双保险喂狗模式(对齐 DLD154Pro V3.03 方案):
| 环节 | 实现 |
|------|------|
| 使能 | `main()``wdt_init()`:分频 16 + 重装载 4095 + 立即喂一次 |
| 超时 | ≈ 1.64sLSI≈40kHz`16×4096/40k` |
| 活性计数 | TMR15 ISR 每 5ms `g_wdg_counter++` |
| 喂狗 | 主循环每轮 `poll_wdg()`:计数达 100500ms)才 `wdt_counter_reload()` |
**双保险语义**
- TMR15 ISR 死 → 计数不涨 → 永不喂狗 → 1.64s 后复位
- 主循环死(阻塞/死循环不走喂狗点)→ poll_wdg 不执行 → 1.64s 后复位
- FreeRTOS 调度失败 / 任务创建失败 → 无人喂狗 → 复位(期望行为,避免"假活")
> ⚠ 喂狗周期 500ms 必须远小于超时 1.64s;修改 WDT_DIV/WDT_RLD 时保持 `喂狗周期 < 超时/2`
---
## 14. 关键专利
@@ -46,6 +46,15 @@
*===========================================================================*/
#define USE_FLATNESS_EXIT 0
/*===========================================================================
* (IWDT) - 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 16 // LSI 分频
#define WDT_RLD 4095 // 12bit 重装载 -> 超时约 1.64s
#define WINDOW_ORIGIN 500 // 基线跟踪窗口 (500 × 10ms = 5s)
/*===========================================================================
@@ -126,6 +135,7 @@ extern uint16_t Hold_CNT; // 有限存在计数器
extern uint8_t loop1_INCNT; // 进入延时计数
extern uint8_t loop1_OUTCNT; // 离开延时/脉冲宽度计数
extern uint8_t TM1cnt; // 50ms tick 分频计数
extern volatile uint16_t g_wdg_counter; // 看门狗活性计数 (TMR15 5ms 递增)
/*===========================================================================
*
@@ -183,5 +193,7 @@ void poll_yellow_led(void);
void poll_green_led(void);
void LEDA_ON_OFF(void);
void vd1_task(void);
void wdt_init(void);
void poll_wdg(void);
#endif /* __TASKLOOP_H__ */
@@ -35,6 +35,7 @@ uint32_t loop1_ORG_SUM;
uint16_t loop1_ORG_CNT;
uint16_t loop1_dlt_ORG;
uint8_t Flt_Reg;
volatile uint16_t g_wdg_counter = 0; // 看门狗活性计数 (TMR15 ISR 5ms 递增)
/* M4 优化: 快速 IIR + 进入确认 */
uint8_t loop1_entry_cnt;
@@ -309,6 +310,29 @@ void poll_yellow_led(void)
}
}
/*===========================================================================
* (IWDT) - V2.10
* : TMR15 ISR 5ms g_wdg_counter, poll_wdg() 500ms
* ISR -> counter -> ; -> poll_wdg ->
*===========================================================================*/
void wdt_init(void)
{
wdt_register_write_enable(TRUE);
wdt_divider_set(WDT_DIV);
wdt_reload_value_set(WDT_RLD);
wdt_enable();
wdt_counter_reload(); // 使能后立即喂一次, 给 FreeRTOS 启动留足时间
g_wdg_counter = 0;
}
void poll_wdg(void)
{
if (g_wdg_counter >= WDT_COUNTER_LIMIT) { // 100 x 5ms = 500ms
g_wdg_counter = 0;
wdt_counter_reload();
}
}
/*===========================================================================
* M1H INIT_VD
*===========================================================================*/
@@ -485,6 +509,9 @@ void TMR15_GLOBAL_IRQHandler(void)
if (tmr_interrupt_flag_get(TMR15, TMR_OVF_FLAG) != RESET) {
/*--- 看门狗活性计数 (5ms) ---*/
g_wdg_counter++;
/*--- 初始化阶段红灯快闪 (200ms 周期) ---*/
if (!g_loop_power_up_state) {
_counter1_init++;
@@ -909,6 +936,7 @@ void loop_task_function(void *pvParameters)
}
#endif
poll_wdg(); // IWDT 喂狗 (500ms, TMR15 活性双保险)
vTaskDelay(10); // 10ms tick, M4 优化: 双路 IIR + 进入确认 + 斜率限幅
}
}
@@ -229,6 +229,8 @@ int main(void)
loop_timer_io_init();
Timr6_Init();
wdt_init(); // IWDT 看门狗使能 (超时约1.64s), 主循环 poll_wdg() 喂狗