api #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <sys/time.h> main() { int fd; int counter = 0; int old_counter = 0; fd = open("/dev/irq", 0); if(fd<0)printf("fail to open api !!!/n"); if(fd>0)printf("open api ok !!! /n"); while(1) { read(fd,&counter,sizeof(int)); printf("irq counter is = %d /n",counter); sleep(1); } close(fd); printf("close api !! /n"); } 驱动程序 #include <linux/module.h> #include <linux/types.h> #include <linux/fs.h> #include <linux/errno.h> #include <linux/mm.h> #include <linux/sched.h> #include <linux/init.h> #include <linux/cdev.h> #include <asm/io.h> #include <asm/system.h> #include <asm/uaccess.h>//copy_to_user #include <linux/timer.h> /*包括timer.h头文件*/ #include <asm/atomic.h> #include<mach/regs-gpio.h> #include<mach/hardware.h> #include<linux/delay.h> #include<linux/interrupt.h> #include<mach/irqs.h> //IRQ_EINT1 #include<linux/workqueue.h> #define IRQ_MAJOR 249 /*预设的second的主设备号*/ static int irq_major = IRQ_MAJOR; volatile int value=0; void gpio_init(void) { s3c2410_gpio_cfgpin(S3C2410_GPB5,S3C2410_GPB5_OUTP); s3c2410_gpio_cfgpin(S3C2410_GPB6,S3C2410_GPB6_OUTP); s3c2410_gpio_cfgpin(S3C2410_GPB7,S3C2410_GPB7_OUTP); s3c2410_gpio_cfgpin(S3C2410_GPB8,S3C2410_GPB8_OUTP); s3c2410_gpio_cfgpin(S3C2410_GPF1,S3C2410_GPF1_EINT1); printk("open gpio_init ok !!/n"); } /*second设备结构体*/ struct irq_dev { struct cdev cdev; /*cdev结构体*/ atomic_t counter;/* 一共经历了多少秒?*/ struct timer_list s_timer; /*设备要使用的定时器*/ }; static struct work_struct irq_wq; struct irq_dev *irq_devp; /*设备结构体指针*/ void irq_do_work() { printk("irq_do_work ok /n"); value++; // printk("irq_do_work count = %d /n",value); } /*定时器处理函数*/ static irqreturn_t irq_handle(int irq,void *dev_id) { // value++; // printk("irq_handle counter is = %d/n",value); printk("irq_handle ok /n"); schedule_work(&irq_wq); return IRQ_RETVAL(IRQ_HANDLED); } /*文件打开函数*/ int irq_open(struct inode *inode, struct file *filp) { /*初始化定时器*/ int i=0; int result; for(i=1;i<6;i++) { s3c2410_gpio_setpin(S3C2410_GPB8,1); s3c2410_gpio_setpin(S3C2410_GPB7,1); s3c2410_gpio_setpin(S3C2410_GPB6,1); s3c2410_gpio_setpin(S3C2410_GPB5,1); printk("irq_open count %d /n",i);ssleep(1); s3c2410_gpio_setpin(S3C2410_GPB8,0); s3c2410_gpio_setpin(S3C2410_GPB7,0); s3c2410_gpio_setpin(S3C2410_GPB6,0); s3c2410_gpio_setpin(S3C2410_GPB5,0);ssleep(1); } result=request_irq(IRQ_EINT1,irq_handle,IRQF_TRIGGER_FALLING,"KEY1",NULL); if(result==0)printk("request_irq ok /n "); else { free_irq(IRQ_EINT1,NULL); printk("request_irq fail /n"); } INIT_WORK(&irq_wq,irq_do_work); printk("hello irq_open !!!/n"); return 0; } /*文件释放函数*/ int irq_release(struct inode *inode, struct file *filp) { free_irq(IRQ_EINT1,NULL); printk("irq_release ok /n"); return 0; } /*读函数*/ static ssize_t irq_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) { if(copy_to_user(buf,&value,1))printk("irq_read fail /n"); else printk("irq_read ok /n "); return 0; } /*文件操作结构体*/ static const struct file_operations irq_fops = { .owner = THIS_MODULE, .open = irq_open, .release = irq_release, .read =irq_read, }; /*初始化并注册cdev*/ static void irq_setup_cdev(struct irq_dev *dev, int index) { int err, devno = MKDEV(irq_major, index); cdev_init(&dev->cdev, &irq_fops); dev->cdev.owner = THIS_MODULE; dev->cdev.ops = &irq_fops; err = cdev_add(&dev->cdev, devno, 1); if (err) printk(KERN_NOTICE "Error %d adding LED%d", err, index); else printk("cdev_add ok !!!/n"); } /*设备驱动模块加载函数*/ int irq_init(void) { int ret; dev_t devno = MKDEV(irq_major, 0); /* 申请设备号*/ if (irq_major) { ret = register_chrdev_region(devno, 1, "AAAA"); printk("register_chredev_region ok !!!/n"); } else /* 动态申请设备号 */ { ret = alloc_chrdev_region(&devno, 0, 1, "AAAA"); irq_major = MAJOR(devno); } if (ret < 0) return ret; /* 动态申请设备结构体的内存*/ irq_devp = kmalloc(sizeof(struct irq_dev), GFP_KERNEL); if (!irq_devp) /*申请失败*/ { ret = - ENOMEM; goto fail_malloc; } else {printk("kmalloc ok !!!/n");} memset(irq_devp, 0, sizeof(struct irq_dev)); irq_setup_cdev(irq_devp, 0); gpio_init(); // INIT_WORK(&irq_wq,irq_do_work); return 0; fail_malloc: unregister_chrdev_region(devno, 1); } /*模块卸载函数*/ void irq_exit(void) { cdev_del(&irq_devp->cdev); /*注销cdev*/ kfree(irq_devp); /*释放设备结构体内存*/ unregister_chrdev_region(MKDEV(irq_major, 0), 1); /*释放设备号*/ } module_param(irq_major, int, S_IRUGO); MODULE_LICENSE("Dual BSD/GPL"); module_init(irq_init); module_exit(irq_exit); 由于没有涉及到 消抖 所以 现实的次数 都跳过显示 [root@EmbedSky /xiangjie]# ls api myirq.ko myirq_read.ko second.ko second_test [root@EmbedSky /xiangjie]# insmod myirq_read.ko register_chredev_region ok !!! kmalloc ok !!! cdev_add ok !!! open gpio_init ok !! [root@EmbedSky /xiangjie]# ./api irq_open count 1 irq_open count 2 irq_open count 3 irq_open count 4 irq_open count 5 request_irq ok hello irq_open !!! open api ok !!! irq_read ok irq counter is = 0 irq_read ok irq counter is = 0 irq_read ok irq counter is = 0 irq_read ok irq counter is = 0 irq_read ok irq counter is = 0 irq_read ok irq counter is = 0 irq_read ok irq counter is = 0 irq_read ok irq counter is = 0 irq_read ok irq counter is = 0 irq_read ok irq counter is = 0 irq_read ok irq counter is = 0 irq_handle ok irq_handle ok irq_do_work ok irq_read ok irq counter is = 1 irq_handle ok irq_do_work ok irq_handle ok irq_do_work ok irq_handle ok irq_do_work ok irq_read ok irq counter is = 4 irq_read ok irq counter is = 4 irq_read ok irq counter is = 4 irq_read ok irq counter is = 4 irq_read ok irq counter is = 4 irq_handle ok irq_do_work ok irq_read ok irq counter is = 5 irq_read ok irq counter is = 5 irq_read ok irq counter is = 5 irq_read ok irq counter is = 5 irq_read ok irq counter is = 5 irq_read ok irq counter is = 5 irq_read ok irq counter is = 5 irq_read ok irq counter is = 5 irq_read ok irq counter is = 5 irq_read ok irq counter is = 5 irq_read ok irq counter is = 5 irq_read ok irq counter is = 5 irq_read ok irq counter is = 5 irq_read ok irq counter is = 5 irq_read ok irq counter is = 5 irq_read ok irq counter is = 5 irq_read ok irq counter is = 5 irq_read ok irq counter is = 5 irq_read ok irq counter is = 5 irq_read ok irq counter is = 5 irq_read ok irq counter is = 5 irq_read ok irq counter is = 5 irq_read ok irq counter is = 5 irq_read ok irq counter is = 5 ^Cirq_release ok [root@EmbedSky /xiangjie]#