中断框架
解决轮询对处理器的占资源缺陷。
硬件模型:
中断源 ------- GIC(屏蔽、优先级、记录、区分)-------FIQ/IRQ---------A9处理器
linux内核软件模型:
中断号与中断处理函数
Arm裸奔:
中断源硬件初始化、中断号、GIC初始化、A9初始化、异常向量表、中断处理函数
对于linux内核模型:
中断号的获取:
1.宏定义 IRQ_EINT(号码) //下图对应的9
2.设备树文件arch/arm/boot/dts/xxx.dts
以按键为例,io硬件的连接:
对应于datasheet的中断号描述。
对于设备树,打开dts文件,参考讯为4.14内核版本
exynos4412-itop-elite.dts -> exynos4412-itop-scp-core.dtsi -> exynos4412.dtsi -> exynos4412-pinctrl.dtsi 通过头文件层层包含,找到pinctrl的dtsi文件
在文件中索引到上图需配置的GPX1部分
在设备树对soc中的定义
Gpio-controller;//gpio控制器
Gpio-cells;//描述长度
Interrupt-contro;//中断控制器
Interrupt-parent;//继承于gic通用中断控制器
Interrupt;//相应中断描述,其中中断号针对datsht的最左边的中断组内的号码。
Interrupt-cells;//中断号描述长度
在编程中,我们需要自定义描述当前设备用的中断号
在exynos4412-itop-elite.dts文件中添加继承于设备树中的gpx1代码:
key_init_node{
compatible = "test_key"; //名称
interrupt-parent = <&gpx1>; //继承
interrupts = <2 IRQ_TYPE_LEVEL_HIGH>; //2对应父类interrupts数组下标
}
其中触发方式:可以用0、2、4、8来表示(上升下降高低电平),也可以宏定义
重新编译设备树文件:make dtbs
更新dtb文件到开发板。
在驱动中
-
获取中断号的简单函数
注意:获取到的号码不是手册上定义的,是内核中定义,不需要去知道怎么生成,直接用
#include <of.h>
#include <of_irq.h>
int get_irqno_from_node(void)
{
//获取到设备树中的结点
struct device_node *np = of_find_node_by_path("/key_int_node");
if(!np){
printk(“find node failed\n”);
}//获取结点中的中断号
int irqno = irq_of_parse_and_map(np, 0);
return irqno;
} -
申请中断 request_irq;
注意:中断可共享,参数5用于同一中断号中不同设备对应处理函数的区别描述,即中断需要通过参数1与参数5才能确定调用哪个处理函数,这样可以解决不同驱动同时使用相同中断号的冲突,各驱动互不影响。 -
编写中断处理函数 typedef irqreturn_t (*irq_handler_t)(int, void *);
-
释放中断free_irq;
设备树pinctrl系统
设备树的引入:好处在于驱动移植时不需要修该大量驱动代码,只需改设备树文件