目录
一、设备树的修改
二、初始化
1、初始化GPIO:申请GPIO、设置成输入模式
2、中断相关初始化:从设备树获取中断号、中断处理函数、申请中断
3、定时器初始化(消抖)
三、中断处理函数
1、按键中断触发之后,开启定时器,延时消抖
2、定时延时到达,上报按键信息给驱动的读函数(imx6uirq_read)
四、驱动读函数获取按键信息
1、驱动读到定时消抖后的按键信息后,确认按键有效,通过 copy_to_user() 发生给应用层
gitee代码链接:gitee_linux_driver: 个人理解编写的linux驱动 - Gitee.com
github代码链接:Can/13_irq at master · CanvMo/Can · GitHub
附件:
1、request_irq 函数:request_irq 函数用于申请中断,此函数会激活(使能)中断,所以不需要我们 手动去使能中断,函数原型:
irq:要申请中断的中断号;
handler:中断处理函数,当中断发生以后就会执行此中断处理函数。
flags:中断标志,可以在文件 include/linux/interrupt.h 里面查看所有的中断标志,常用的中断标志,如下所示:标志位可以多组合使用
标志 | 描述 |
IRQF_SHARED | 多个设备共享一个中断线,共享的所有中断都必须指定此标志。如果使用共享中断的话,request_irq 函数的 dev 参数就是唯一区分他们的标志。 |
IRQF_ONESHOT | 单次中断,中断执行一次就结束。 |
IRQF_TRIGGER_NONE | 无触发 |
IRQF_TRIGGER_RISING | 上升沿触发 |
IRQF_TRIGGER_FALLING | 下降沿触发 |
IRQF_TRIGGER_HIGH | 高电平触发 |
IRQF_TRIGGER_LOW | 低电平触发 |
name:中断名字,设置以后可以在/proc/interrupts 文件中看到对应的中断名字。
dev: 如果将 flags 设置为 IRQF_SHARED 的话, dev 用来区分不同的中断,一般情况下将
dev 设置为设备结构体, dev 会传递给中断处理函数 irq_handler_t 的第二个参数。第二个参数是一个指向 void 的指针,也就是个通用指针,需要与 request_irq 函数的 dev 参数保持一致。
用法:
2、上半部与下半部中断处理
(1) 上半部:上半部就是中断处理函数,那些处理过程比较快,不会占用很长时间的处理就可
以放在上半部完成;
(2) 下半部:如果中断处理过程比较耗时,那么就将这些比较耗时的代码提出来,交给下半部
去执行,这样中断处理函数就会快进快出;
(3) 上半部处理很简单,直接编写中断处理函数就行了,,默认就是这种写法;
(4) Linux 内核提供了多种下半部机制:软中断、tasklet、工作队列