免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2006 | 回复: 2
打印 上一主题 下一主题

求助 linux按键驱动程序调试,请各位大侠指点一下 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-11-23 15:50 |只看该作者 |倒序浏览
#include <linux/sched.h>
#include <linux/init.h>                                                                                  
#include <asm/hardware.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/time.h>
#include <linux/slab.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <linux/ioctl.h>
#include <asm/ioctl.h>
#include <linux/cdev.h>
#include <asm-arm/arch-s3c2410/regs-gpio.h>

#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h>
#include <linux/device.h>

#define     BUTTON_IRQ1 IRQ_EINT8
#define     BUTTON_IRQ2 IRQ_EINT9
#define     BUTTON_IRQ3 IRQ_EINT10
#define     BUTTON_IRQ4 IRQ_EINT11
#define     BUTTON_IRQ5 IRQ_EINT13
#define DEVICE_NAME "button"
static int buttonMajor=0;
static int button_minor=0;
#define     BUTTONMINOR 0
#define     MAX_BUTTON_BUF  16
   
#define BUTTONSTATUS_1      8
#define BUTTONSTATUS_2      9
#define BUTTONSTATUS_3      10
#define BUTTONSTATUS_4      11
#define BUTTONSTATUS_5      13

static unsigned char buttonRead(void);
static int flag=0;

typedef struct {
    unsigned int buttonStatus;      //....
    unsigned char buf[MAX_BUTTON_BUF]; //.....
    unsigned int head,tail;         //........
    wait_queue_head_t wq;           //....
} BUTTON_DEV;

static BUTTON_DEV buttondev;

#define BUF_HEAD    (buttondev.buf[buttondev.head])     //....
#define BUF_TAIL    (buttondev.buf[buttondev.tail])     //....
#define INCBUF(x,mod)   ((++(x)) & ((mod)-1))       //.......

static void (*buttonEvent)(void);

static void buttonEvent_dummy(void) {}

static void buttonEvent_1(void)
{
    if(buttondev.buttonStatus==BUTTONSTATUS_5) {
    BUF_HEAD=BUTTONSTATUS_5;
     }

    if(buttondev.buttonStatus==BUTTONSTATUS_4) {
    BUF_HEAD=BUTTONSTATUS_4;
     }

    if(buttondev.buttonStatus==BUTTONSTATUS_3) {
    BUF_HEAD=BUTTONSTATUS_3;
     }

    if(buttondev.buttonStatus==BUTTONSTATUS_2) {
    BUF_HEAD=BUTTONSTATUS_2;
     }
    if(buttondev.buttonStatus==BUTTONSTATUS_1) {
    BUF_HEAD=BUTTONSTATUS_1;
     }

    buttondev.head=INCBUF(buttondev.head,MAX_BUTTON_BUF);
    flag=1;
    wake_up_interruptible(&(buttondev.wq));
    }

static irqreturn_t isr_button(int irq,void *dev_id,struct pt_regs *regs)
{
    switch (irq) {
    case BUTTON_IRQ1:buttondev.buttonStatus=BUTTONSTATUS_1;
                break;
    case BUTTON_IRQ2:buttondev.buttonStatus=BUTTONSTATUS_2;
                break;
    case BUTTON_IRQ3:buttondev.buttonStatus=BUTTONSTATUS_3;
                break;
    case BUTTON_IRQ4:buttondev.buttonStatus=BUTTONSTATUS_4;
                break;
    case BUTTON_IRQ5:buttondev.buttonStatus=BUTTONSTATUS_5;
                break;
    default:break;
     }
   
    buttonEvent();
    return 0;
}

static int button_open(struct inode *inode,struct file *filp)
{
    int ret;
    buttondev.head=buttondev.tail=0;
    buttonEvent=buttonEvent_1;  
    ret=request_irq(BUTTON_IRQ1,isr_button,IRQF_DISABLED,DEVICE_NAME,NULL);
    if(ret) {
    printk("BUTTON_IRQ1: could not register interrupt\n";
    return ret;
     }
    ret=request_irq(BUTTON_IRQ2,isr_button,IRQF_DISABLED,DEVICE_NAME,NULL);
    if(ret) {
    printk("BUTTON_IRQ2: could not register interrupt\n";
    return ret;
     }
    ret=request_irq(BUTTON_IRQ3,isr_button,IRQF_DISABLED,DEVICE_NAME,NULL);
    if(ret) {
    printk("BUTTON_IRQ3: could not register interrupt\n";
    return ret;
     }
    ret=request_irq(BUTTON_IRQ4,isr_button,IRQF_DISABLED,DEVICE_NAME,NULL);
    if(ret) {
    printk("BUTTON_IRQ4: could not register interrupt\n";
    return ret;
     }
    ret=request_irq(BUTTON_IRQ5,isr_button,IRQF_DISABLED,DEVICE_NAME,NULL);
    if(ret) {
    printk("BUTTON_IRQ5: could not register interrupt\n";
    return ret;
     }


    return 0;
}

static int button_release(struct inode *inode,struct file *filp)
{
    buttonEvent=buttonEvent_dummy;
    free_irq(BUTTON_IRQ1,NULL);
    free_irq(BUTTON_IRQ2,NULL);
    free_irq(BUTTON_IRQ3,NULL);
    free_irq(BUTTON_IRQ4,NULL);
    free_irq(BUTTON_IRQ5,NULL);
    return 0;
}

static ssize_t button_read(struct file *filp,char __user  *buffer,size_t count,loff_t *ppos)
{
     int button_ret=0;
retry:
      if(buttondev.head!=buttondev.tail) {
    button_ret=buttonRead();
    copy_to_user(buffer,&button_ret,sizeof(int));
       return sizeof(int);
     }

    else {
    if(filp->f_flags & O_NONBLOCK)
        return -EAGAIN;

   
    wait_event_interruptible(buttondev.wq,flag);
    flag=0;
       if(signal_pending(current))
         {
      printk("rturn -ERESTARTSYS\n";
        return -ERESTARTSYS;
          }
    goto retry;
     }

    return sizeof(int);
}

static struct file_operations button_fops= {
    .owner  =   THIS_MODULE,
    .open   =   button_open,
    .read   =   button_read,
    .release    =   button_release,
};


struct  cdev *button_dev;
struct  class *button_class;
static int __init s3c2410_button_init(void)
{
    int ret,err;
    dev_t dev,devno;
        s3c2410_gpio_pullup(S3C2410_GPG0,1);
        s3c2410_gpio_pullup(S3C2410_GPG1,1);
               s3c2410_gpio_pullup(S3C2410_GPG2, 1);
               s3c2410_gpio_pullup(S3C2410_GPG3,1);
        s3c2410_gpio_pullup(S3C2410_GPG5,1);
        s3c2410_gpio_cfgpin(S3C2410_GPG0, S3C2410_GPG0_EINT;  
        s3c2410_gpio_cfgpin(S3C2410_GPG1, S3C2410_GPG1_EINT9);  
        s3c2410_gpio_cfgpin(S3C2410_GPG2, S3C2410_GPG2_EINT10);  
        s3c2410_gpio_cfgpin(S3C2410_GPG3, S3C2410_GPG3_EINT11);  
        s3c2410_gpio_cfgpin(S3C2410_GPG5, S3C2410_GPG5_EINT13);  

       

        set_irq_type(BUTTON_IRQ1,IRQT_FALLING);
        set_irq_type(BUTTON_IRQ2,IRQT_FALLING);
        set_irq_type(BUTTON_IRQ3,IRQT_FALLING);
        set_irq_type(BUTTON_IRQ4,IRQT_FALLING);
        set_irq_type(BUTTON_IRQ5,IRQT_FALLING);
       
    buttonEvent=buttonEvent_dummy;

if(buttonMajor){
                dev = MKDEV(buttonMajor,button_minor);
                ret = register_chrdev_region(dev,1,"button";
        }else{
                ret = alloc_chrdev_region(&dev,buttonMajor,1,"button";
                buttonMajor=MAJOR(dev);
        }
        if(ret < 0){
                printk(KERN_WARNING"button:can't get mjor %d\n",buttonMajor);
                return ret;
        }
        devno = MKDEV(buttonMajor,0);
        button_dev=cdev_alloc();
        cdev_init(button_dev,&button_fops);
        button_dev->owner=THIS_MODULE;
        button_dev->ops=&button_fops;
        err=cdev_add(button_dev,devno,1);
        if(err){
                printk("Error %d adding button",err);       
                //return -1;
        }
        button_class=class_create(THIS_MODULE,"button_class";
        if(IS_ERR(button_class)){
                printk("Err: failed in creating class.\n";
          return  -1;
        }
        device_create(button_class, NULL, MKDEV(buttonMajor,button_minor), DEVICE_NAME "%d",button_minor);
        buttonMajor=ret;
    buttondev.head=buttondev.tail=0;
       buttondev.buttonStatus=BUTTONSTATUS_1;
    init_waitqueue_head(&(buttondev.wq));
    return 0;
}

static unsigned char buttonRead(void)
{
    unsigned long flags;
    unsigned char button_ret;
     local_irq_save(flags);
    button_ret=BUF_TAIL;
    buttondev.tail=INCBUF(buttondev.tail,MAX_BUTTON_BUF);
     local_irq_restore(flags);
    return button_ret;
}
   
static void __exit s3c2410_button_eixt(void)
{


cdev_del(button_dev);
        device_destroy(button_class, MKDEV(buttonMajor,button_minor));
        class_destroy(button_class);
        unregister_chrdev_region(MKDEV (buttonMajor,button_minor), button_dev);
}

MODULE_LICENSE("GPL");
MODULE_AUTHOR("llg");

module_init(s3c2410_button_init);
module_exit(s3c2410_button_eixt);


测试时候,没有按按键时候,驱动程序不停中断,怎么回事?
用万能表测试,驱动初始化,电压为0v,没有按按键时候,电压也为0v,按按键时,电压为3.3v
请各位大侠指点一下,谢谢!

论坛徽章:
0
2 [报告]
发表于 2009-11-25 14:03 |只看该作者
中断处理函数如果执行default语句,就应该跳过buttonEvent()函数直接return

论坛徽章:
5
摩羯座
日期:2014-07-22 09:03:552015元宵节徽章
日期:2015-03-06 15:50:392015亚冠之大阪钢巴
日期:2015-06-12 16:01:352015年中国系统架构师大会
日期:2015-06-29 16:11:2815-16赛季CBA联赛之四川
日期:2018-12-17 14:10:21
3 [报告]
发表于 2009-11-26 10:36 |只看该作者

一堆表情
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP