具体解释kernel中watchdog 驱动程序
Posted wzjhoutai
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了具体解释kernel中watchdog 驱动程序相关的知识,希望对你有一定的参考价值。
watchdog不管在小系统还是大的project系统中都是必须存在的。在解决线程挂死、系统死循环等都用非常重要的应用,算是系统出问题恢复初始状态的救命稻草。
在kernel中wdt的应用不是非经常见,原因就是相比于裸系统来讲。它的线程会出现一些异步的情况,执行状态easy出现系统不可控的时刻。
对于kernel中应用wdt而言,一般採用了一种通用方法。就是用一个timer进行喂狗操作。
下面选取一个典型的代码进行说明,就用 Atmel AT32AP700X device,在kernel-》drivers-》watchdog->at32ap700x_wdt.c
它的操作方法调用方法是不支持文件操作的,一般执行ioctl的方式进行调用
static long at32_wdt_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
int ret = -ENOTTY;
int time;
void __user *argp = (void __user *)arg;
int __user *p = argp;
switch (cmd) {
case WDIOC_GETSUPPORT:
ret = copy_to_user(argp, &at32_wdt_info,
sizeof(at32_wdt_info)) ? -EFAULT : 0;
break;
case WDIOC_GETSTATUS:
ret = put_user(0, p);
break;
case WDIOC_GETBOOTSTATUS:
ret = put_user(wdt->boot_status, p);
break;
case WDIOC_SETOPTIONS:
ret = get_user(time, p);
if (ret)
break;
if (time & WDios_DISABLECARD)
at32_wdt_stop();
if (time & WDIOS_ENABLECARD)
at32_wdt_start();
ret = 0;
break;
case WDIOC_KEEPALIVE:
at32_wdt_pat();
ret = 0;
break;
case WDIOC_SETTIMEOUT:
ret = get_user(time, p);
if (ret)
break;
ret = at32_wdt_settimeout(time);
if (ret)
break;
/* Enable new time value */
at32_wdt_start();
/* fall through */
case WDIOC_GETTIMEOUT:
ret = put_user(wdt->timeout, p);
break;
}
return ret;
}
上面就是函数的样子,这里能够看到主要的命令就是
wdt_settimeout 设置看门狗的最长喂狗时间
wdt_keepalive 喂狗函数命令
他们都相应了自己的函数,这样就能够在上层进行调用了。
接着向下分析。wdt_settimeout
get_user(time, p);
if (ret)
break;
ret = at32_wdt_settimeout(time);
if (ret)
break;
/* Enable new time value */
at32_wdt_start();
调用了三个函数 依次的作用是
get_user(time, p); 查看状态
at32_wdt_settimeout(time); 设置时间间隔
at32_wdt_start();势能看门狗
函数还是能从名字看出来作用的
喂狗函数相同的就是at32_wdt_pat()
这里走进去看一下 static inline void at32_wdt_pat(void)
{
spin_lock(&wdt->io_lock);
wdt_writel(wdt, CLR, 0x42);
spin_unlock(&wdt->io_lock);
}
这里就能看出来就是想clr寄存器里面写一个0x42就等于是喂狗了
再来看看其它的函数吧
static int at32_wdt_settimeout(int time)
{
/*
* All counting occurs at 1 / SLOW_CLOCK (32 kHz) and max prescaler is
* 2 ^ 16 allowing up to 2 seconds timeout.
*/
if ((time < TIMEOUT_MIN) || (time > TIMEOUT_MAX))
return -EINVAL;
/*
* Set new watchdog time. It will be used when at32_wdt_start() is
* called.
*/
wdt->timeout = time;
return 0;
}
设置时间的函数就是推断一下时间是不是超出范围了 假设没有就设置下去好了
start就不看了 就是启动之前检測一下是不是重新启动时间有没有设置 没有的话就设置一个最大值
重点看一下关闭函数
static int at32_wdt_close(struct inode *inode, struct file *file)
{
if (expect_release == 42) {
at32_wdt_stop();
} else {
dev_dbg(wdt->miscdev.parent,
"unexpected close, not stopping watchdog!\n");
at32_wdt_pat();
}
clear_bit(1, &wdt->users);
expect_release = 0;
return 0;
}
这里能够看到wdt 是一旦打开就不能关闭的 这样也是符合常理的 假设能够关闭 也就失去了存在的意义了 。存在被攻击的可能。
下一次解释下ioctl的方法
以上是关于具体解释kernel中watchdog 驱动程序的主要内容,如果未能解决你的问题,请参考以下文章
活久见 kernel:NMI watchdog: BUG: soft lockup - CPU#8 stuck for 28s! [xsoftdd/12:0]
基于S3C2440的嵌入式Linux驱动——看门狗(watchdog)驱动解读