深入浅出Linux设备驱动编程--设备驱动中的中断处理
作者 佚名技术
来源 Linux系统
浏览
发布时间 2012-05-16
与Linux设备驱动中中断处理相关的是申请与释放IRQ的API request_irq()和free_irq(),request_irq()的原型为: int request_irq(unsigned int irq, void (*handler)(int irq, void *dev_id, struct pt_regs *regs), unsigned long irqflags, const char * devname, void *dev_id); irq是要申请的硬件中断号; handler是向系统登记的中断处理函数,是一个回调函数,中断发生时,系统调用这个函数,dev_id参数将被传递; irqflags是中断处理的属性,若设置SA_INTERRUPT,标明中断处理程序是快速处理程序,快速处理程序被调用时屏蔽所有中断,慢速处理程序不屏蔽;若设置SA_SHIRQ,则多个设备共享中断,dev_id在中断共享时会用到,一般设置为这个设备的device结构本身或者NULL. free_irq()的原型为: void free_irq(unsigned int irq,void *dev_id); 另外,与Linux中断息息相关的一个重要概念是Linux中断分为两个半部:上半部(tophalf)和下半部(bottom half).上半部的功能是“登记中断”,当一个中断发生时,它进行相应地硬件读写后就把中断例程的下半部挂到该设备的下半部执行队列中去.因此,上半部执行的速度就会很快,可以服务更多的中断请求.但是,仅有“登记中断”是远远不够的,中断的事件可能很复杂.因此,Linux引入了一个下半部,来完成中断事件的绝大多数使命.下半部和上半部最大的不同是下半部是可中断的,而上半部是不可中断的,下半部几乎做了中断处理程序所有的事情,可以被新的中断打断!下半部则相对来说并不是非常紧急的,通常还是比较耗时的,因此由系统自行安排运行时机,不在中断服务上下文中执行.Linux实现下半部的机制主要有tasklet和工作队列. tasklet基于Linux softirq,其使用相当简单,我们只需要定义tasklet及其处理函数并将二者关联: void my_tasklet_func(unsigned long); //定义一个处理函数: DECLARE_TASKLET(my_tasklet,my_tasklet_func,data); //定义一个tasklet结构my_tasklet,与my_tasklet_func(data)函数相关联 然后,在需要调度tasklet的时候引用一个简单的API就能使系统在适当的时候进行调度运行: tasklet_schedule(&my_tasklet); 此外,Linux还提供了另外一些其它的控制tasklet调度与运行的API: DECLARE_TASKLET_DISABLED(name,function,data); //与DECLARE_TASKLET类似,但等待tasklet被使能 tasklet_enable(struct tasklet_struct *); //使能tasklet tasklet_disble(struct tasklet_struct *); //禁用tasklet tasklet_init(struct tasklet_struct *,void (*func)(unsigned long),unsigned long); //类似DECLARE_TASKLET() tasklet_kill(struct tasklet_struct *); // 清除指定tasklet的可调度位,即不允许调度该tasklet 我们先来看一个tasklet的运行实例,这个实例没有任何实际意义,仅仅为了演示.它的功能是:在globalvar被写入一次后,就调度一个tasklet,函数中输出“tasklet is executing”: #include <linux/interrupt.h> … //定义与绑定tasklet函数 void test_tasklet_action(unsigned long t); DECLARE_TASKLET(test_tasklet, test_tasklet_action, 0); void test_tasklet_action(unsigned long t) { printk("tasklet is executingn"); } … ssize_t globalvar_write(struct file *filp, const char *buf, size_t len, loff_t *off) { … if (copy_from_user(&global_var, buf, sizeof(int))) { return - EFAULT; } //调度tasklet执行 tasklet_schedule(&test_tasklet); return sizeof(int); } 中断与真实的硬件息息相关,脱离硬件而空谈中断是毫无意义的,我 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |
你可能对下面的文章感兴趣
上一篇: linux 卷标设置与管理下一篇: 深入浅出Linux设备驱动编程--定时器
关于深入浅出Linux设备驱动编程--设备驱动中的中断处理的所有评论