AXI互连上的DMA传输
所有DMA事务都使用AXI接口在PL中的片上存储器、DDR存储器和从外设之间传递数据。PL中的从设备通过DMAC的外部请求接口与DMAC通信,以控制数据流。这意味着从设备可以请求DMA交易,以便将数据从源地址传输到目标地址。
虽然DMAC在技术上可以访问PS中的IOPs,但这通常不是很有用。原因是这些路径通常不提供流量控制信号。流量控制是确保数据以稳定速率传输的机制,以避免缓冲区溢出或数据丢失。由于缺少这些信号,DMAC无法有效地管理通过PS IOPs的数据流。
DMAC通常使用的数据路径如图9-3所示,外围请求接口(用于流量控制)在图中没有显示。每个AXI路径可以是读或写操作,因此存在多种组合。其中两个典型的DMA事务例子包括:
- 内存到内存(片上内存到DDR内存):通常用于在系统的不同内存区域之间高效地传输数据。例如,处理器可能需要将数据从片上缓存或SRAM移动到DDR主存储器中,以便长期存储或供其他设备访问。
- 内存到/从PL外设(DDR内存到PL外设或从PL外设到DDR内存);用于在系统的处理器系统和可编程逻辑部分之间传输数据。DDR内存中的数据可以通过DMA被高效地传输到PL中的外设,如硬件加速器或I/O接口。同样,PL外设产生的数据也可以通过DMA被传输回DDR内存或片上内存,以供处理器或其他设备使用。
在考虑AXI事务时,有一些关键的特性和限制需要注意。如下所示:
- AXI数据传输大小:
- AXI支持的数据访问宽度可以达到AXI数据总线的64位宽度。
- 如果用户将
src_burst_size
或dst_burst_size
字段编程为大于64位,AXI会发出一个精确的终止信号。 - 最大突发长度(burst length)是16个数据节拍(data beats)。
- AXI突发跨越4KB边界:
- AXI规范不允许AXI突发跨越4KB地址边界。
- 如果控制器被编程为使用突发起始地址、大小和长度的组合,这会导致单个突发跨越4KB地址边界,那么控制器将生成两个突发,它们的组合长度等于指定的长度。这种操作对DMAC通道线程程序是透明的。换句话说,DMAC(或其背后的软件/硬件逻辑)会处理这种地址边界的跨越情况,而不需要DMAC通道线程程序显式地处理这个问题。例如,当DMAC接收到一个DMALD(可能是表示DMA读操作的指令)时,它会自动生成两个适当的AXI读突发操作,而不是一个可能会跨越4KB边界的突发操作。
- AXI突发类型:
- 可以编程以生成仅用于数据访问的固定地址或递增地址突发类型。不会为数据访问或指令获取生成环绕地址突发。
- AXI写地址:
- 可以发出多达八个未完成的写地址(写发出能力)。
- DMAC在发出写地址之前,会先读取完成该写事务所需的所有数据字节。
- AXI写数据交织:
- 不生成交织的写数据。一个写事务的所有写数据节拍都会在下一个写事务的任何写数据节拍之前输出。
- AXI特性:
- 不支持锁定(locked)或独占(exclusive)访问。锁定访问通常用于确保在事务完成之前,数据不会被其他事务修改。独占访问则用于缓存一致性协议,确保在特定时间只有一个处理器可以访问或修改某个内存位置。
这些考虑因素对于正确配置和使用AXI接口至关重要,特别是在设计高性能数据传输系统时。了解AXI的这些特性和限制可以帮助开发者避免潜在的问题,并优化数据传输的效率。
DMA Manager
负责管理DMA传输的软件或硬件接口的一部分。它允许用户通过两个APB(Advanced Peripheral Bus,高级外设总线)接口之一向DMA控制器发送指令。
当DMAC(DMA控制器)在实时操作中时,用户通常只能发送以下有限指令集的一个子集:
- DMAGO :用于启动用户指定的DMA通道上的DMA传输。它告诉DMA控制器开始从源地址读取数据,并将数据写入目标地址,根据预配置的DMA描述符或通道设置进行传输。
- DMASEV (DMA Set Event/Interrupt):用于通过用户指定的事件编号来触发事件或中断。这可以用于通知系统DMA操作已完成,或者达到某个特定条件(如传输错误、完成一定百分比等)。这样,CPU或其他系统组件可以响应这些事件并采取相应的行动。
- DMAKILL:用于终止一个DMA线程。在某些情况下,可能需要取消或停止正在进行的DMA传输。DMAKILL指令允许用户做到这一点,它会导致DMA控制器停止当前的DMA操作,并释放与该线程关联的任何资源。
需要注意的是,当DMAC在实时操作中时,其他更复杂的配置或管理指令可能不可用或受到限制,因为实时系统需要快速响应和确定性行为。因此,这些基本指令集(DMAGO、DMASEV和DMAKILL)为实时环境中的DMA操作提供了必要的控制和反馈机制。
DMA管理器(DMA Manager)的操作取决于SLCR(System Level Control Register)寄存器中的TZ_DMA_NS
设置的安全状态。这个设置决定了DMA管理器是在安全状态还是非安全状态下运行。
- 安全状态(Secure State):如果DMA管理器在安全状态下运行,那么必须使用安全的APB接口来发送指令。如果使用非安全的APB接口发送指令,DMAC(DMA Controller)将会忽略这些指令。
- 非安全状态(Non-Secure State):当DMA管理器在非安全状态下运行时,建议使用非安全的APB接口来启动或重启DMA通道。但是,即使在非安全模式下,也可以使用安全的APB接口。这通常是在某些特殊情况下,比如需要更高安全级别的操作时才这样做。
在通过Debug Instruction寄存器或DBGCMD寄存器向DMA管理器发送指令之前,必须首先读取DBGSTATUS寄存器以确保调试器处于空闲状态。如果调试器不处于空闲状态,DMA管理器将忽略这些指令。
当DMA管理器从APB(Advanced Peripheral Bus)从接口接收到指令时,由于系统内部的处理流程和资源限制,可能需要经过几个时钟周期才能处理该指令。例如,如果流水线正忙于处理另一条指令。
在发出DMAGO之前,系统内存必须包含一个适合DMA通道线程执行的程序,从DMAGO指定的地址开始。
示例:启动DMA通道线程
以下示例显示了使用调试指令寄存器启动DMA通道线程所需的步骤:
-
创建DMA通道程序:
首先,你需要为DMA通道编写一个程序。这通常是一个包含DMA传输指令的序列。 -
将程序存储在系统内存区域:
将你的DMA通道程序存储在系统内存的一个区域中。确保这个区域对DMA管理器是可访问的。 -
轮询
dmac.DBGSTATUS
寄存器以确保调试空闲:
在尝试编程DMAGO指令之前,你需要确保调试器处于空闲状态。这可以通过读取dmac.DBGSTATUS
寄存器并检查其dbgstatus
位是否为0来实现。 -
写入
dmac.DBGINST0
寄存器:
使用APB接口之一,向dmac.DBGINST0
寄存器写入以下信息:- DMAGO指令的字节0编码。
- DMAGO指令的字节1编码。
- 调试线程位设置为0,以选择DMA管理器。
-
写入
dmac.DBGINST1
寄存器:
使用DMAGO指令的字节[5:2]数据(通常是目标地址的高位部分)写入dmac.DBGINST1
寄存器。这些字节必须设置为在第2步中写入系统内存的程序中第一个指令的地址。 -
指示DMAC执行指令:
向dmac.DBGCMD
寄存器写入0。这将指示DMAC执行调试指令寄存器中包含的指令。DMAC会启动DMA通道线程,并将dbgstatus
位设置为1。当DMAC完成指令的执行后,它会清除dbgstatus
位,将其设置回0。
注意事项:
- 在编写和调试DMA通道程序时,请确保遵循你的硬件文档和DMA管理器的规范。
- 在发送任何DMA指令之前,始终检查DMA管理器的状态,以确保它准备好接受新的指令。
- 如果你的系统支持中断,并且你希望在DMA操作完成时得到通知,请确保正确设置和配置相关的中断。
- 始终考虑DMA操作的性能和资源消耗,以避免对系统造成不良影响。