Watchdog 使用指南
1. 模块介绍
1.1. 术语定义
术语 | 定义 | 注释说明 |
---|---|---|
WDT | Watchdog,下文简称wdt | 看门狗 |
clr_thd | Clear threshold | 清看门狗的计数时,当前计数必须要满足此门限 |
irq_thd | IRQ threshold | 看门狗产生中断的计数值 |
rst_thd | Reset threshold | 看门狗触发系统重启的门限值 |
ping | - | 指将Watchdog的计时器清零,使其重 新计数,俗称“喂狗” |
1.2. 模块简介
WDT(Watchdog)给系统提供一个健康监控功能,在系统无法正常使用时,可以强制复位系统;而在系统正常运行期间,可通过重置计数来保证Watchdog模块不触发复位。
Watchdog V1.0在V0.1基础上做了优化升级,提供更多可配置的功能:
-
支持在复位系统前先(时刻可配置)发出一个中断信号,来通知系统做一些复位前的准备工作;
-
增加对计数器清零的限制,只有当前计数值满足一个门限(可配置)才能执行清零;
-
支持预先加载4个Watchdog的配置(软件可以理解为多通道),运行时可一键切换;
-
支持预先加载4个Watchdog的配置(软件可以理解为多通道),运行时可一键切换;
-
写允许
普通状态,无任何权限限制,随时可重新配置计数器;
-
写保护
如果要重新配置Watchdog计时器,需先写入操作码OP_WR_EN解锁(进入“写允许”状态);
-
写失效
此时Watchdog进入只读状态,只有OP寄存器可写(用于喂狗、切换通道)。从图中可以看到此状态不可逆,如果要修改Watchdog配置,必须要reset系统才可以。
-
-
支持更多的操作码(Operate Code),如计时器清零、通道切换、写使能。
2. 参数配置
2.1. 内核配置
在luban根目录下执行 make kernel-menuconfig,进入kernel的功能配置,按如下选择:
Linux
Device Drivers
[*] Watchdog Timer Support
<*> Artinchip SoC watchdog support
2.2. DTS 参数配置
2.2.1. Watchdog 自定义参数
Watchdog 驱动支持从DTS中配置的自定义参数,如下表:
参数名称 | 适用版本 | 类型 | 取值范围 | 功能说明 |
---|---|---|---|---|
dbg_continue | V1.0 | boolean | 有 - 1,无 - 0 | 用Jtag进入debug状态时,计数是否继续默认值是0,停止计数 |
clr_thd | V1.0 | 正整数 | > 0 ,单位:秒 | 允许清除WDT的最小秒数 |
小技巧
- 关于清除WDT的逻辑关系,请参考图 Watchdog 清零的窗口示意图 的相关说明。
- 在FPGA环境,清零窗口的功能无效,需要屏蔽clr_thd的判断逻辑。
2.2.2. Common 配置
在common/d211.dtsi中的Watchdog控制器定义:
wdt0: watchdog@19000000 {
compatible = "artinchip,aic-wdt-v1.0";
reg = <0x0 0x19000000 0x0 0x1000>;
interrupts-extended = <&plic0 64 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cmu CLK_WDOG>;
resets = <&rst RESET_WDOG>;
dbg_continue; // 使用Jtag进入debug状态时,计数是否继续。默认是暂停计数
clr_thd = <3>; // 用于设置clr_thd,单位:秒
};
注解
其中有两个扩展字段,如果没有配置将默认是0。
2.2.3. Board 配置
xxx/board.dts中的参数配置比较简单,只是说明是否要打开Watchdog:
&wdt0 {
status = "okay";
};
3. 调试指南
3.1. 调试开关
在luban根目录下执行 make kernel-menuconfig,进入kernel的功能配置,可以打开Watchdog模块的DEBUG选项 :
Linux
Kernel hacking
Artinchip Debug
[*] Watchdog driver debug
此DEBUG选项打开的影响:
- Watchdog驱动以-O0编译
- Watchdog的pr_dbg()和dev_dbg()调试信息会被编译
在系统运行时,如果要打印pr_dbg()和dev_dbg()信息,还需要调整loglevel为8,两个方法:
- 在board.dts中修改bootargs,增加“loglevel=8”
- 在板子启动到Linux shell后,执行命令:
echo 8 > /proc/sys/kernel/printk
3.2. Sysfs 节点
3.2.1. status 节点
在Watchdog驱动初始化成功后,会在Sysfs中注册生成一个 status
节点,其中打印了当前的配置及状态信息:
[aic@] # cat /sys/devices/platform/soc/19000000.watchdog/status
In Watchdog V256.00:
Module Enable: 0
Dbg continue: 0
clr_thd: 333
Write disable: 0
IRQ Enable: 0
Current chan: 0 0
Current cnt: 352
chan clr_thd irq_thd rst_thd
0 0 160000 320000
1 0 160000 320000
2 0 160000 320000
3 0 160000 320000
3.2.2. 当前的 Watchdog 通道信息
查看当前生效正在使用的 Watchdog 通道信息,方法:
[aic@] # cat /sys/devices/platform/soc/*.watchdog/timeout —— 当前通道的timeout配置
10
[aic@] # cat /sys/devices/platform/soc/*.watchdog/pretimeout —— 当前通道的pretimeout配置
0
[aic@] # cat /sys/devices/platform/soc/*.watchdog/channel —— 当前生效的通道编号
0
4. 测试指南
4.1. 测试环境
4.1.1. 硬件
- 开发板,或D211的FPGA板
4.1.2. 软件
- PC端的串口终端软件,用于PC和开发板进行串口通信
- luban中带有的test_wdt测试工具
4.1.3. 软件配置
在luban的根目录下通过 make menuconfig 可以打开 test_wdt 测试工具的编译:
Artinchip packages
Sample code
[*] test-watchdog
4.2. test_wdt 测试
test_wdt的主要功能是通过ioctl标准接口,来查询、设置Watchdog的。
板子上的test_wdt位于 /usr/local/bin/
,无需进入该目录,在shell中直接运行test_wdt即可。
test_wdt的帮助信息:
[aic@] # test_wdt -u
Compile time: Apr 16 2022 14:31:42
Usage: test_wdt [options]
-i, --info Print the status and infomation
-s, --set-timeout Set a timeout, in second
-g, --get-timeout Get the current timeout, in second
-p, --set-pretimeout Set a pretimeout, in second
-G, --get-pretimeout Get the current pretimeout, in second
-k, --keepalive Keepalive the watchdog
-u, --usage
Example: test_wdt -c 0 -s 12
Example: test_wdt -c 1 -s 100 -p 90
注解
- WDT V1.0驱动中对timeout参数的范围有限制:[1, 3600],即最小1秒、最多1小时。
- Linux的Watchdog子系统中对pretimeout参数有限制:pretimeout必须小于timeout。
test_wdt的使用示例:
[aic@] # test_wdt -i
In Artinchip Watchdog timer watchdog V0, options 0x8180
Status: 32768
Boot status: 0
[aic@] # test_wdt -s 3601
wdt_set_timeout()125 - Set chan0 timeout 3601, pretimeout 0
[ERROR] wdt_set_timeout()128 - Failed to set timeout 22[Invalid argument]
[aic@] # test_wdt -s 0
wdt_set_timeout()125 - Set chan0 timeout 0, pretimeout 0
[ERROR] wdt_set_timeout()128 - Failed to set timeout 22[Invalid argument]
[aic@] # test_wdt -g
wdt_get_timeout()155 - Get chan0 timeout 16
[aic@] # test_wdt -s 2
wdt_set_timeout()125 - Set chan0 timeout 2, pretimeout 0
[aic@] # test_wdt -g
wdt_get_timeout()155 - Get chan0 timeout 2
[aic@] # test_wdt -s 9
wdt_set_timeout()125 - Set chan0 timeout 9, pretimeout 0
[aic@] # test_wdt -g
wdt_get_timeout()155 - Get chan0 timeout 9
[aic@] # test_wdt -s 9 -p 4
wdt_set_timeout()125 - Set chan0 timeout 9, pretimeout 4