请教一下,我在linux下编写watchdog的驱动程序,使用linux内核中的sa1100-wdt.c做了修改,可是不管是修改 static int margin __initdata = 60 还是 #define OSCR_FREQ CLOCK_TICK_RATE的值在不喂狗的情况下watchdog总是在60秒后reset 究竟是什么原因呢?以下是我的程序: #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/miscdevice.h> #include <linux/init.h>
#ifdef CONFIG_ARCH_PXA #include <asm/arch/pxa-regs.h> #endif
#include <asm/hardware.h> #include <asm/bitops.h> #include <asm/uaccess.h> //#include <asm/sa-1100.h>
#define OSCR_FREQ 3250000//CLOCK_TICK_RATE
#define WDIOC_SETTIMEOUT 1 #define WDIOC_GETTIMEOUT 2 #define WDIOC_KEEPALIVE 3 //static unsigned long pxa3xxwdt_users; unsigned long pre_margin;
//static int boot_status;
/* * Allow only one person to hold it open */ static int pxa3xx_watchdog_open(struct inode *inode, struct file *file) { // nonseekable_open(inode, file); /*if (test_and_set_bit(1,&pxa3xxwdt_users)) return -EBUSY;*/ /* Activate SA1100 Watchdog timer */ OSMR3 = OSCR + pre_margin; OSSR = OSSR_M3; OWER = OWER_WME; OIER |= OIER_E3; printk(KERN_EMERG "device is open
"); return 0; }
/* * The watchdog cannot be disabled. * * Previous comments suggested that turning off the interrupt by * clearing OIER[E3] would prevent the watchdog timing out but this * does not appear to be true (at least on the PXA255). */ static int pxa3xx_watchdog_release(struct inode *inode, struct file *file) { printk(KERN_CRIT "WATCHDOG: Device closed - timer will not stop
"); OWER = ~OWER_WME; //clear_bit(1, &pxa3xxwdt_users); return 0; }
/*static struct watchdog_info ident = { .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, .identity = "SA1100/PXA255 Watchdog", }; */ static int pxa3xx_watchdog_ioctl(struct inode *inode, 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(&arg, &ident,sizeof(ident)) ? -EFAULT : 0; break;*/ case WDIOC_SETTIMEOUT: ret = get_user(time, &arg); if (ret) break; if (time <= 0 || time > 255) { ret = -EINVAL; break; } pre_margin = OSCR_FREQ*time; OSMR3 = OSCR + pre_margin; printk(KERN_EMERG "pre_margin=%d
",pre_margin); /*fall through*/ case WDIOC_GETTIMEOUT: ret = put_user(pre_margin / OSCR_FREQ, &arg); break; case WDIOC_KEEPALIVE: OSMR3 = OSCR + pre_margin; ret = 0; break; } return ret; }
static const struct file_operations pxa3xx_watchdog_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .ioctl = pxa3xx_watchdog_ioctl, .open = pxa3xx_watchdog_open, .release = pxa3xx_watchdog_release, };
static struct miscdevice pxa3xx_watchdog_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &pxa3xx_watchdog_fops, };
int margin = 10; //__initdata = 60; /* (secs) Default is 1 minute */
static int __init pxa3xx_watchdog_init(void) { int ret; pre_margin=OSCR_FREQ * margin; ret = misc_register(&pxa3xx_watchdog_miscdev); if (ret == 0) printk(KERN_EMERG "initial succeed!
"); return 0; }
static void __exit pxa3xx_watchdog_exit(void) { misc_deregister(&pxa3xx_watchdog_miscdev); }
module_init(pxa3xx_watchdog_init); module_exit(pxa3xx_watchdog_exit);
觉得有点奇怪,请指教一下,谢谢
|