http://www.aichengxu.com/linux/7030074.htm
http://blog.csdn.net/droidphone/article/details/7445825
http://blog.csdn.net/droidphone/article/details/7497787
http://www.cnblogs.com/subo_peng/p/5324398.html
http://blog.chinaunix.net/uid-24666775-id-3787938.html
irq_desc结构相当于irq是实体类java bean ,描述irq的一个结构体/类
整个通用中断子系统几乎都是围绕着irq_desc结构进行,系统中每一个irq都对应着一个irq_desc结构
读取interrupts会依次显示irq编号,每个cpu对该irq的处理次数,中断控制器的名字,irq的名字,以及驱动程序注册该irq时使用的名字
cat /proc/interrupts
144: 179 287 86 312 GPIO IT7260 //触摸屏驱动注册中断
181: 265 271 243 220 GPIO GPIO_INT //这个指纹驱动注册中断
request_threaded_irq
request_irq是request_threaded_irq的一个wrapper,只是将其中的thread_fn置为空。
thread_fn如果该参数不为NULL,内核会为该irq创建一个内核线程,当中断发生时,如果handler回调返回值是IRQ_WAKE_THREAD,内核将会激活中断线程,在中断线程中,该回调函数将被调用,所以,该回调函数运行在进程上下文中,允许进行阻塞操作
Therequest_threaded_irq() function was added to allow developers to split interrupt handling code into two parts. One part that will execute with interrupts blocked, and a second part that can be done by a kernel thread without interrupts blocked
4412设置外部中断为下降沿触发,但是在上升沿的时候也触发中断
http://bbs.topeetboard.com/forum.php?mod=viewthread&tid=4108&extra=
http://bbs.csdn.net/topics/392087110
建议屏蔽为一个管脚。一个一个来判断是否中断异常
在Linux内核中,request_irq() 函数是注册中断服务函数:函数的原型如下:
intrequest_irq(unsignedintirq,void(*handler)(int,void*,structpt_regs*),unsignedlongfrags,constchar*device,void*dev_id);
5个参数的含义如下:
第一个参数irq:申请的硬件中断号;
第二个参数handler:是一个函数指针,向系统登记的中断处理函数,是一个回调函数,当中断发生时,系统调用这个函数,传入的参数包括中断设备id,寄存器值。
第三个参数flags:指定了快速中断或中断共享等中断处理属性。
第四个参数devices:指定设备驱动程序的名称。
第五个参数dev_id:传入中断处理程序的参数,可以为NULL,在注册共享中断时,此参数不能为NULL,作为共享中断时的中断区别参数。
为何gpio_to_irq不能静态使用? 是因为你C基础差,函数好像不能直接赋值给结构体声明时的成员,初始化时好像只能赋值常量
http://blog.csdn.net/airk000/article/details/23339257
静态使用: 在结构体声明的时候irq成员使用gpio_to_irq会报错,
而动态调用的话就没有问题
http://www.cnblogs.com/yasmi/articles/4933842.html
http://blog.chinaunix.net/uid-20786208-id-3235255.html
http://blog.csdn.net/mirkerson/article/details/8464290
在申请中断时加上了IRQF_NO_SUSPEND, 另一个是irq_enable_wake(irq); 这两个函数都可以赋予IRQ唤醒系统的能力
http://www.wowotech.net/pm_subsystem/driver_pm.html
linux中断处理的上半部和下半部
设备的中断会打断内核中进程的正常调度和运行,系统对更高吞吐率的追求势必要求中断服务程序尽可能地短小精悍。但是,这个良好的愿望往往与现实并不吻合。在大多数真实的系统中,当中断到来时,要完成的工作往往并不会是短小的,它可能要进行较大量的耗时处理。
为了在中断执行时间尽可能短和中断处理需完成大量工作之间找到一个平衡点,Linux 将中断处理程序分解为两个半部:顶半部(top half)和底半部(bottom half)。
顶半部完成尽可能少的比较紧急的功能,它往往只是简单地读取寄存器中的中断状态并清除中断标志后就进行“登记中断”的工作。“登记中断”意味着将底半部处理程序挂到该设备的底半部执行队列中去。这样,顶半部执行的速度就会很快,可以服务更多的中断请求。
现在,中断处理工作的重心就落在了底半部的头上,它来完成中断事件的绝大多数任务。底半部几乎做了中断处理程序所有的事情,而且可以被新的中断打断,这也是底半部和顶半部的最大不同,因为顶半部往往被设计成不可中断。底半部则相对来说并不是非常紧急的,而且相对比较耗时,不在硬件中断服务程序中执行。
尽管顶半部、底半部的结合能够改善系统的响应能力,但是,僵化地认为 Linux设备驱动中的中断处理一定要分两个半部则是不对的。如果中断要处理的工作本身很少,则完全可以直接在顶半部全部完成。
其他操作系统中对中断的处理也采用了类似于Linux系统的方法,真正的硬件中断服务程序都应该尽可能短。
因此,许多操作系统都提供了中断上下文和非中断上下文相结合的机制,将中断的耗时工作保留到非中断上下文去执行。
Linux 系统实现底半部的机制主要有tasklet,工作队列和软中断。Linux 的中断处理分为两个半部,顶半部处理紧急的硬件操作,底半部处理不紧急的耗时操作。tasklet 和工作队列都是调度中断底半部的良好机制,tasklet 基于软中断实现。内核定时器也依靠软中断实现。内核中的延时是忙等待或者睡眠等待,为了充分利用CPU资源,使系统有更好的吞吐性能,在对延迟时间的要求并不是很精确的情况下,睡眠等待通常是值得推荐的。
网友评论