You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);

当前出现两个异常:

  1. S2MM_DMASR和MM2S_DMASR寄存器值为0x1002,说明第12位(中断触发位)已置位,但cat /proc/interrupts显示DMA中断计数仍为0。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 22:44:57