|
楼主 |
发表于 2006-6-30 16:32:03
|
显示全部楼层
cpu:at91rm9200
linux:2.4
driver:misc,源码在下边
user code:
for(;;)
{
ret=ioctl(fd,WDIOC_KEEPALIVE,&g1);
printf("ret=%d\n",ret);
}
按说显示一个3后显示ret=0,这样循环,
但是,结果是:
3
3
3
3
3
3
3
3
3
3
3
3
ret=0ret=0ret=0ret=0ret=0ret=0ret=0ret=0ret=0ret=0ret=0ret=0
3
3
3
3
3
3
3
3
3
3
3
3
ret=0ret=0ret=0ret=0ret=0ret=0ret=0ret=0ret=0ret=0ret=0ret=0
3
3
3
3
3
3
3
3
3
3
3
3
ret=0ret=0ret=0ret=0ret=0ret=0ret=0ret=0ret=0ret=0ret=0ret=0
各位帮忙分析一下
#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/sched.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/pm.h>
#include <linux/miscdevice.h>
#include <linux/poll.h>
#include <asm/dma.h>
#include <asm/semaphore.h>
#include <asm/uaccess.h>
#include <asm/hardware.h>
#define WATCHDOG_MINOR 131 //misc次设备号
#define WDIOC_GETSTATUS 1
#define WDIOC_GETBOOTSTATUS 2
#define WDIOC_KEEPALIVE 3
#define WDIOC_SETTIMEOUT 4
#define WDIOC_GETTIMEOUT 5
static int timeout=3;
static int timer_alive=0;
//static int testmode;
#define TIMER_MARGIN 60 /* (secs) Default is 1 minute */
static int soft_margin = TIMER_MARGIN; /* in seconds */
static void watchdog_ping(void)
{
/*
* Refresh the timer.
*/
}
/*
* Allow only one person to hold it open
*/
//wdt设备打开操作
static int wdt977_open(struct inode *inode, struct file *file)
{
if(timer_alive) //计数器,当wdt被启用后进制重复打开!
return -EBUSY;
#ifdef CONFIG_WATCHDOG_NOWAYOUT
MOD_INC_USE_COUNT;
#endif
timer_alive++;
//max timeout value = 255 minutes (0xFF). Write 0 to disable WatchDog.
if( timeout>255 )
timeout=255;
// printk("Watchdog: active, current timeout %d min.\n",timeout);
return 0;
}
//wdt的关闭操作
static int wdt977_release(struct inode *inode, struct file *file)
{
/*
* Shut off the timer.
* Lock it in if it's a module and we defined ...NOWAYOUT
*/
#ifndef CONFIG_WATCHDOG_NOWAYOUT
lock_kernel();
timer_alive=0;
unlock_kernel();
// printk("Watchdog: shutdown.\n");
#endif
// printk("Watchdog: shutdown.\n");
timer_alive=0;
return 0;
}
//在这里wdt的写就是“喂狗”操作
static ssize_t wdt977_write(struct file *file, const char *data, size_t len, loff_t *ppos)
{
//max timeout value = 255 minutes (0xFF). Write 0 to disable WatchDog.
if (timeout>255)
timeout=255;
/*
* Refresh the timer.
*/
//we have a hw bug somewhere, so each 977 minute is actually only 30sec
//as such limit the max timeout to half of max of 255 minutes...
// if (timeout>126)
// timeout = 126;
return 1;
}
struct wd
{
int a;
int b;
int c;
};
static struct wd wd2;
//wdt的ioctl函数
static int watchdog_ioctl( struct inode *inode, struct file *file,unsigned int cmd, unsigned long arg )
{
int i, new_margin;
int ret=0;
/*
static struct watchdog_info ident=
{
WDIOF_SETTIMEOUT,
0,
"Footbridge Watchdog"
};
*/
switch( cmd )
{
default:
return -ENOTTY;
/*
case WDIOC_GETSUPPORT:
i = verify_area(VERIFY_WRITE, (void*) arg, sizeof(struct watchdog_info));
if (i)
return i;
else
return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident));
*/
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
// printk("1\n");
return put_user(1,(int *)arg);
case WDIOC_KEEPALIVE:
watchdog_ping();
printk("3\n");
return 0;
case WDIOC_SETTIMEOUT:
// printk("4\n");
if (get_user(new_margin, (int *)arg))
return -EFAULT;
/* Arbitrary, can't find the card's limits */
if ((new_margin < 0) || (new_margin > 60))
return -EINVAL;
// soft_margin = new_margin;
watchdog_ping();
/* Fall */
return 0;
case WDIOC_GETTIMEOUT:
if (copy_from_user(&wd2, (struct wd *) arg, sizeof(wd2)))
ret = -EFAULT;
// printk("%d\n",wd2.a);
// printk("%d\n",wd2.b);
// printk("%d\n",wd2.c);
// printk("5\n");
wd2.a=5;wd2.b=7;wd2.c=9;
return copy_to_user((void *) arg, &wd2, sizeof(wd2));
return put_user(soft_margin, (int *)arg);
}
}
//定义fops结构,开发驱动对struct file_operations 再熟悉不过了。
//函数的入口很简单,这就是为什么采用misc的原因了
static struct file_operations wdt977_fops=
{
owner: THIS_MODULE,
write: wdt977_write,
open: wdt977_open,
ioctl: watchdog_ioctl,
release: wdt977_release,
};
//根据misc驱动模型要求,定义miscdevice 结构体
static struct miscdevice wdt977_miscdev=
{
minor: WATCHDOG_MINOR,
name: "wd",
fops: &wdt977_fops,
};
static int __init nwwatchdog_init(void)
{
// if (!machine_is_netwinder())
// return -ENODEV;
misc_register(&wdt977_miscdev); //注册设备驱动
// printk("NetWinder Watchdog sleeping.\n");
return 0;
}
static void __exit nwwatchdog_exit(void)
{
misc_deregister(&wdt977_miscdev); //卸载设备驱动
}
EXPORT_NO_SYMBOLS;
module_init(nwwatchdog_init);
module_exit(nwwatchdog_exit);
//MODULE_LICENSE("GPL"); |
|