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