背景:
我想做的是能够从我的 ARM 处理器写入 Zynq 7000 上的 BRAM。
为此,我有以下组件:
-M_AXI_GP0 on PS7 connects to S_AXI_LITE on axi_cdma_0 through an AXI Interconnect
-cdma_introut on axi_cdma_0 connects to IRQ_F2P on PS7 through sys_concat, input 11. This means that this maps to Interrupt 87 on PS7.
-M_AXI on axi_cdma_0 connects to S00_AXI on axi_mem_intercon
-M01_AXI on axi_mem_intercon connects to S_AXI_HP3 on PS7
-M00_AXI on axi_mem_intercon connects to S_AXI on axi_bram_ctrl_0
-BRAM_PORTA on axi_bram_ctrl_0 connects to BRAM_PORTA on blk_mem_gen0
==================================================== ========================
在我看来,这个设置应该做的是:
一旦从 ARM DMA 引擎提交事务,Zynq 将使用 GP0 通过 GP0 向 CDMA 控制器发送命令。
CDMA 控制器将在其从 AXI_LITE 端口上接收命令,并解释通过 HP3 访问 RAM 的请求。
CDMA 控制器将通过 axi_mem_intercon 移动数据,以便从 M01_AXI 上的 hp3 获取事务数据,并通过 M00_AXI 将其发送到 BRAM 控制器
BRAM 控制器将接收 AXI-4 输入并将其转换为适当的 BRAM 端口,以将数据写入 blk_mem_gen_0 生成的 BRAM
完成此动作后,CDMA 会通过 sys_concat 发送中断,向 DMA Engine 指示其工作已完成。
将此 hdl 设计加载到 PL 结构后,我尝试通过内核模块将事务提交给 DMA 引擎。结果是超时,DMA 引擎显然永远不会完成任务。
==================================================== ========================
在我试图找出问题的过程中,我做了以下观察:
在尝试了超时的写入事务后,我尝试了对同一 DMA 通道的读取事务,但配置为读取数据。我得到的是我试图写入的所有数据。对我来说,这似乎表明 DMA 引擎正在写入某个地方,但没有识别出任务的完成
有问题的 BRAM 是双端口 RAM,另一个端口读取 BRAM 中的数据并切换 LED 以反映数据。当我尝试写入事务时,LED 没有切换,所以似乎 DMA 事务没有达到 BRAM
查看 cat /proc/interrupts 时,我可以看到几个中断,但不是 GIC 87。如前所述,我使用的中断线连接到 IRQ concat 块的输入 11。我可以确认到输入 12 的中断线确实对应于 /proc/interrupts 的 GIC 88,所以我相信我对我正在寻找的中断的理解是正确的。因此,由于某种原因,它没有在处理器上注册该中断。
==================================================== ========================
基于此,我相信我的这个 CDMA 的设备树条目是不正确的。
在 Vivado 中,我可以在地址编辑器中看到这些条目(为简洁起见,省略了一些条目):
sys_ps7
Data(32 address bits:0x40000000 [1G])
axi_cdma_0 S_AXI_LITE Reg 0x43C0_0000 64K 0x43C0_FFFF
axi_cdma_0
Data(32 address bits : 4G)
axi_bram_ctrl_0 S_AXI Mem0 0xC000_0000 4K 0xC000_0FFF
sys_ps7 S_AXI_HP3 HP3... 0x0000_0000 1G 0x3FFF_FFFF
我编写设备树条目的尝试如下:
axi-cdma@43C00000{
#dma-cells = <0x1>;
compatible = "tst,axi-cdma-ctrl-1.00.a";
reg = <0x10000000 0x1000>;
interrupts = <0x0 0x37 0x4>;
interrupt-parent = <0x1>;
dma-channel@C0000000{
buswidth = <0x20>;
}
在我在内核模块中添加此条目之前,甚至无法注册事务通道,现在它注册了,因此我相当确定内核至少接受了此条目以分配 DMA 通道。但是,我不太了解 devicetree 的工作原理,特别是寻址方式,所以我很有可能写错了,这就是我的交易没有成功的原因。谁能帮我纠正我的设计?}