⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 io_irq.c

📁 IO驱动的全过程和源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/init.h>#include <linux/kernel.h>	/* printk() */#include <linux/slab.h>		/* kmalloc() */#include <linux/fs.h>		/* everything... */#include <linux/errno.h>	/* error codes */#include <linux/types.h>	/* size_t */#include <linux/proc_fs.h>#include <linux/fcntl.h>	/* O_ACCMODE */#include <linux/seq_file.h>#include <linux/cdev.h>#include <linux/kfifo.h>#include <linux/sched.h> /* current and everything *///#include <linux/delay.h>  /* udelay */#include <asm/system.h>		/* cli(), *_flags */#include <asm/uaccess.h>	/* copy_*_user */#include <asm/atomic.h>#include "IO_irq.h"		/* local definitions *//* * Our parameters which can be set at load time. */int IO_irq_major =   0;int IO_irq_minor =   0;module_param(IO_irq_major, int, S_IRUGO);module_param(IO_irq_minor, int, S_IRUGO);struct IO_irq_dev *IO_irq_devices;	/* allocated in scull_init_module */static atomic_t IO_irq_available = ATOMIC_INIT(1);static spinlock_t IO_irq_lock = SPIN_LOCK_UNLOCKED;static DECLARE_WAIT_QUEUE_HEAD(IO_irq_wait);static unsigned long prevjiffies = 0;static unsigned int prevkey = 0;static struct IO_irq_key key1;static struct IO_irq_key key2;static struct IO_irq_key key3;static struct IO_irq_key key4;struct workqueue_struct *tekkamanwork;static struct delayed_work irq_work_delay;static struct work_struct irq_work;static struct tasklet_struct keytask;struct kfifo *tekkamanfifo;static spinlock_t tekkamanlock= SPIN_LOCK_UNLOCKED;static unsigned char *tekkamantmp;static unsigned char *tekkamanbuf ;/*key1_tasklet*/void key1_tasklet(unsigned long arg){	struct IO_irq_key *data = (struct IO_irq_key *)arg;	unsigned long j=0;	printk("\n**************key1_tasklet_start*****************\n");	j = jiffies;	printk("time:%08lx  delta:%3li     inirq:%i    pid:%3i   cpu:%i   command:%s\n",			     j, j - data->prevjiffies, in_interrupt() ? 1 : 0,			     current->pid, smp_processor_id(), current->comm);	printk("\n**************key1_tasklet_end*****************\n");}/*key2-3_work_fn*/void irq_work_delay_fn(void *arg){	struct IO_irq_key *data = &key2;	unsigned long j=0;	printk("\n**************key2_workqueue_start*****************\n");	j = jiffies;	printk("time:%08lx  delta:%3li     inirq:%i    pid:%3i   cpu:%i   command:%s\n",			     j, j - data->prevjiffies, in_interrupt() ? 1 : 0,			     current->pid, smp_processor_id(), current->comm);	printk("\n**************key2_workqueu_end*****************\n");}void irq_work_fn(void *arg){	struct IO_irq_key *data = &key3;	unsigned long j=0;	printk("\n**************key3_workqueue_start*****************\n");	j = jiffies;	printk("time:%08lx  delta:%3li     inirq:%i    pid:%3i   cpu:%i   command:%s\n",			     j, j - data->prevjiffies, in_interrupt() ? 1 : 0,			     current->pid, smp_processor_id(), current->comm);	printk("\n**************key3_workqueu_end*****************\n");}/* * irq handled */static irqreturn_t IO_irq_interrupt1(int irq, void *dev_id, struct pt_regs *regs){	unsigned long j =0;	j = jiffies;	printk("\n**************KEY = 1*****************\n");	if (!prevkey) printk("NO prevkey\nnow jiffies =0x%08lx\ncount = %d\n", j , ++key1.count);	else if (!key1.prevjiffies) printk("prevkey=%d at 0x%08lx\nNO prekey1\nnow jiffies =0x%08lx\ncount = %d\n" , prevkey , prevjiffies , j, ++key1.count);	else printk("prevkey=%d at  0x%08lx\nprekey1 at 0x%08lx\nnow jiffies =0x%08lx\ncount = %d\n" , prevkey , prevjiffies , key1.prevjiffies , j, ++key1.count);	prevkey = 1;	prevjiffies = key1.prevjiffies =j;	tasklet_schedule(&keytask);	printk("\n**************KEY = 1 END*****************\n");	return IRQ_HANDLED;}static irqreturn_t IO_irq_interrupt2(int irq, void *dev_id, struct pt_regs *regs){	unsigned long j =0;	int result = 0;	j = jiffies;	printk("\n**************KEY = 2*****************\n");	if (!prevkey) printk("NO prevkey\nnow jiffies =0x%08lx\ncount = %d\n", j , ++key2.count);	else if (!key2.prevjiffies) printk("prevkey=%d at 0x%08lx\nNO prekey2\nnow jiffies =0x%08lx\ncount = %d\n" , prevkey , prevjiffies , j, ++key2.count);	else printk("prevkey=%d at  0x%08lx\nprekey2 at 0x%08lx\nnow jiffies =0x%08lx\ncount = %d\n" , prevkey , prevjiffies , key2.prevjiffies , j, ++key2.count);	prevkey = 2;	prevjiffies = key2.prevjiffies =j;	if ((result =queue_delayed_work(tekkamanwork , &irq_work_delay, DELAY))!=1) 		printk("IO_irq_interrupt2 cannot add work ! ");		printk("result = %d ",result);	printk("\n**************KEY = 2 END*****************\n");	return IRQ_HANDLED;}static irqreturn_t IO_irq_interrupt3(int irq, void *dev_id, struct pt_regs *regs){	unsigned long j =0;	int result = 0;	j = jiffies;	printk("\n**************KEY = 3*****************\n");	if (!prevkey) printk("NO prevkey\nnow jiffies =0x%08lx\ncount = %d\n", j , ++key3.count);	else if (!key3.prevjiffies) printk("prevkey=%d at 0x%08lx\nNO prekey3\nnow jiffies =0x%08lx\ncount = %d\n" , prevkey , prevjiffies , j, ++key3.count);	else printk("prevkey=%d at  0x%08lx\nprekey3 at 0x%08lx\nnow jiffies =0x%08lx\ncount = %d\n" , prevkey , prevjiffies , key3.prevjiffies , j, ++key3.count);	prevkey = 3;	prevjiffies = key3.prevjiffies =j;	if ((result = schedule_work(&irq_work))!=1) printk("IO_irq_interrupt3 cannot add  work sharequeue  ! ");		printk("result = %d ",result);	printk("\n**************KEY = 3 END*****************\n");	return IRQ_HANDLED;}static irqreturn_t IO_irq_interrupt4(int irq, void *dev_id, struct pt_regs *regs){	unsigned int len = 0;	unsigned long j =0;	j = jiffies;	if (!prevkey) len = sprintf(tekkamanbuf,"\n**********KEY = 4**********\nNO prevkey\nnow jiffies =0x%08lx\ncount = %d\n*********KEY = 4 END***********\n", j , ++key4.count);	else if (!key4.prevjiffies) len = sprintf(tekkamanbuf,"\n**********KEY = 4**********\nprevkey=%d at 0x%08lx\nNO prekey4\nnow jiffies =0x%08lx\ncount = %d\n*********KEY = 4 END***********\n" , prevkey , prevjiffies , j, ++key4.count);	else len = sprintf(tekkamanbuf,"\n**********KEY = 4**********\nprevkey=%d at  0x%08lx\nprekey4 at 0x%08lx\nnow jiffies =0x%08lx\ncount = %d\n*********KEY = 4 END***********\n" , prevkey , prevjiffies , key4.prevjiffies , j, ++key4.count);	prevkey = 4;	prevjiffies = key4.prevjiffies =j;		kfifo_put(tekkamanfifo, tekkamanbuf,  len);		return IRQ_HANDLED;}/* * Open and close */int IO_irq_open(struct inode *inode, struct file *filp){	struct IO_irq_dev *dev; /* device information */	int result1,result2,result3,result4;	spin_lock(&IO_irq_lock);	while (! atomic_dec_and_test (&IO_irq_available)) {		atomic_inc(&IO_irq_available);		spin_unlock(&IO_irq_lock);		if (filp->f_flags & O_NONBLOCK) return -EAGAIN;		if (wait_event_interruptible (IO_irq_wait, atomic_read (&IO_irq_available)))			return -ERESTARTSYS; /* tell the fs layer to handle it */				spin_lock(&IO_irq_lock);	}	spin_unlock(&IO_irq_lock);	dev = container_of(inode->i_cdev, struct IO_irq_dev, cdev);	if ((dev->IO_irq1 >= IRQ_EINT0)&&(dev->IO_irq2 >= IRQ_EINT0)&&(dev->IO_irq3 >= IRQ_EINT0)&&(dev->IO_irq4 >= IRQ_EINT0))	{		result1 = request_irq(dev->IO_irq1, IO_irq_interrupt1, 0 , "IO_irq1", (void *)NULL);		result2 = request_irq(dev->IO_irq2, IO_irq_interrupt2, 0 , "IO_irq2", (void *)NULL);		result3 = request_irq(dev->IO_irq3, IO_irq_interrupt3, 0 , "IO_irq3", (void *)NULL);		result4 = request_irq(dev->IO_irq4, IO_irq_interrupt4, 0 , "IO_irq4", (void *)NULL);		if (result1 || result2 || result3 || result4 ) {			printk( "IO_irq: can't get assigned one of irq \n");			if (!result1) free_irq(IO_irq_devices->IO_irq1, NULL);			if (!result2) free_irq(IO_irq_devices->IO_irq2, NULL);			if (!result3) free_irq(IO_irq_devices->IO_irq3, NULL);			if (!result4) free_irq(IO_irq_devices->IO_irq4, NULL);			return -EAGAIN;		} else { 			s3c2410_gpio_cfgpin(S3C2410_GPG11, S3C2410_GPG11_EINT19);			s3c2410_gpio_pullup(S3C2410_GPG11, 0);			s3c2410_gpio_cfgpin(S3C2410_GPG3, S3C2410_GPG3_EINT11);			s3c2410_gpio_pullup(S3C2410_GPG3, 0);			s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_EINT2);			s3c2410_gpio_pullup(S3C2410_GPF2, 0);			s3c2410_gpio_cfgpin(S3C2410_GPF0, S3C2410_GPF0_EINT0);			s3c2410_gpio_pullup(S3C2410_GPF0, 0);			dev->IO_status = 0x1f ;		}	}	else   {		printk("IO_irq: get IRQ failed !\n");		return -EAGAIN;		}	filp->private_data = dev; /* for other methods */	tasklet_init(&keytask , key1_tasklet , (unsigned long)&key1);	tekkamanwork = create_workqueue("tekkamanwork");	INIT_DELAYED_WORK(&irq_work_delay, irq_work_delay_fn); 	INIT_WORK(&irq_work, irq_work_fn);	tekkamantmp = kmalloc(512, GFP_KERNEL);	tekkamanbuf = kmalloc (512 , GFP_KERNEL);	tekkamanfifo = kfifo_alloc(512, GFP_KERNEL, &tekkamanlock);		printk( "IO_irq: opened !  \n");	return nonseekable_open(inode, filp);          /* success */}int IO_irq_release(struct inode *inode, struct file *filp){		free_irq(IO_irq_devices->IO_irq1, NULL);	free_irq(IO_irq_devices->IO_irq2, NULL);	free_irq(IO_irq_devices->IO_irq3, NULL);	free_irq(IO_irq_devices->IO_irq4, NULL);	s3c2410_gpio_cfgpin(S3C2410_GPG11, S3C2410_GPG11_INP);	s3c2410_gpio_cfgpin(S3C2410_GPG3, S3C2410_GPG3_INP);	s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_INP);	s3c2410_gpio_cfgpin(S3C2410_GPF0, S3C2410_GPF0_INP);	IO_irq_devices->IO_status = 0 ;	tasklet_kill(&keytask);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -