我正在使用zynq板,向z转动,并且添加了两个来自PL的中断,我使用:编辑了设备树:
amba_pl {
#address-cells = <0x1>;
#size-cells = <0x1>;
compatible = "simple-bus";
ranges;
gpio1@43c20000 {
#gpio-cells = <0x2>;
#interrupt-cells = <0x2>;
compatible = "generic-uio";
gpio-controller;
interrupt-controller;
interrupt-parent = <&intc>;
interrupts = <0x0 0x20 0x4>;
reg = <0x43c20000 0x10000>;
xlnx,all-inputs = <0x1>;
xlnx,all-inputs-2 = <0x0>;
xlnx,all-outputs = <0x0>;
xlnx,all-outputs-2 = <0x0>;
xlnx,dout-default = <0x0>;
xlnx,dout-default-2 = <0x0>;
xlnx,gpio-width = <0x3>;
xlnx,gpio2-width = <0x20>;
xlnx,interrupt-present = <0x1>;
xlnx,is-dual = <0x0>;
xlnx,tri-default = <0xffffffff>;
xlnx,tri-default-2 = <0xffffffff>;
};
gpio2@43c30000 {
#gpio-cells = <0x2>;
#interrupt-cells = <0x2>;
compatible = "generic-uio";
gpio-controller;
interrupt-controller;
interrupt-parent = <&intc>;
interrupts = <0x0 0x21 0x4>;
reg = <0x43c30000 0x10000>;
xlnx,all-inputs = <0x1>;
xlnx,all-inputs-2 = <0x0>;
xlnx,all-outputs = <0x0>;
xlnx,all-outputs-2 = <0x0>;
xlnx,dout-default = <0x0>;
xlnx,dout-default-2 = <0x0>;
xlnx,gpio-width = <0x3>;
xlnx,gpio2-width = <0x20>;
xlnx,interrupt-present = <0x1>;
xlnx,is-dual = <0x0>;
xlnx,tri-default = <0xffffffff>;
xlnx,tri-default-2 = <0xffffffff>;
};
};
它被映射到中断,cat / proc / interrupts
57:52 0 GIC 57 cdns-i2c
61:1 0 GIC 61 SII902x_det
62:0 0 GIC 62逻辑vc
63:0 0 GIC 63 0-0053
64:2 0 GIC 64 gpio1
65:2 0 GIC 65 gpio2
然后我用中断创建了一个模块,并将它们注册到96和97 (64 + 32)和(65 + 32),代码为:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/irqdomain.h>
#include <linux/interrupt.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <asm/exception.h>
#include <asm/mach/irq.h>
//#define INTERRUPT 96
#define INTERRUPT 96
MODULE_LICENSE("GPL");
static irqreturn_t interrupt_hook(int irq, void *dev_id, struct pt_regs *regs) {
printk("interrupt_hook!!\n");
return IRQ_HANDLED;
}
static int __init clcdint_init(void) {
unsigned int irq;
unsigned int irqflags;
int ret;
irq = INTERRUPT;
irqflags = IRQF_TRIGGER_RISING;
ret = request_irq(irq, interrupt_hook, irqflags, "int-test", NULL);
if(ret != 0) {
printk("ERROR: IRQ request failed %d", irq);
printk(" - code %d , EIO %d , EINVAL %d\n", ret, EIO, EINVAL);
}
printk("clcdint_init\n");
return 0;
}
module_init(clcdint_init);
static void __exit clcdint_exit(void) {
unsigned int irq;
irq=INTERRUPT;
free_irq(irq, NULL);
printk("clcdint_exit\n");
}
module_exit(clcdint_exit);
然后将其映射,我正在通过计数器和板上带有指示正确操作的led的开关生成IRQ,功能映射到:
96:0 0 zynq-gpio 0完整测试
97:1 0 zynq-gpio 1 int-test2
在insmod之后我得到 \ 0x1b [0; 31mZ-turn#\ 0x1b [m insmod driverirq146.ko 成功:注册IRQ 97 clcdint_init2
但是IRQ并不经常发生,正如您在/ proc / interrupts计数器中看到的那样,它发生一次或两次,也许是在软件方面,如果有人提出任何建议。