1,中断号–就是一个号码,需要通过一定的方式去获取到
在3.14.0内核中,从设备树中获取
获取中断号到方法: 1, 宏定义 IRQ_EINT(号码) 2,设备树文件中 arch/arm/boot/dts/exynos4412-fs4412.dts 硬件连接: key ---- gpx1_2--- EINT10 设备树文件:arch/arm/boot/dts/exynos4x12-pinctrl.dtsi gpx1: gpx1 { gpio-controller; #gpio-cells = <2>; interrupt-controller; interrupt-parent = <&gic>; interrupts = <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>, <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>; #interrupt-cells = <2>; }; 在编程过程中,需要定义自己的节点--描述当前设备用的中断号 arch/arm/boot/dts/exynos4412-fs4412.dts +51 key_int_node{ compatible = "test_key"; interrupt-parent = <&gpx1>; interrupts = <2 4>;//<中断组号 触发方式> }; 编译设备树文件: make dtbs 更新dtbs文件: cp -raf arch/arm/boot/dts/exynos4412-fs4412.dtb /tftpboot/
2,在驱动中去通过代码获取到中断号,并且申请中断(实现中断处理方法)
a,获取到中断号码: int get_irqno_from_node(void) { // 获取到设备树中到节点 struct device_node *np = of_find_node_by_path("/key_int_node"); if(np){ printk("find node ok\n"); }else{ printk("find node failed\n"); } // 通过节点去获取到中断号码 int irqno = irq_of_parse_and_map(np, 0); printk("irqno = %d\n", irqno); return irqno; } b,申请中断 int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char * name, void * dev) 参数1: 设备对应的中断号 参数2: 中断的处理函数 typedef irqreturn_t (*irq_handler_t)(int, void *); 参数3:触发方式 #define IRQF_TRIGGER_NONE 0x00000000 //内部控制器触发中断的时候的标志 #define IRQF_TRIGGER_RISING 0x00000001 //上升沿 #define IRQF_TRIGGER_FALLING 0x00000002 //下降沿 #define IRQF_TRIGGER_HIGH 0x00000004 // 高点平 #define IRQF_TRIGGER_LOW 0x00000008 //低电平触发 参数4:中断的描述,自定义,主要是给用户查看的 /proc/interrupts 参数5:传递给参数2中函数指针的值 返回值: 正确为0,错误非0 参数2的赋值: irqreturn_t key_irq_handler(int irqno, void *devid) { return IRQ_HANDLED; } 释放中断: void free_irq(unsigned int irq, void *dev_id) 参数1: 设备对应的中断号 参数2:与request_irq中第5个参数保持一致
书写步骤:
1.驱动基本框架
2.在init函数中获取中断号
3.申请中断
至此,现在这个驱动可以向下管理硬件,但不能向上提供接口