QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1474|回复: 1

at91 驱动 返回慢

[复制链接]
发表于 2006-6-30 09:36:13 | 显示全部楼层 |阅读模式
我有一块at91rm9200的板子,写了个看门狗的模拟驱动程序,
就是多次IOCTL时返回很慢,各位知道原因吗?
 楼主| 发表于 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");
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-23 03:54 , Processed in 0.040618 second(s), 16 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表