ZYNQ7000平台AXI DMA中断计数不更新及控制寄存器位异常排查
问题描述
我在ZYNQ 7000系列SOC Minized板上,通过UIO驱动搭配AXI DMA实现PL到PS的数据传输,已加载Petalinux系统。执行cat /proc/interrupts能看到DMA对应的61、62号中断。
应用程序已成功映射UIO驱动,寄存器配置如下:
DMA_Set(DMA_Base_Addr+MM2S_DMACR, 0x00000004); DMA_Set(DMA_Base_Addr+S2MM_DMACR, 0x00000004); DMA_Set(DMA_Base_Addr+MM2S_DMACR, 0x00000000); DMA_Set(DMA_Base_Addr+S2MM_DMACR, 0x00000000); DMA_Set(DMA_Base_Addr+MM2S_DMACR, 0x00007000); DMA_Set(DMA_Base_Addr+S2MM_DMACR, 0x00007000); DMA_Set(DMA_Base_Addr+MM2S_SA, 0x30000000); DMA_Set(DMA_Base_Addr+S2MM_DA, 0x30000400); DMA_Set(DMA_Base_Addr+MM2S_DMACR, 0x00000001); DMA_Set(DMA_Base_Addr+S2MM_DMACR, 0x00000001); DMA_Set(DMA_Base_Addr+MM2S_LENGTH,0x30000400); DMA_Set(DMA_Base_Addr+S2MM_LENGTH,0x00000400);
当前出现两个异常:
- S2MM_DMASR和MM2S_DMASR寄存器值为0x1002,说明第12位(中断触发位)已置位,但
cat /proc/interrupts显示DMA中断计数仍为0。 - S2MM_DMACR和MM2S_DMACR寄存器值为0x10003,第15位为1,但Xilinx手册明确说明该位始终为0。
已通过修改system-user.dtsi预留内存,相关日志:
New:~$ dmesg |grep eserved Reserved memory: created DMA memory pool at 0x30000000, size 256 MiB OF: reserved mem: initialized node buffer@0x30000000, compatible id shared-dma-pool cma: Reserved 16 MiB at 0x2f000000 Memory: 735840K/1048576K available (7168K kernel code, 243K rwdata, 1904K rodata, 1024K init, 118K bss, 296352K res) hw-breakpoint: found 5 (+1 reserved) breakpoint and 1 watchpoint registers.
附system-user.dtsi内容:
/include/ "system-conf.dtsi" / { chosen { bootargs = "earlycon clk_ignore_unused uio_pdrv_genirq.of_id=generic-uio rootwait quiet loglevel=0"; stdout-path = "serial0:115200n8"; }; reserved-memory{ #address-cells=<1>; #size-cells =<1>; ranges; dma_reserved:buffer@0{ compatible="shared-dma-pool"; no-map; reg=<0x30000000 0x1000000>; }; dma_proxy@0 { compatible ="xlnx,dma_proxy"; dmas = <&axi_dma_0 1>; dma-names = "dma1"; memory-region = <&dma_reserved>; }; }; &amba_pl { dma1:@dma40400000 { compatible = "generic-uio"; reg = <0x40400000 0x10000>; interrupt-parent = <&intc>; interrupts = <0 30 4>; }; }; &axi_dma_0{ compatible = "generic-uio"; linux,uio-name = "dma0"; }; &qspi { #address-cells = <1>; #size-cells = <0>; flash0: flash@0 { compatible = "n25q512a","micron,m25p80","jedec,spi-nor"; spi-max-frequency = <50000000>; reg = <0x0>; #address-cells = <1>; #size-cells = <1>; }; };
问题分析与解决
1. 中断计数未增加的原因
- UIO驱动中断绑定错误:设备树中同时给
&axi_dma_0和amba_pl下的dma1节点配置了generic-uio属性,但axi_dma_0未配置中断信息。AXI DMA包含MM2S和S2MM两个独立中断,你仅给dma1配置了一个中断(<0 30 4>),实际两个DMA中断(61、62)未被UIO驱动正确注册。 - 用户态未处理中断:UIO驱动要求用户态程序主动读取
/dev/uioX文件描述符确认中断,内核才会更新/proc/interrupts计数。如果你的应用程序仅配置DMA寄存器,未实现UIO中断监听逻辑(如read()阻塞等待、poll()监听),内核不会统计该中断。 - 硬件中断路由异常:检查PL端DMA中断是否正确连接到ZYNQ的GIC中断控制器,确保AXI DMA的中断输出引脚已与PS的中断输入引脚完成硬件连接。
2. 控制寄存器第15位异常的原因
该位是复位完成(Reset Done)只读位:你先写入0x4触发DMA软复位,之后写入0x0清除软复位位,DMA完成复位操作后会自动置位该位。手册中“始终为0”指的是软件无法写入该位,而非硬件不会置位,当前读取到第15位为1是正常的硬件行为,并非异常。
内容的提问来源于Stack Exchange,提问作者Creator
相关产品推荐
相关产品推荐

