在编写含有中断的程序中,少不了中断的申请(request_irq)及中断释放(free_irq),当然少不了对中断的处理,常用的中断处理方法有tasklet,工作队列以及软中断,其中tasklet和工作队列的使用法方类似,定义一个结构和一个处理函数,然后将结构与处理函数联系起来就可以了,下面通过2个例子说明: tasklet的使用: #include<linux/kernel.h> #include<linux/module.h> #include<linux/init.h> #include<linux/interrupt.h> static int irq; //中断号 static char *devname; //设备名 static struct tasklet_struct mytasklet; //tasklet结构体 module_param(irq,int,0644); module_param(devname,charp,0644); struct myirq { int devid; }; struct myirq mydev={1119}; static void mytasklet_handler(unsigned long data) //tasklet处理函数 { printk("tasklet is working\n"); } static irqreturn_t myirq_handler(int irq,void *dev) //中断处理函数 { struct myirq mydev; static int count =0 ; mydev=*(struct myirq*)dev; printk("key:%d\n",count+1); printk("devid %d isr is working\n",mydev.devid); printk("botoom half will be working\n"); tasklet_init(&mytasklet,mytasklet_handler,0); //初始化tasklet将tasklet结构与tasklet处理函数建立联系 tasklet_schedule(&mytasklet); //调用tasklet printk("isr is leaving\n"); count++; return IRQ_HANDLED; } static int __init myirq_init() { printk(KERN_NOTICE "MODULE is working...\n"); if(request_irq(irq,myirq_handler,IRQF_SHARED,devname,&mydev)!=0) //申请中断 { printk("%s request irq %d faild\n",devname,irq); return -1; } printk("%s request irq %d success \n",devname,irq); return 0; } static int __exit myirq_exit() { printk("module is leaving\n"); free_irq(irq,&mydev); //释放中断 return 0; } module_init(myirq_init); module_exit(myirq_exit); MODULE_LICENSE("GPL"); 工作队列使用: #include<linux/kernel.h> #include<linux/module.h> #include<linux/init.h> #include<linux/interrupt.h> #include<linux/workqueue.h> static int irq; static char *devname; static struct work_struct mywork; module_param(irq,int,0644); module_param(devname,charp,0644); struct myirq { int devid; }; struct myirq mydev={1119}; static void mywork_handler(void *data) { printk("work is working\n"); } static irqreturn_t myirq_handler(int irq,void *dev) { struct myirq mydev; static int count =0 ; mydev=*(struct myirq*)dev; printk("key:%d\n",count+1); printk("devid %d isr is working\n",mydev.devid); printk("botoom half will be working\n"); INIT_WORK(&mywork,mywork_handler); schedule_work(&mywork); printk("isr is leaving\n"); count++; return IRQ_HANDLED; } static int __init myirq_init() { printk(KERN_NOTICE "MODULE is working...\n"); if(request_irq(irq,myirq_handler,IRQF_SHARED,devname,&mydev)!=0) { printk("%s request irq %d faild\n",devname,irq); return -1; } printk("%s request irq %d success \n",devname,irq); return 0; } static int __exit myirq_exit() { printk("module is leaving\n"); free_irq(irq,&mydev); return 0; } module_init(myirq_init); module_exit(myirq_exit); MODULE_LICENSE("GPL");
|