pxues 发表于 2009-11-23 15:47

求助 linux按键驱动程序调试,请各位大侠指点一下

#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_BUF16
   
#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 {
    // struct cdev *cdev;
    unsigned int buttonStatus;      //....
    unsigned char buf; //.....
    unsigned int head,tail;         //........
    wait_queue_head_t wq;         //....
} BUTTON_DEV;

static BUTTON_DEV buttondev;

#define BUF_HEAD    (buttondev.buf)   //....
#define BUF_TAIL    (buttondev.buf)   //....
#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,
};


structcdev *button_dev;
structclass *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_EINT8);
        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=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);




在测试中没有按按键时,驱动程序不停地中断,怎么回事?
没有
页: [1]
查看完整版本: 求助 linux按键驱动程序调试,请各位大侠指点一下