看门狗,又叫 watchdogtimer,是一个定时器电路, 一般有一个输入,叫喂狗,一个输出到MCU的RST端,MCU正常工作的时候,每隔一段时间输出一个信号到喂狗端,给 WDT 清零,如果超过规定的时间不喂狗,(一般在程序跑飞时),WDT 定时超过,就会给出一个复位信号到MCU,是MCU复位. 防止MCU死机. 看门狗的作用就是防止程序发生死循环,或者说程序跑飞。
watchdog的操作就是reset,所以跟电源是有联系的。
1. 软硬件watchdog的区别
通常情况下,watchdog需要硬件支持,但是如果确实没有相应的硬件,还想使用watchdog功能,则可以使用liunx模拟的watchdog,即软件watchdog。
硬件watchdog必须有硬件电路支持, 设备节点/dev/watchdog对应着真实的物理设备, 不同类型的硬件watchdog设备由相应的硬件驱动管理。软件watchdog由一内核模块softdog.ko 通过定时器机制实现,/dev/watchdog并不对应着真实的物理设备,只是为应用提供了一个与操作硬件watchdog相同的接口。
硬件watchdog比软件watchdog有更好的可靠性。软件watchdog基于内核的定时器实现,当内核或中断出现异常时,软件watchdog将会失效。而硬件watchdog由自身的硬件电路控制, 独立于内核。无论当前系统状态如何,硬件watchdog在设定的时间间隔内没有被执行写操作,仍会重新启动系统。
一些硬件watchdog卡如WDT501P 以及一些Berkshire卡还可以监测系统温度,提供了 /dev/temperature接口。
对于应用程序而言, 操作软件、硬件watchdog的方式基本相同:打开设备/dev/watchdog, 在重启时间间隔内对/dev/watchdog执行写操作。即软件、硬件watchdog对应用程序而言基本是透明的。
在任一时刻, 只能有一个watchdog驱动模块被加载,管理/dev/watchdog 设备节点。如果系统没有硬件watchdog电路,则可以加载软件watchdog驱动softdog.ko。
2. 软件看门狗
2.1 kernel watchdog
kernel watchdog是用来检测Lockup 的。所谓lockup,是指某段内核代码占着CPU不放。Lockup严重的情况下会导致整个系统失去响应。Lockup有几个特点:
首先只有内核代码才能引起lockup,因为用户代码是可以被抢占的,不可能形成lockup(只有一种情况例外,就是SCHED_FIFO优先级为99的实时进程即使在用户态也可能使[watchdog/x]内核线程抢不到CPU而形成soft lockup)
其次内核代码必须处于禁止内核抢占的状态(preemption disabled),因为Linux是可抢占式的内核,只在某些特定的代码区才禁止抢占(例如spinlock),在这些代码区才有可能形成lockup。
2.1.1 soft lockup
Lockup分为两种:soft lockup 和 hard lockup,它们的区别是 hard lockup 发生在CPU屏蔽中断的情况下。而soft lockup则是单个CPU被一直占用的情况(中断仍然可以响应)。
NMI,即非可屏蔽中断。即使在内核代码中设置了屏蔽所有中断的时候,NMI也是不可以被屏蔽的。
可屏蔽中断包含时钟中断,外设中断(比如键盘中断,I/O设备中断,等等),当我们处理中断处理程序的时候,在中断处理程序top half时候,在不允许嵌套的情况下,需要关闭中断。
但NMI就不一样了,即便在关闭中断的情况下,他也能被响应。触发NMI的条件一般都是ECC error之类的硬件Error。但NMI也给我们提供了一种机制,在系统中断被误关闭的情况下,依然能通过中断处理程序来执行一些紧急操作,比如kernel panic。
检测soft lockup的原理是给每个CPU分配一个定时执行的内核线程[watchdog/x],如果该线程在设定的期限内没有得到执行的话就意味着发生了soft lockup,[watchdog/x]是SCHED_FIFO实时进程,优先级为最高的99,拥有优先运行的特权。
系统会有一个高精度的计时器hrtimer(一般来源于APIC),该计时器能定期产生时钟中断,该中断对应的中断处理例程是kernel/watchdog.c: watchdog_timer_fn(),在该例程中:
要递增计数器hrtimer_interrupts,这个计数器同时为hard lockup detector用于判断CPU是否响应中断;
还要唤醒[watchdog/x]内核线程,该线程的任务是更新一个时间戳;
soft lock detector检查时间戳,如果超过soft lockup threshold一直未更新,说明[watchdog/x]未得到运行机会,意味着CPU被霸占,也就是发生了soft lockup。
linux kernel会自动检测softlockup,在发生softlockup情况下,系统默认会打印相关warning信息。如果需要出发panic的话,可以设置
echo 1 > /proc/sys/kernel/softlockup_panic
可以同时设置 watchdog_thresh参数来定义发现softlockup以后系统panic的时间,默认是10s, 也就是说20s后系统panic。最大能设到60s,也就是说,120s后启动系统panic。
一般来说,在production system上,不建议使用softlockup_panic选项(有可能误伤)。可以在调试系统上使用。
2.1.1 hard lockup
Hard lockup比soft lockup更加严重,CPU不仅无法执行其它进程,而且不再响应中断。检测hard lockup的原理利用了PMU的NMI perf event,因为NMI中断是不可屏蔽的,在CPU不再响应中断的情况下仍然可以得到执行,它再去检查时钟中断的计数器hrtimer_interrupts是否在保持递增,如果停滞就意味着时钟中断未得到响应,也就是发生了hard lockup
Linux kernel设计了一个检测lockup的机制,称为NMI Watchdog,是利用NMI中断实现的,用NMI是因为lockup有可能发生在中断被屏蔽的状态下,这时唯一能把CPU抢下来的方法就是通过NMI,因为NMI中断是不可屏蔽的。
NMI watchdog会利用到之前讲到的hrtimer。它的触发条件是基于PMU的NMI perf event,当PMU的计数器溢出时会触发NMI中断,对应的中断处理例程是 kernel/watchdog.c: watchdog_overflow_callback(),hard lockup detector就在其中,它会检查上述hrtimer的中断次数(hrtimer_interrupts)是否在保持递增,如果停滞则表明hrtimer中断未得到响应,也就是发生了hard lockup。
这里面,被watch的对象是hrtimer,而watchdog则是由PMU设备发起的NMI中断处理程序 watchdog_overflow_callback()
hardlockup的检测需要启动NMI watchdog。可以通过设置内核参数实现:
echo 1 > /proc/sys/kernel/nmi_watchdog 1 在发生hardlockup情况下,如果我们需要系统panic,可以设置(默认已设定)
echo 1 > /proc/sys/kernel/hardlockup_panic
2.2 用户态watchdog
用户程序有可能占着临界资源无法释放,系统太忙,疲于响应各种中断,导致无法执行调度程序。这都可能导致系统无法正常使用。
在这种情况下,时钟中断和NMI中断仍然能够被响应,所以内核lockup检测机制无法检查出来。但由于系统已经无法正常工作,我们需要一种机制,一种用户态的watchdog,来检测这种系统挂起的状态,并作出相应的动作。
用户态watchdog,自然检测的对象是用户态的程序(是否能被调度)。这里面,基于硬件支持程度不同,我们分为hardware watchdog和software watchdog。后者简称softdog。
2.2.1 softdog
使用softdog很简单,只需要:
安装 watchdog rpm
启动softdog服务
-systemctl start softdog.service
默认情况下,watchdog程序会通过softdog.ko创建一个叫做/dev/watchdog1的设备(timer 设备),并且定期往它写东西(用于更新时间戳)。
位于内核的softdog会模拟timer设备(通过时钟中断的方式模拟),并执行相应的中断处理例程,该例程的目的是检查timer 设备(即/dev/watchdog1)是否timeout。如果timeout,则执行相应动作(默认为panic)。
2.2.1 hardware watchdog
通过BMC实现、通过iTCO实现
3. 硬件看门狗
3.1 硬件寄存器介绍
看门狗主要由寄存器、计数器和狗叫模块构成,通过寄存器对看门狗进行基本设置,计数器计算狗叫时间,狗叫模块决定看门狗超时后发出的中断或复位方式。
QOTOM Q300P自带硬件看门狗,由SuperIO芯片提供,这里简单实现一下看门狗的复位功能,只需要对看门狗的配置寄存器组和数据寄存器组进行操作。
WDTCTRL:Watch Dog Timer Control Register (Index=71h, Default=00h) 控制寄存器,主要是设置中断,这里不涉及
WDTCONF:Watch Dog Timer Configuration Register (Index=72h, Default=001s0000b) 配置寄存器 Bit6 or Bit4设置为1即可开启看门狗功能,这里使用Bit6脉冲信号
WDTVALLSB:Watch Dog Timer Time-out Value (LSB) Register (Index=73h, Default=38h) 低位数据寄存器WDTVALMSB:Watch Dog Timer Time-out Value (MSB) Register (Index=74h, Default=00h) 高位数据寄存器
3.2 喂狗操作
samples/watchdog/watchdog-simple.c中有一个简单的例子:
int main(void) { int fd = open("/dev/watchdog", O_WRONLY); int ret = 0; if (fd == -1) { perror("watchdog"); exit(EXIT_FAILURE); } while (1) { ret = write(fd, "�", 1); if (ret != 1) { ret = -1; break; } sleep(10); } close(fd); return ret; }
3.3 watchdog硬件驱动编写
例如:drivers/watchdog/imx_sc_wdt.c中 imx_sc_wdt_probe中会调用devm_watchdog_register_device
#define DEFAULT_TIMEOUT 60 #define MAX_TIMEOUT 128 static int imx_sc_wdt_probe(struct platform_device *pdev) { struct watchdog_device *wdog; struct device *dev = &pdev->dev; int ret; wdog = &imx_sc_wdd->wdd; wdog->info = &imx_sc_wdt_info; wdog->ops = &imx_sc_wdt_ops; wdog->min_timeout = 1; wdog->max_timeout = MAX_TIMEOUT; wdog->parent = dev; wdog->timeout = DEFAULT_TIMEOUT; ret = imx_sc_wdt_set_timeout(wdog, wdog->timeout); if (ret) return ret; return devm_watchdog_register_device(dev, wdog);
imx_sc_wdt_ops的定义为:
static const struct watchdog_ops imx_sc_wdt_ops = { .owner = THIS_MODULE, .start = imx_sc_wdt_start, .stop = imx_sc_wdt_stop, .ping = imx_sc_wdt_ping, .set_timeout = imx_sc_wdt_set_timeout, .set_pretimeout = imx_sc_wdt_set_pretimeout, };
例如imx_sc_wdt_start的实现,使用了smc下发到BL31中处理,为了突出安全性。
static int imx_sc_wdt_start(struct watchdog_device *wdog) { struct arm_smccc_res res; arm_smccc_smc(IMX_SIP_TIMER, IMX_SIP_TIMER_START_WDOG, 0, 0, 0, 0, 0, 0, &res); if (res.a0) return -EACCES; arm_smccc_smc(IMX_SIP_TIMER, IMX_SIP_TIMER_SET_WDOG_ACT, SC_TIMER_WDOG_ACTION_PARTITION, 0, 0, 0, 0, 0, &res); return res.a0 ? -EACCES : 0; }
后记:
对于重要的驱动操作的寄存器,在ARM中需要放入BL31中,也就是说寄存器地址是在安全世界的,不能让内核直接按地址操作,只暴露了通用的协议接口,就是一个约束,只能这么用,其他用法不行。暴露API而不是所有寄存器是安全世界和非安全世界的一个重要区别。“啥都懂一点,啥都不精通,
-
mcu
+关注
关注
146文章
17123浏览量
350986 -
看门狗
+关注
关注
10文章
560浏览量
70789 -
电源管理
+关注
关注
115文章
6177浏览量
144444 -
定时器
+关注
关注
23文章
3246浏览量
114719
原文标题:电源管理入门-14 Watchdog
文章出处:【微信号:OS与AUTOSAR研究,微信公众号:OS与AUTOSAR研究】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论