Linux Watchdog/看门狗
Watchdog timer(看门狗定时器)是一种电子计时器,其用于检测和恢复计算机故障。在正常操作期间,计算机定期重置看门狗定时器以防止它“超时”。如果由于硬件故障或程序错误,计算机无法重置看门狗,定时器将生成超时信号,复位和重启计算机。Watchdog timer通常出现在嵌入式系统或设备中,在这些设备中,人们无法轻易访问设备或无法及时对故障作出反应。在这样的系统中,如果计算机挂起,计算机就.
Watchdog timer
(看门狗定时器)是一种电子计时器,其用于检测和恢复计算机故障。在正常操作期间,计算机定期重置看门狗定时器以防止它“超时”。如果由于硬件故障或程序错误,计算机无法重置看门狗,定时器将生成超时信号,复位和重启计算机。
Watchdog timer
通常出现在嵌入式系统或设备中,在这些设备中,人们无法轻易访问设备或无法及时对故障作出反应。在这样的系统中,如果计算机挂起,计算机就不能依赖于人来调用重启; 它必须靠Watchdog timer
来复位。
简单Watchdog
微控制器通常包括一个集成的片上看门狗。在其他计算机中,看门狗可以驻留在直接连接到CPU的附近芯片中,看门狗和CPU可以共享公共时钟信号,如下面的框图所示,或者它们可以具有独立的时钟信号。
Linux Watchdog daemon
通常通过写入看门狗控制端口来完成重启看门狗定时器的操作,通常称为“踢”看门狗或者“喂狗”。在Linux
操作系统中,用户空间程序通过与看门狗设备驱动程序交互来启动监视程序。
watchdog
是这样一个守护进程:它打开/dev/watchdog
,并且经常写入它以使内核不能重置,至少每分钟一次。每次写入都会延迟重启时间。一段时间不活动后,看门狗硬件将导致复位。该守护进程对应的程序是/usr/sbin/watchdog
。
watchdog
守护程序的配置文件是/etc/watchdog.conf
,一个典型的配置文件如下
test-binary = /usr/bin/test.sh
watchdog-device = /dev/watchdog0
realtime = yes
priority = 1
这些选项分别表示:
选项 | 说明 |
---|---|
test-binary | 执行给定的二进制文件以执行一些用户定义的测试 |
watchdog-device | 设置监视程序设备名称 |
realtime | 如果设置为yes ,看门狗将自己锁定到内存中,因此永远不会被换出 |
priority | 设置实时模式的计划优先级 |
Watchdog设备驱动配置
首先配置watchdog_device
结构体,默认timeout
是1秒,因为该watchdog
设备如果超过1.6秒没有被“喂”,就会复位整个嵌入式设备:
static struct watchdog_device test_wdt_dev = {
.groups = test_wdt_groups,
.info = &test_wdt_info,
.ops = &test_wdt_ops,
.min_timeout = 1,
.max_timeout = 2,
.timeout = 1,
};
接着配置watchdog_ops
结构体,这里的ping
就是每隔1秒会执行的函数:
static const struct watchdog_ops test_wdt_ops = {
.owner = THIS_MODULE,
.start = test_wdt_start,
.stop = test_wdt_stop,
.ping = test_wdt_ping,
};
下面就是ping
,start
,stop
函数的实现:
static inline void test_wdt_enable(bool enable)
{
if (enable)
gpio_direction_output(GPIO_WD_EN, WD_EN_ACTIVE);
else
gpio_direction_output(GPIO_WD_EN, !WD_EN_ACTIVE);
}
static int test_wdt_start(struct watchdog_device *wdog)
{
test_wdt_enable(true);
return 0;
}
static int test_wdt_stop(struct watchdog_device *wdog)
{
test_wdt_enable(false);
return 0;
}
static void test_wdt_ping(void)
{
gpio_direction_output(GPIO_WD_IN, 0);
udelay(20);
gpio_direction_output(GPIO_WD_IN, 1);
udelay(20);
}
在驱动初始化函数里面注册这个watchdog
设备:
static int __init test_wdt_init(void)
{
int err = 0;
watchdog_set_nowayout(&test_wdt_dev, true);
watchdog_stop_on_reboot(&test_wdt_dev);
err = watchdog_register_device(&test_wdt_dev);
if (err) {
pr_err("Failed to register watchdog device\n");
return err;
}
return 0;
}
module_init(test_wdt_init);
测试Watchdog设备的复位功能
首先把test_watchdog
驱动编译成模块形式:
CONFIG_TEST_WATCHDOG=m
进入系统后在/etc/init.d/test_watchdog
脚本里面自动执行如下两个命令,加载驱动和启动守护进程:
#!/bin/sh
/sbin/modprobe test_watchdog
/usr/sbin/watchdog
这时候watchdog
设备已经正常工作,并且watchdog
守护进程会每隔1秒喂它(调用test_wdt_ping()
),以防止嵌入式设备被复位。如果我们kill
该守护进程,内核就会停止调用test_wdt_ping()
喂狗,整个设备就会在1.6秒内被该watchdog
复位:
$ killall -9 watchdog
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)