idea6410看门狗watchdog移植及喂狗

//--------------------------------------------------------------------------------------------

// 作者:longtian635241(longtian_huang@urbetter.com

// 论坛ID:idea6410

// 版权:idea6410

// 平台:友坚idea6410开发板

// 发布日期:2012-11-22

// 最后修改:2012-11-22

//

//----------------------------------------------------------------------------------------------

 

linux-3.6.6其实已经有看门狗驱动了,即H:\VM share\linux-3.6.6\drivers\watchdog\s3c2410_wdt.c;只需配置就可用了!

【1】在内核中配置看门狗驱动

在内核源代码目录执行:make menuconfig,进入内核配置主菜单,依次选择进入如下子菜单:

Device Drivers --->
[*] Watchdog Timer Support --->

<*> S3C2410 Watchdog

 

/

   在drivers/watchdog/s3c2410_wdt.c中进行修改:

  1. #define CONFIG_S3C2410_WATCHDOG_ATBOOT      (1)  
  2. #define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME    (15)  
#define CONFIG_S3C2410_WATCHDOG_ATBOOT		(1)
#define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME	(15)


 

注:

  1. #define CONFIG_S3C2410_WATCHDOG_ATBOOT      (0)//系统启动时不开启看门狗  
  2. #define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME    (15)//复位时间  

///可以不必修改!

启动显示:

s3c2410-wdt s3c2410-wdt: watchdog inactive, reset disabled, irq enabled

 

 

 

 

【2】关于打开和关闭看门狗

在看门狗驱动程序中,我们注意到有这样一个函数,注意其中的蓝色粗体部分字体:

#define PFX "s3c2410-wdt: "
#define CONFIG_S3C2410_WATCHDOG_ATBOOT (0)
//这里表明看门狗的默认时间是15 秒,如果超过此时间系统将自行重启
#define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME (15)
static ssize_t s3c2410wdt_write(struct file *file, const char __user *data,
size_t len, loff_t *ppos)
{
/*
* Refresh the timer.
*/
if (len) {
if (!nowayout) {
size_t i;
/* In case it was set long ago */
expect_close = 0;
for (i = 0; i != len; i++) {
char c;
if (get_user(c, data + i))
return -EFAULT;
if (c == 'V')
expect_close = 42;
}
}
s3c2410wdt_keepalive();
}
return len;
}

根据此代码,我们判定可以在打开看门狗设备(/dev/watchdog)之后不断的向看门狗随便写入写入一些数据以实现喂狗操作,但是,当写入“V“时,就可以关闭看门狗了。

原因分析:

open函数:

  1. static int s3c2410wdt_open(struct inode *inode, struct file *file)  
  2. {  
  3.     if (test_and_set_bit(0, &open_lock))  
  4.         return -EBUSY;  
  5.   
  6.     if (nowayout)  
  7.         __module_get(THIS_MODULE);  
  8.   
  9.     expect_close = 0;  
  10.   
  11.     /* start the timer */  
  12.     s3c2410wdt_start();  
  13.     return nonseekable_open(inode, file);  
  14. }  
static int s3c2410wdt_open(struct inode *inode, struct file *file)
{
	if (test_and_set_bit(0, &open_lock))
		return -EBUSY;

	if (nowayout)
		__module_get(THIS_MODULE);

	expect_close = 0;

	/* start the timer */
	s3c2410wdt_start();
	return nonseekable_open(inode, file);
}


release函数:

  1. static int s3c2410wdt_release(struct inode *inode, struct file *file)  
  2. {  
  3.     /* 
  4.      *  Shut off the timer. 
  5.      *  Lock it in if it's a module and we set nowayout 
  6.      */  
  7.   
  8.     if (expect_close == 42)  
  9.         s3c2410wdt_stop();  
  10.     else {  
  11.         dev_err(wdt_dev, "Unexpected close, not stopping watchdog\n");  
  12.         s3c2410wdt_keepalive();  
  13.     }  
  14.     expect_close = 0;  
  15.     clear_bit(0, &open_lock);  
  16.     return 0;  
  17. }  
static int s3c2410wdt_release(struct inode *inode, struct file *file)
{
	/*
	 *	Shut off the timer.
	 * 	Lock it in if it's a module and we set nowayout
	 */

	if (expect_close == 42)
		s3c2410wdt_stop();
	else {
		dev_err(wdt_dev, "Unexpected close, not stopping watchdog\n");
		s3c2410wdt_keepalive();
	}
	expect_close = 0;
	clear_bit(0, &open_lock);
	return 0;
}


write函数:

  1. static ssize_t s3c2410wdt_write(struct file *file, const char __user *data,  
  2.                 size_t len, loff_t *ppos)  
  3. {  
  4.     /* 
  5.      *  Refresh the timer. 
  6.      */  
  7.     if (len) {  
  8.         if (!nowayout) {  
  9.             size_t i;  
  10.   
  11.             /* In case it was set long ago */  
  12.             expect_close = 0;  
  13.   
  14.             for (i = 0; i != len; i++) {  
  15.                 char c;  
  16.   
  17.                 if (get_user(c, data + i))  
  18.                     return -EFAULT;  
  19.                 if (c == 'V')  
  20.                     expect_close = 42;  
  21.             }  
  22.         }  
  23.         s3c2410wdt_keepalive();  
  24.     }  
  25.     return len;  
  26. }  
static ssize_t s3c2410wdt_write(struct file *file, const char __user *data,
				size_t len, loff_t *ppos)
{
	/*
	 *	Refresh the timer.
	 */
	if (len) {
		if (!nowayout) {
			size_t i;

			/* In case it was set long ago */
			expect_close = 0;

			for (i = 0; i != len; i++) {
				char c;

				if (get_user(c, data + i))
					return -EFAULT;
				if (c == 'V')
					expect_close = 42;
			}
		}
		s3c2410wdt_keepalive();
	}
	return len;
}


 

   看门狗只能被一个进程打开,打开函数中先判断了一下,然后启动了看门狗;再看write函数,写入的如果是V则允许关闭看门狗,如果不是V仅仅喂狗一次;最后是release函数,如果允许关闭则关闭看门狗,如果不允许关闭,打印"Unexpectedclose, not stopping watchdog",喂狗一次。此时看门狗并没有关闭,所以系统会复位的,如果输入V则看门狗被关闭,这样系统就不复位了。

 

 

【3】测试看门狗

根据上面的分析,我们可以使用 echo 命令向/dev/watchdog 设备随便写入一些数据即可开启看门狗,比如:echo 0 > /dev/watchdog,如下:

[root@zxj /]#echo 0 > /dev/watchdog
s3c2410-wdt s3c2410-wdt: Unexpected close, not stopping watchdog
[root@zxj /]#

此时,如果静等 15 秒钟,系统将会自动重启,这样就证实了看门狗已经被开启了。如果 15 秒之内,我们不停地重复“喂狗”操作,也就是不停的使用echo 命令向看门狗写入数据,那么系统就不会重启。那么,如何停止看门狗呢?根据上面的分析,只要写入“V”就可以了。需要知道的是,但我们使用echo 命令向/dev/watchdog 写入数据的时候,同时也把“回车”给送进去了,因此可以这样操作:echo -n V >/dev/watchdog这里的“-n”意思是“去掉回车”,为了测试,你可以先输入:
echo 0 > /dev/watchdog
接着再输入:
echo –n V > /dev/watchdog
然后接着静等,过了好久,系统依然在正常运行,这就证明了看门狗已经被关闭了。

设置成系统启动就启动看门狗,并且看门狗到期时间为15s。这样系统复位后每15s系统就会复位一次,所以我们在用户空间进行喂狗,驱动中的那个中断函数是当看门狗作为定时器时用的,所以没有实现喂狗,所以只能在用户程序中喂狗,下面是源码:
  1. #include <stdio.h>    
  2. #include <unistd.h>    
  3. #include <sys/stat.h>    
  4. #include <sys/types.h>    
  5. #include <fcntl.h>    
  6. #include <stdlib.h>    
  7. #include <errno.h>    
  8. #include <linux/watchdog.h>    
  9.     
  10. int main(int argc, char **argv){    
  11.     int fd;    
  12.     fd = open("/dev/watchdog",O_RDONLY);    
  13.     if(fd < 0){    
  14.         perror("/dev/watchdog");    
  15.         return -1;    
  16.     }    
  17.     for(;;){    
  18.         ioctl(fd, WDIOC_KEEPALIVE);    
  19.         sleep(3);    
  20.     }    
  21.     close(fd);    
  22.     return 0;    
  23. }  
#include <stdio.h>  
#include <unistd.h>  
#include <sys/stat.h>  
#include <sys/types.h>  
#include <fcntl.h>  
#include <stdlib.h>  
#include <errno.h>  
#include <linux/watchdog.h>  
  
int main(int argc, char **argv){  
    int fd;  
    fd = open("/dev/watchdog",O_RDONLY);  
    if(fd < 0){  
        perror("/dev/watchdog");  
        return -1;  
    }  
    for(;;){  
        ioctl(fd, WDIOC_KEEPALIVE);  
        sleep(3);  
    }  
    close(fd);  
    return 0;  
}

编译:

  1. arm-linux-gcc wdt.c -o wdt  
arm-linux-gcc -o Feed-watchdog Feed-watchdog.c

   把Feed-watchdog拷贝到/bin/下,并修改root-2.6.38/etc/init.d/rcS文件,添加Feed-watchdog&这么一句,让系统启动后这个应用程序在后台运行。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值