设备中断设计组成
设计一个pio中断作为例子,配置如下图所示: 配置pio的中断为下降沿中断,并开启 选项,打开此选项后产生的中断需要手动清除edge capture寄存器才会释放中断。 使用Qsys自动分配基地址与中断号。 把pio设备挂在HPS的h2f_lw_axi_master总线上,并且把pio的irq连接到hps的f2h_irq0上,到此完成HPS配置。 现在需要在verilog工程中产生一个周期脉冲来控制pio不断出发下降沿中断,这里是的周期为1Hz。 脉冲产生模块 把led_level连接到pio的输入端。 剩下的就是重新编译工程与烧写FPGA了。 这里需要注意三个参数 1.compatible的赋值需要与platform_driver(Linux 驱动)中的字符串一致,否则无法使用platform提供的函数获取此设备信息; 2.reg的基地址取值需要看设备挂在什么总线上,现在设备挂在h2f_lw_axi_master总线上,此总线的基地址是0xff200000,并且设备分配的地址为0,因此reg的基地址为0xff200000。第二个参数为设备寄存器占用的空间,pio占用空间为0x10(0x0 - 0xF)。 3.interrupts的第二个参数赋值是与HPS中的中断资源号一致。此号码与GIC的编号换算方法如下: 现在使用的HPS中断号是3,即对应使用FPGA IRQ3(f2h_irq0使用前32个FPGA中断),根据GIC中断列表知道GIC中断号为75,而interrupts的中断号是GIC中断号减32,等于43。 为什么需要减32,主要是因为GIC的号码是从32开始的。 做中断时需要查看CV的datasheet Volume3,里面的GIC章节说得很清楚。其实主要看GIC Interrupt Map就好了。 Linux驱动程序设计 Linux驱动需要使用platform_driver架构。 使用platform_driver架构的驱动需要有以上两个结构体。 其中compatible的字符串需要与dts中的一样。这里补充一句dts文件需要通过dtc工具编译为dtb文件,在u-boot启动时被读取,才能把设备信息注册进内核。 在platform_driver加载时,会通过此字符串进行设备匹配('DE1-SoC,FPGA_IRQ0'),如果存在此设备,就会调用probe函数。 在probe函数里需要进行中断函数申请,具体方法如下: platform_get_irq可以获取经过Linux内核映射后的中断号,并通过request_irq申请中断。 除了申请中断以外,probe还需要申请pio虚拟地址,这将会在中断程序中用到。 中断函数如下: 在中断里需要对pio进行清中断处理,为什么要这样做需要看pio的文档。如果不清这寄存器,Linux会死机(一直在中断响应中)。 其实就是清除pio寄存器组中的edge capture寄存器(偏移量为0xC),写'1'是因为需要清除最低的IO线引起的中断。因为在HPS配置中也仅仅配置了1根IO线。 相关资料 |
|