一、DW 看门狗核心设计特点
DW (DesignWare) 看门狗是 Synopsys 公司的 APB 总线从设备 IP 核,主要用于在 SoC 中防止系统因程序跑飞或死锁而无法恢复。它有几个核心特征:
-
不可停止:看门狗一旦启动,硬件上就无法被软件停止。即使用户向控制寄存器写入禁用值,也不会生效。
-
必须定时喂狗:软件必须在设定的超时周期内执行"喂狗"操作,否则看门狗会产生中断或直接复位系统。
-
16 档可编程超时:硬件内部预置了 16 个超时周期(Timeout Period,简称 TOP),每个 TOP 是一个 32 位的计数值,看门狗计数器从这个值开始递减计数,归零时触发超时事件。
-
两种响应模式:可通过控制寄存器配置超时后产生复位(RESET)还是先产生中断(IRQ)再复位。
二、寄存器总览与地址映射
DW 看门狗只使用 4 个 32 位寄存器 ,均以 WDOG_xxx_REG_OFFSET 形式定义:
| 偏移量 | 寄存器名(Linux 宏) | 功能简述 |
|---|---|---|
| 0x00 | WDOG_CONTROL_REG_OFFSET |
控制寄存器(WDT_CR):使能看门狗、选择响应模式 |
| 0x04 | WDOG_TIMEOUT_RANGE_REG_OFFSET |
超时范围寄存器(WDT_TORR):选择 16 档超时周期之一 |
| 0x08 | WDOG_CURRENT_COUNT_REG_OFFSET |
当前计数值寄存器(WDT_CURR):只读,查看剩余计数值 |
| 0x0C | WDOG_COUNTER_RESTART_REG_OFFSET |
计数器重启寄存器(WDT_CRR):写入固定值 0x76 触发"喂狗" |
三、各寄存器详解
1. 控制寄存器(WDT_CR)------ 偏移量 0x00
控制寄存器决定看门狗是否使能,以及在超时时产生复位信号还是先产生中断。它的位定义如下:
位 1 位 0
+----+----+----+----+
| RM | EN | ... |
+----+----+----+----+
| 位 | 字段名 | 功能说明 |
|---|---|---|
| 0 | EN (Enable) | 0:禁用看门狗;1:使能看门狗 。 由于看门狗一旦使能就无法停止,该位只能写一次,之后不能再改写。 |
| 1 | RM (Response Mode) | 响应模式选择 。 0:超时后产生复位(RESET); 1:超时后先产生中断(IRQ),若中断未及时清除则最终复位。 |
注意:有些实现版本(如某些 Rockchip SoC)支持中断模式,但并非所有 DW 看门狗的硬件实例都连接了中断信号线,使用前需查阅具体芯片手册确认。
编程要点:
-
使能前必须确保已配置好超时范围(WDT_TORR),否则可能使用默认值 0xFFFF,导致超时周期极短。
-
使能后,EN 位将始终为 1,无法清零。
2. 超时范围寄存器(WDT_TORR)------ 偏移量 0x04
WDT_TORR 用于从 16 档预设的超时周期中选择一档作为当前看门狗的计数值。
31 4 3 0
+-------------------------+--------+
| RESERVED | TOP |
+-------------------------+--------+
| 位 | 字段名 | 功能说明 |
|---|---|---|
| 3:0 | TOP (Timeout Period) | 选择 16 档超时周期之一。TOP 值范围 0 ~ 15,分别对应硬件预置的 16 个不同的计数值。 |
| 31:4 | Reserved | 保留位,写 0,读忽略。 |
超时时间计算公式:
超时时间 = (TOP 对应的计数值) × (1 / 参考时钟频率)
其中"参考时钟频率"来源于设备树 clocks 属性指定的时钟。
TOP 值对应的计数值(举例):
-
若 DW 看门狗采用标准默认的 16 档计数值,TOP 值与计数值的对应关系如下:
-
TOP = 0 → 计数值 = 0x00001000(即 4096)
-
TOP = 1 → 计数值 = 0x00002000(即 8192)
-
TOP = 2 → 计数值 = 0x00004000(即 16384)
-
...
-
TOP = 15 → 计数值 = 0x80000000(即 2,147,483,648)
-
若芯片厂商对 DW 看门狗的 TOP 值做了定制化修改,则应在设备树中通过 snps,watchdog-tops 属性指定自定义的 16 档计数值列表。
编程要点:
-
必须在使能看门狗之前配置好 WDT_TORR,否则使能后计数器将使用无效或错误的计数值。
-
某些版本的 DW 看门狗支持在 WDT_TORR 寄存器的高位(位 7:4)设置一个额外的
TOPINIT字段,用于在启动时预加载超时值,具体需查阅 SoC 的 TRM。
3. 当前计数值寄存器(WDT_CURR)------ 偏移量 0x08
这是一个只读寄存器,存放看门狗计数器当前的递减计数值。软件可以通过读取该值监控剩余的超时时间,用于调试或日志记录。
31 0
+-----------------------------------------------------+
| CURRENT VALUE |
+-----------------------------------------------------+
该字段为 32 位只读,复位值 = 0xFFFFFFFF。
编程要点:
-
由于 APB 总线与看门狗计数器时钟可能异步,读取的值可能不是实时精确的,仅作参考。
-
驱动层通常会忽略此寄存器,因为喂狗周期由软件定时器(如
watchdog_dev.c)控制,无需频繁读取硬件计数值。
4. 计数器重启寄存器(WDT_CRR)------ 偏移量 0x0C
WDT_CRR 是喂狗操作 的核心寄存器。向该寄存器写入一个固定的"魔数" 0x76,会触发硬件将当前 TOP 对应的计数值重新装入计数器,计数器从该值重新开始递减。
写入数据:
31 7 6 0
+-------------+--------+
| Reserved | 0x76 |
+-------------+--------+
写入值 :固定为 0x76。写入其他值无效。
编程要点:
-
喂狗时必须先写入
0x76,硬件才能将 WDT_TORR 指定的计数值装入计数器。 -
某些 DW 看门狗版本还要求写入 WDT_CRR 后,计数器重启才会生效。否则,即使配置了 WDT_TORR,计数器可能仍使用旧值或默认值运行。
-
如果软件在喂狗期间被高优先级中断打断,可能导致喂狗时序错乱。为了保证喂狗操作的原子性,在喂狗之前应关闭中断,喂狗之后再开中断。
四、超时时间的计算
假设参考时钟频率为 freq(单位 Hz),TOP 值对应的计数值为 top_val,则超时时间计算公式为:
超时时间(秒)= top_val / freq
举例 :若 freq = 24 MHz = 24,000,000 Hz,TOP = 2(计数值 = 16,384),则:
text
超时时间 = 16384 / 24000000 ≈ 0.0006827 秒 ≈ 0.68 ms
如需更长的超时时间,可选择更大的 TOP 值。TOP = 15(计数值 ≈ 2.147×10⁹)时,相同频率下的超时时间约为:
超时时间 ≈ 2147483648 / 24000000 ≈ 89.5 秒
注意 :实际超时时间还与 DW 看门狗 IP 的合成参数(如计数器位宽、时钟分频等)有关。若芯片厂商定制了
snps,watchdog-tops属性,计数值列表以设备树中指定的为准。
五、标准使用流程
DW 看门狗的典型配置步骤如下:
-
使能看门狗模块时钟 :通过系统时钟控制器使能 WDT 的时钟(如 Rockchip 的
PCLK_WDT)。 -
配置 WDT_TORR:选择所需的超时档位(TOP 值 0~15)。
-
配置 WDT_CR:设置响应模式(RM 位),然后使能看门狗(EN 位 = 1)。
-
启动看门狗 :向 WDT_CRR 写入
0x76,完成第一次喂狗,计数器开始递减。 -
周期性喂狗 :在超时时间到达之前,再次向 WDT_CRR 写入
0x76,计数器重新装载并继续递减。
示例代码流程(伪代码):
cpp
// 1. 使能时钟(与具体 SoC 相关)
enable_wdt_clock();
// 2. 配置超时档位(TOP = 5)
write32(base + WDT_TORR, 0x5);
// 3. 配置控制寄存器:响应模式 = 复位,并启用看门狗
write32(base + WDT_CR, (0x1 << 1) | 0x1); // RM=1(先中断后复位),EN=1
// 4. 启动看门狗(喂狗)
write32(base + WDT_CRR, 0x76);
// 5. 周期性喂狗(例如在定时器中断或主循环中)
while (1) {
// ... 应用逻辑
write32(base + WDT_CRR, 0x76);
delay_ms(feed_interval_ms);
}
六、注意事项
-
不可停止 :DW 看门狗一旦启动,就无法被软件停止,只能在系统复位后才会重新禁用。这是其硬件设计决定的,与某些可禁用的看门狗不同。
-
先配置后使能:必须在使能看门狗之前完成 WDT_TORR 的配置。若先使能再配置超时范围,计数器可能使用默认值 0xFFFF(即 65535 个时钟周期),导致超时周期极短,可能尚未完成初始化就触发复位。
-
喂狗原子性:为保证喂狗操作不被中断破坏,应在喂狗前关闭中断、喂狗后恢复中断。
-
中断模式可选:并非所有 DW 看门狗的硬件实例都连接了中断信号线。若要使用中断模式(RM=1),需查阅芯片 TRM 确认 WDT 的中断输出已连接到中断控制器。
-
TOP 值可能被定制 :部分芯片厂商(如 Rockchip)会修改 DW 看门狗的默认 TOP 值列表,驱动会通过设备树的
snps,watchdog-tops属性来覆盖默认值。
七、快速参考
| 寄存器 | 偏移量 | 类型 | 功能 | 关键操作 |
|---|---|---|---|---|
| WDT_CR | 0x00 | 读写 | 控制/模式选择 | 位 0 = 1:使能;位 1:0=复位,1=中断 |
| WDT_TORR | 0x04 | 读写 | 超时范围选择 | 位 3:0 = TOP 值(0~15) |
| WDT_CURR | 0x08 | 只读 | 当前计数值 | 读取剩余计数值 |
| WDT_CRR | 0x0C | 只写 | 喂狗/重启 | 写入 0x76 |
超时时间 = top_val ÷ freq,其中 top_val 由 TOP 值和硬件预置列表决定。
启用顺序:配置 WDT_TORR → 配置 WDT_CR(使能) → 写 WDT_CRR(喂狗启动) → 周期喂狗。