通用特性
核心时钟与通道配置
独立的核心、从接口和主接口时钟
Independent core, slave interface and master interface clocks
最多支持 32 个通道
Up to 32 channels, one per source and destination pair, configurable in coreConsultant
数据传输单向性
Data transfers in one direction only (each channel is unidirectional)
最多两个 AXI 主接口
Up to two AXI master interfaces, configurable in coreConsultant
用于多层支持(Two master interfaces for multilayer support)
多个 AXI 主接口通过允许外设直接连接不同 AXI 互连,提升总线性能(Multiple AXI masters increase bus performance by allowing direct connection of peripherals on different AXI interconnects)
支持不同 AMBA 层上的不同 ACLK(Support for different ACLK on different AMBA layers)
DMA 传输类型与内存接口
支持多种 DMA 传输模式
Memory-to-memory, memory-to-peripheral, peripheral-to-memory, and peripheral-to-peripheral DMA transfers
独立的外部内存接口(每通道)
Separate external memory interface (per channel) to connect SRAM or Register File based memories to Channel FIFO
接口标准与配置
AMBA 3 AXI / AMBA 4 AXI 兼容的主接口
AMBA 3 AXI/AMBA 4 AXI-compliant master interface
AHB / APB4 从接口用于编程 DMA 控制器
AHB/APB4 slave interface for programming the DMA controller
仅支持 SINGLE 传输(hburst = 3’b000)(AHB slave interface supports only SINGLE transfers (hburst = 3’b000))
AXI 主接口数据总线宽度最高 512 位
AXI master data bus width up to 512 bits (for both AXI master interfaces), configurable in coreConsultant
端序模式可静态或动态选择 —> 似乎有点强大,动态静态选择端序模式?
Endian mode can be selected statically or dynamically for AXI master interfaces, configurable in coreConsultant
动态选择端序的输入引脚
Input pin to dynamically select endianness
高级功能与控制
主接口链表访问端序的独立控制
Independent control for endianness of linked list access on master interfaces, configurable in coreConsultant
可选的标识寄存器
Optional identification register, configurable in coreConsultant
通道锁定支持
Channel locking support
支持在不同传输层级上锁定主总线接口的内部通道仲裁(Supports locking of the internal channel arbitration for the master bus interface at different transfer hierarchy)
DMAC 状态指示输出
DMAC status indication outputs
空闲/忙指示(Idle/busy indication)
DMA 保持功能
DMA hold function ——–> 这个有点意思,重点聊一下
输出引脚指示 DMA 事务级别的最后写传输
Output pin indicates the last write transfer at DMA transaction level
多级 DMA 传输层级
Multiple levels of DMA transfer hierarchy
1.3.2 通道缓冲
每个通道配备单个先进先出(FIFO)
FIFO深度可在 coreConsultant中配置
自动打包/解包数据以适配FIFO宽度
1.3.3 通道控制
每个通道支持可编程传输类型(内存到内存、内存到外设、外设到内存、外设到外设)
支持单次或多次DMA事务
每个通道支持可编程的多事务大小
每个通道支持可编程的最大AMBA突发传输大小(可在 coreConsultant中配置)
通道禁用时无数据丢失
通道挂起与恢复
通道优先级可编程
锁定不同传输层级下主总线接口的内部通道仲裁
支持通过链表、连续地址、自动重载、影子寄存器方法实现可编程多块传输
链表动态扩展
源(SRC)/目的(DST)多块传输类型独立配置
每个通道的源和目的各配备一个状态机
数据和链表项(LLI)访问采用独立状态机
控制信号(如缓存、保护)可按每个DMA块编程
传输长度(块长度)可编程
错误状态寄存器,便于在错误事件中进行调试
1.3.4 Flow Control(流控制)
可编程的DMA传输级流控制
若在DMA初始化前已知块传输大小,DMA控制器作为DMA块传输级的流控制器。
若在DMA初始化前未知块传输大小,源或目标外设作为不定长度(需求模式)DMA块传输的流控制器。
1.3.5 Handshaking Interface(握手接口)
面向非内存外设的可编程软件和硬件握手接口
最多支持64个硬件握手接口/外设,可在coreConsultant中配置
支持启用/禁用单个握手接口
外设与通道之间的可编程映射;支持多对一映射(同一时间仅一个外设激活)
提供内存映射寄存器,用于在软件握手模式下控制DMA传输
1.3.6 Interrupt Outputs(中断输出)
支持合并中断输出和独立中断输出
中断触发条件包括:
DMA传输完成(DMA transfer completion)
块传输完成(Block transfer completion)
单个或多个事务完成(Single or multiple transaction completion)
错误条件(Error condition)
通道挂起或禁用(Channel suspend or disable)
支持中断使能和屏蔽(Interrupt enabling and masking)
以上是文档中“Flow Control”“Handshaking Interface”“Interrupt Outputs”章节的所有功能点,涵盖了流控制策略、握手接口的配置能力、中断输出的类型与触发条件等核心特性。
术语
文档中对DMA相关核心术语进行了定义(部分关键术语示例,结合上下文推测完整定义方向):
Channel (通道):DMA内用于管理源-目的地数据传输的独立单元,每个通道对应一对源和目标,最多支持32个通道,可配置。
Transaction (事务):AXI总线上的单次数据传输操作,DMA通过多个事务完成一个块(Block)传输。
Burst (突发传输):AXI总线中连续传输多个数据的模式,DMA支持配置突发长度(如AHB从接口的hburst = 3’b000表示单事务突发)。
Flow Controller (流控制器):在DMA块传输中负责控制数据流动的角色——若块大小已知,由DMA控制器自身作为流控制器;若块大小未知(需求模式),由源/目标外设作为流控制器。
Handshaking Interface (握手接口):用于DMA与外设之间同步数据传输的接口,分为软件握手(通过寄存器配置)和硬件握手(通过引脚交互),最多支持64个硬件握手接口,可配置外设与通道的映射关系。
Interrupt (中断):DMA完成任务或出现异常时输出的信号,分为合并/独立中断,触发条件包括传输完成、块完成、错误、通道挂起/禁用等,支持中断使能和屏蔽。
文档中对DMA相关核心术语的定义如下(按原文顺序):
Transaction(事务)
基本DMA传输单元,由硬件或软件握手接口决定。仅当传输发生在DW_axi_dmac与非内存外设之间时,事务才有意义。事务分为两类:
Single transaction(单事务):长度为1,转换为INCR类型的AXI突发传输(burst length = 1)。
Burst transaction(突发事务):突发长度由程序配置到DW_axi_dmac中。突发事务会被转换为一系列AXI突发传输,其长度受程序控制,通常与源/目标外设的FIFO大小相关,且属于DW_axi_dmac与源/目标外设之间的传输。
Block(块)
DW_axi_dmac数据的一个集合,数据量由流控制器(flow controller)决定:
若传输发生在DW_axi_dmac与内存之间:块会被直接拆分为一系列突发事务(burst transactions)。
若传输发生在DW_axi_dmac与非内存外设之间:块会被拆分为一系列DW_axi_dmac事务,这些事务又会被转换为一系列AXI事务。
DMA transfer(DMA传输)
软件控制DW_axi_dmac传输中的块数量。一旦DMA传输完成,硬件会自动禁用通道并可生成中断以通知“DMA传输完成”。通道随后可被重新配置以执行新的DMA传输。
Single-block DMA transfer(单块DMA传输):由一个块组成。
Multi-block DMA transfer(多块DMA传输):由多个DMA块组成。多块DMA传输通过以下方式支持:
块链接(linked list chaining,启用LLI时);
- 自动重加载(auto-reloading)通道寄存器;
- 影子寄存器(shadow registers);
- 连续块(contiguous blocks)。
源和目标可以独立选择使用哪种方法。
Linked lists (block chaining)(链表/块链接)
链表指针(LLP)指向系统内存中下一个链表项(LLI)的位置。LLI是一组描述“下一个块(块描述符)”和“下一个LLI”的寄存器。DW_axi_dmac在块链接使能时,会在每个块的开始时获取LLI。LLI访问总是使用突发大小(arsize/awsize),且该大小与数据总线宽度相同(不能更改或编程为其他值)。突发长度(awlen/arlen)可根据数据总线宽度设置,以确保访问不会跨越一个完整的LLI结构(64字节)。若突发长度不受其他设置限制,DW_axi_dmac会将整个LLI(40字节)在一次AXI突发中传输。
Auto-reloading(自动重加载)
DW_axi_dmac在每个块传输结束时,自动从影子寄存器的内容中重新加载通道寄存器。
Contiguous blocks(连续块)
当地址选择“后续块是前一个块的延续”时,使用连续块模式。
Shadow register(影子寄存器)
DW_axi_dmac在当前块传输进行时,自动将通道寄存器加载为“与下一个块传输对应的值”(这些值由软件在影子寄存器中预先编程)。
Channel locking(通道锁定)
软件可将通道编程为“锁定AXI主接口的仲裁”,持续时间覆盖:
一次DMA传输;
一次块传输;
一次事务(单事务或突发事务)。
Functions
2.13.2 多块传输的 4 种方式
当 DW_axi_dmac 配置为多块传输时,在连续块之间需要重新编程 CHx_SAR(源地址)和 CHx_DAR(目的地址)寄存器。有四种方法可以实现:
1. Contiguous Address(连续地址模式)
工作原理:
- 连续块之间的地址选择为前一块结束地址的延续
- 地址自动递增,无需软件干预
控制方式:
- 通过 CHx_CTL.SRC_MLTBLK_TYPE 和 CHx_CTL.DST_MLTBLK_TYPE 寄存器字段控制
- 限制:CHx_SAR 和 CHx_DAR 不能同时选择为连续模式
实现技巧:
- 如果需要源地址和目的地址都连续,可以使用 Linked List 间接实现
- 设置下一个块描述符的 LLI.CHx_SAR 地址为前一块结束地址 +1
- 设置下一个块描述符的 LLI.CHx_DAR 地址为前一块结束地址 +1
注意事项:
如果启用连续地址模式的多块传输,完整的 DMA 传输必须至少有两个块,否则会导致不可预测的行为。
channel suspend-disable-abort
2.18.1 Channel Suspend(通道挂起)
挂起通道的步骤:
| 步骤 | 操作 |
|---|---|
| 1 | 软件向 DMAC_ChEnReg 的 CH_SUSP 位写入 1 |
| 2 | DW_axi_dmac 在完成所有已发起的 AXI 源端传输后,优雅地停止所有来自源端外设的传输 |
| 3 | DW_axi_dmac 将 CHx_IntStatusReg.CH_SRC_SUSPENDED 置 1,表示源数据传输已挂起,并产生中断(如果未屏蔽) |
| 4 | DW_axi_dmac 将通道 FIFO 中的所有数据传输到目的端外设 |
| 5 | DW_axi_dmac 清除通道锁定,并重置 CHx_CFG 寄存器中的通道锁定设置 |
| 6 | DW_axi_dmac 将 CHx_IntStatusReg.ChLock_Cleared 置 1,表示通道锁定已清除 |
| 7 | DW_axi_dmac 将 CHx_IntStatusReg.CH_SUSPENDED 置 1,表示通道已挂起 |
| 8 | DW_axi_dmac 产生 CH_SUSPENDED 中断(如果未屏蔽) |
注意事项:
- 如果通道 FIFO 已满且目的端外设未请求数据传输,DW_axi_dmac 无法在相应的主接口上接收更多数据,可能导致死锁
- 在 CHx_CTL.SRC_TR_WIDTH < CHx_CTL.DST_TR_WIDTH 的情况下,挂起时 FIFO 中可能仍有数据但不足以形成单次目的端传输,这些数据会在通道恢复后继续传输
2.18.2 Channel Suspend and Resume(通道挂起与恢复)
挂起后恢复的步骤:
| 步骤 | 操作 |
|---|---|
| 1 | 执行 Channel Suspend 的步骤 1-4 |
| 2 | 软件向 DMAC_ChEnReg.CH_SUSP 位写入 0 |
| 3 | DW_axi_dmac 从挂起点恢复 DMA 传输 |
重要限制:
一旦软件启动挂起操作(写入 1 到 CH_SUSP),在 CHx_IntStatusReg.CH_SUSPENDED 置 1 之前,软件不能通过写入 0 来恢复通道。DW_axi_dmac 会忽略此写入操作。
2.18.3 Channel Suspend and Disable(通道挂起后禁用)
挂起后禁用的步骤:
| 步骤 | 操作 |
|---|---|
| 1 | 执行 Channel Suspend 的步骤 1-4 |
| 2 | 在 CHx_IntStatusReg.CH_SUSPENDED 置 1 后,软件向 DMAC_ChEnReg.CH_EN 写入 0 来禁用通道 |
| 3 | DW_axi_dmac 将 CHx_IntStatusReg.CH_DISABLED 置 1 |
| 4 | DW_axi_dmac 产生 CH_DISABLED 中断(如果未屏蔽) |
| 5 | DW_axi_dmac 清除 DMAC_ChEnReg.CH_EN 位为 0 |
数据丢失警告:
当 CHx_CTL.SRC_TR_WIDTH < CHx_CTL.DST_TR_WIDTH 时,FIFO 中剩余的数据不会被传输到目的端外设,数据会丢失。
2.18.4 Channel Disable without Suspend(不挂起直接禁用)
直接禁用通道的步骤:
| 步骤 | 操作 |
|---|---|
| 1 | 软件向 DMAC_ChEnReg.CH_EN 写入 0 |
| 2 | DW_axi_dmac 在完成所有已发起的 AXI 源端传输后,优雅地停止所有来自源端外设的传输 |
| 3 | DW_axi_dmac 将通道 FIFO 中的所有数据传输到目的端外设 |
| 4 | DW_axi_dmac 清除通道锁定,并重置 CHx_CFG 寄存器 |
| 5 | DW_axi_dmac 将 CHx_IntStatusReg.ChLock_Cleared 置 1 |
| 6 | DW_axi_dmac 将 CHx_IntStatusReg.CH_DISABLED 置 1 |
| 7 | DW_axi_dmac 产生 CH_DISABLED 中断(如果未屏蔽) |
| 8 | DW_axi_dmac 清除 DMAC_ChEnReg.CH_EN 位为 0 |
重要限制:
一旦软件启动禁用操作(写入 0 到 CH_EN),在 CHx_IntStatusReg.CH_DISABLED 置 1 之前,软件不能通过写入 1 来重新使能通道。DW_axi_dmac 会忽略此写入操作。
2.18.5 Abnormal Channel Abort(异常通道中止)
中止不是推荐的操作! 仅在以下情况使用:
- 软件想要禁用通道但不想重置整个 DW_axi_dmac
- 例如:某个通道由于未收到握手接口的响应而挂起
建议: 在中止之前,应先尝试禁用通道。
中止通道的步骤:
| 步骤 | 操作 |
|---|---|
| 1 | 软件向 DMAC_ChEnReg.CH_ABORT 写入 1 |
| 2 | DW_axi_dmac 在完成所有已发起的 AXI 源端/目的端传输后,优雅地停止所有传输 |
| 3 | 通道 FIFO 中的数据被刷新,会丢失 |
| 4 | DW_axi_dmac 清除通道锁定,并重置 CHx_CFG 寄存器 |
| 5 | DW_axi_dmac 将 CHx_IntStatusReg.ChLock_Cleared 置 1 |
| 6 | DW_axi_dmac 将 CHx_IntStatusReg.CH_ABORTED 置 1 |
| 7 | DW_axi_dmac 产生 CH_ABORTED 中断(如果未屏蔽) |
| 8 | DW_axi_dmac 清除 DMAC_ChEnReg.CH_EN 位为 0 |
三种操作对比:
| 特性 | Suspend | Disable | Abort |
|---|---|---|---|
| 目的 | 暂时暂停传输 | 正常停止传输 | 紧急停止传输 |
| FIFO 数据 | 保留,可继续传输 | 尝试传输,剩余丢失 | 全部丢失 |
| 恢复能力 | 可恢复 | 不可恢复 | 不可恢复 |
| 推荐使用 | ✓ | ✓ | ✗ (仅紧急情况) |
| 中断状态 | CH_SUSPENDED | CH_DISABLED | CH_ABORTED |
multi blocks transfer(重点)
4种多块传输模式:
- 连续地址模式
- 自动重载模式
- 影子寄存器模式
- LLI模式
连续地址模式
工作原理:
- 连续块之间的地址选择为前一块结束地址的延续
- 地址自动递增,无需软件干预
控制方式:
- 通过 CHx_CTL.SRC_MLTBLK_TYPE 和 CHx_CTL.DST_MLTBLK_TYPE 寄存器字段控制
- 限制:CHx_SAR 和 CHx_DAR 不能同时选择为连续模式
实现技巧:
- 如果需要源地址和目的地址都连续,可以使用 Linked List 间接实现
- 设置下一个块描述符的 LLI.CHx_SAR 地址为前一块结束地址 +1
- 设置下一个块描述符的 LLI.CHx_DAR 地址为前一块结束地址 +1
注意事项:
如果启用连续地址模式的多块传输,完整的 DMA 传输必须至少有两个块,否则会导致不可预测的行为。
自动重载模式
工作原理:
- 在每个块传输完成时,通道传输控制寄存器用它们的初始值重新加载
- 这些重新加载的值用于新的块传输
可重载的寄存器:
| 寄存器 | 说明 |
|---|---|
| CHx_SAR | 源地址寄存器 |
| CHx_DAR | 目的地址寄存器 |
| CHx_BLOCK_TS | 块传输大小寄存器 |
| CHx_CTL | 通道控制寄存器 |
具体重载哪些寄存器取决于为源和目的外设选择的多块传输类型(参见 Table 2-4)。
同步机制:
如果块传输完成中断未屏蔽,DW_axi_dmac 会等待软件向 DMAC_IntClear_Reg 寄存器写入 1 来清除中断,然后才会继续下一个块传输。
注意事项:
如果启用自动重载模式的多块传输,完整的 DMA 传输必须至少有两个块,否则会导致不可预测的行为。
影子寄存器模式
工作原理:
- 在每个块传输完成时,通道传输控制寄存器从对应的阴影寄存器加载
- 这些值用于新的块传输
可加载的寄存器:
| 寄存器 | 说明 |
|---|---|
| CHx_SAR | 源地址寄存器 |
| CHx_DAR | 目的地址寄存器 |
| CHx_BLOCK_TS | 块传输大小寄存器 |
| CHx_CTL | 通道控制寄存器 |
关键特性:
- 无独立内存映射:阴影寄存器没有独立的内存映射
- 软件写入方式:软件总是写入 CHx_SAR, CHx_DAR, CHx_BLOCK_TS 和 CHx_CTL 寄存器
- 硬件内部路由:如果使用阴影寄存器模式,DW_axi_dmac 内部将数据路由到对应的阴影寄存器
- 读取行为:读取这些寄存器始终返回当前块的传输数据,而不是阴影寄存器内容(对应下一个块)
有效性检查:
- CHx_CTL.ShadowReg_Or_LLI_Valid 位指示阴影寄存器内容是否有效
- 0 = 无效
- 1 = 有效
- 如果在获取阶段读取为 0,DW_axi_dmac 会:
a. 丢弃阴影寄存器内容
b. 产生 ShadowReg_Or_LLI_Invalid_ERR 中断
c. 等待软件向 CHx_BLK_TFR_ResumeReqReg 寄存器写入任意值,表示有效数据已就绪
配置参数:
如果 DMAX_CHx_SHADOW_REG_EN 参数设置为 0,阴影寄存器模式被禁用。
LLI 模式
LLI 描述符结构
DesignWare AXI DMA 支持通过链表(Linked List)实现多块传输。链表项(LLI)是一个 64 字节对齐的数据结构,包含以下字段:
| 字段 | 宽度 | 功能 |
|---|---|---|
| SAR | 64 位 | 源数据地址 |
| DAR | 64 位 | 目的数据地址 |
| BLOCK_TS | 20 位 | 块传输大小(单位:传输宽度) |
| LLP | 64 位 | 指向下一个描述符的指针(bit[5:0] 必须为 0,64 字节对齐) |
| CTRL_L | 32 位 | 传输宽度、burst 大小等 |
| CTRL_H | 32 位 | 中断使能、LLI 结束标志等 |
CH_CFG_L 寄存器配置:
| 位 | 字段 | 说明 |
|---|---|---|
| [3:0] | SRC_MULTBLK_TYPE / DST_MULTBLK_TYPE | 多块传输类型选择 |
| 0b0000 = CONTIGUOUS(连续地址) | ||
| 0b0001 = RELOAD(自动重载) | ||
| 0b0010 = SHADOW(阴影寄存器) | ||
| 0b1111 = LINKED_LIST(链表) |
CH_CTL_H 寄存器配置:
| 位 | 字段 | 说明 |
|---|---|---|
| [31] | LLP_SRC_EN | LLI 源使能 |
| [30] | LLP_DST_EN | LLI 目的使能(最后一个描述符设为 1) |
| [26] | IOC_BlkTfr | Block 完成中断使能 |
LLI 链式传输流程:
软件配置 CH_LLP_L/H 寄存器指向第一个 LLI 描述符
DMA 引擎取指 desc[0],执行传输,完成中断(可选)
根据 LLP 取指 desc[1],执行传输,完成中断(可选)
重复直到最后一个描述符(LLP_DST_EN=1,链表结束)
中断
中断类型
DW_axi_dmac 支持以下几大类中断:
1. 传输完成类中断(Channel Interrupts)
| 中断名称 | 触发条件 | 寄存器位 |
|---|---|---|
| Block Transfer Done | 块传输完成 | CHx_INTSTATUS.Block_Tfr_Done |
| Transaction Done | 事务传输完成 | CHx_INTSTATUS.Tran_Done |
| Source Transaction Done | 源端事务完成 | CHx_INTSTATUS.Src_Tran_Done |
| Destination Transaction Done | 目的端事务完成 | CHx_INTSTATUS.Dst_Tran_Done |
| DMA Transfer Done | DMA 传输完成 | CHx_INTSTATUS.DMA_Tfr_Done |
| Channel Disable Done | 通道禁用完成 | CHx_INTSTATUS.Ch_Disabled |
2. 错误类中断(Error Interrupts)
| 中断名称 | 触发条件 | 寄存器位 |
|---|---|---|
| AXI Bus Error | AXI 总线错误(源端) | CHx_INTSTATUS.Src_AXI_Bus_Err |
| AXI Bus Error | AXI 总线错误(目的端) | CHx_INTSTATUS.Dst_AXI_Bus_Err |
| LLI Fetch Error | LLI 取指错误 | CHx_INTSTATUS.LLP_Fetch_Err |
| LLI Write-back Error | LLI 回写错误 | CHx_INTSTATUS.LLP_Writeback_Err |
3. ECC 保护类中断(ECC Protection Interrupts)
| 中断名称 | 触发条件 | 寄存器位 |
|---|---|---|
| FIFO ECC Correctable Error | FIFO 单比特错误(已纠正) | CHx_INTSTATUS.ECC_PROT_CHMem_CorrERR |
| FIFO ECC Uncorrectable Error | FIFO 多比特错误(不可纠正) | CHx_INTSTATUS.ECC_PROT_CHMem_UnCorrERR |
| AXI Master ECC Correctable Error | AXI 主接口单比特错误 | DMAC_COMMONREG_INTSTATUS.MXIF_ECC_CorrERR |
| AXI Master ECC Uncorrectable Error | AXI 主接口多比特错误 | DMAC_COMMONREG_INTSTATUS.MXIF_ECC_UnCorrERR |
4. 奇偶校验错误中断(Parity Error Interrupts)
| 中断名称 | 触发条件 | 寄存器位 |
|---|---|---|
| Common Register Parity Error | 公共寄存器写奇偶校验错误 | DMAC_COMMONREG_INTSTATUS.SLVIF_CommonReg_WRPARITY_ERR |
| Channel Register Parity Error | 通道寄存器写奇偶校验错误 | CHx_INTSTATUS.SLVIF_WRPARITY_ERR |
5. 通用中断(Common Interrupts)
| 中断名称 | 触发条件 |
|---|---|
| Common Register Interrupt | 任意通道中断汇总 |
| Combined Interrupt | 所有中断的综合输出 |
中断生成机制
中断生成流程图:
1 | 传输事件/错误发生 |
中断使能层次结构:
| 层级 | 名称 | 寄存器/位 |
|---|---|---|
| Level 1 | 全局中断使能 | DMAC_CFG.INT_EN (bit 1) |
| Level 2 | 通道中断使能 | CHx_INTSTATUS_ENA |
| Level 3 | 中断信号使能 | CHx_INTSIGNAL_ENA |
| 输出 | 中断输出 | → 中断输出 |
中断寄存器映射
3.1 通道中断寄存器(每通道)
| 寄存器 | 偏移 | 功能 |
|---|---|---|
| CHx_INTSTATUS | 0x088 | 中断状态寄存器(R/W) |
| CHx_INTSTATUS_ENA | 0x080 | 中断使能寄存器(R/W) |
| CHx_INTSIGNAL_ENA | 0x090 | 中断信号使能寄存器(R/W) |
| CHx_INTCLEAR | 0x098 | 中断清除寄存器(W) |
3.2 通用中断寄存器
| 寄存器 | 偏移 | 功能 |
|---|---|---|
| DMAC_COMMONREG_INTSTATUS | 0x050 | 通用中断状态 |
| DMAC_COMMONREG_INTSTATUS_ENA | 0x040 | 通用中断使能 |
| DMAC_COMMONREG_INTSIGNAL_ENA | 0x048 | 通用中断信号使能 |
| DMAC_COMMONREG_INTCLEAR | 0x038 | 通用中断清除 |
| DMAC_INTSTATUS | 0x030 | 综合中断状态输出 |
中断处理流程
4.1 轮询模式处理流程
1 | // 1. 配置传输 |
4.2 中断模式处理流程
1 | // 1. 注册中断处理函数 |
错误处理流程
5.1 AXI 总线错误处理
当发生 AXI 总线错误时:
1. 硬件自动操作:
- DMA 传输优雅停止
- 通道自动禁用
- CHx_INTSTATUS 错误位置位
- CH_DISABLED 状态位置位
2. 软件处理流程:
1 | // 检查错误中断 |
5.2 ECC 错误处理
1 | // 读取 ECC 错误状态 |
中断输出配置 & 中断位定义
六、中断输出配置
DMAC 支持三种中断输出配置模式(通过 DMAX_INTR_IO_TYPE 参数配置):
| 模式 | 值 | 中断输出 |
|---|---|---|
| COMBINED_ONLY | 0 | 单一综合中断输出 |
| CHANNEL_AND_COMMONREG | 1 | 分离的通道中断 + 通用中断 |
| ALL_INTERRUPT_OUTPUTS | 2 | 所有中断独立输出 |
七、中断位定义(CHx_INTSTATUS)
| 位 | 名称 | 说明 |
|---|---|---|
| Bit 0 | Block_Tfr_Done | 块传输完成 |
| Bit 1 | Tran_Done | 事务传输完成 |
| Bit 2 | Src_Tran_Done | 源事务完成 |
| Bit 3 | Dst_Tran_Done | 目的事务完成 |
| Bit 4 | DMA_Tfr_Done | DMA 传输完成 |
| Bit 5 | Ch_Disabled | 通道禁用完成 |
| Bit 6 | Src_AXI_Bus_Err | 源 AXI 总线错误 |
| Bit 7 | Dst_AXI_Bus_Err | 目的 AXI 总线错误 |
| Bit 8 | LLP_Fetch_Err | LLI 取指错误 |
| Bit 9 | LLP_WriteBack_Err | LLI 回写错误 |
| Bit 10 | ECC_PROT_CorrERR | ECC 可纠正错误 |
| Bit 11 | ECC_PROT_UnCorrERR | ECC 不可纠正错误 |
| Bit 12 | SLVIF_WRPARITY_ERR | 写奇偶校验错误 |
实际代码实现
1 | void axidma_irq_handler1(unsigned int irq_id) |
最佳实践
八、中断配置最佳实践
1. 传输前配置:
- 清除所有 pending 中断
- 配置中断使能寄存器
- 使能全局中断
2. 中断服务程序:
- 首先读取中断状态
- 根据中断类型执行相应处理
- 及时清除中断状态
3. 错误处理:
- 使能错误中断
- 在中断中记录错误信息
- 必要时重新初始化传输
ECC特性
TODO:
berametal implement
LLI
描述符说明 & 结构实现
1.1 硬件描述符格式(64 字节对齐)
1 | struct axidma_desc { |
1.2 描述符字段说明
| 字段 | 宽度 | 功能 |
|---|---|---|
| SAR | 64 位 | 源数据地址 |
| DAR | 64 位 | 目的数据地址 |
| BLOCK_TS | 20 位 | 块传输大小(单位:传输宽度) |
| LLP | 64 位 | 指向下一个描述符的指针(bit[5:0] 必须为 0,64 字节对齐) |
| CTRL_L | 32 位 | 传输宽度、burst 大小等 |
| CTRL_H | 32 位 | 中断使能、LLI 结束标志等 |
核心配置函数实现
2.1 函数原型
1 | void __axidma_config(struct axidma_config config, struct axidma_desc *desc) |
2.2 配置流程
1 | void __axidma_config(struct axidma_config config, struct axidma_desc *desc) |
关键寄存器配置:
CH_CFG_L 寄存器:
- [3:0] SRC_MULTBLK_TYPE / DST_MULTBLK_TYPE
- 0b0000 = CONTIGUOUS(连续地址)
- 0b0001 = RELOAD(自动重载)
- 0b0010 = SHADOW(阴影寄存器)
- 0b1111 = LINKED_LIST(链表)
CH_CTL_H 寄存器:
- [31] LLP_SRC_EN - LLI 源使能
- [30] LLP_DST_EN - LLI 目的使能(最后一个描述符设为 1)
- [26] IOC_BlkTfr - Block 完成中断使能
测试用例
基础 LLI 测试 — 2 段链表
基础 LLI 测试 — 5 段链表
多 SG 列表测试
多通道 + 优先级 + LLI 测试
压力测试
测试用例汇总表:
| 测试函数 | 功能 | 描述符数量 | 通道数 | 特性 |
|---|---|---|---|---|
| dmac_memcpy_lli_func04_2 | 基础 LLI 测试 | 2 | 1 | 验证基本链表功能 |
| dmac_memcpy_lli_func04_3 | 多段 LLI 测试 | 5 | 1 | 验证长链表功能 |
| dmac_memcpy_lli_func05 | SG 列表测试 | 10+ | 1 | 验证分散传输 |
| dmac_memcpy_lli_func06 | 多通道 + 优先级 | 15×2 | 2 | 验证通道仲裁 |
| dmac_stress_lli_func06 | 压力测试 | 多段×8 | 8 | 验证满载性能 |
多 SG 列表测试
该测试用例主要特点在与:SRC/DST的地址都不连续:
1 | int dmac_memcpy_lli_func05(unsigned int id, unsigned int chann, unsigned int width) |
内存布局图示
源内存区域 (DDR) 与 目的内存区域 (DDR) 映射:
1 | 源内存区域 (DDR) 目的内存区域 (DDR) |
说明:
- 每段间隔 = 0x1000 (未使用)
- 每段大小 = 0x1000 (4KB)
- 总传输数据 = 10 × 4KB = 40KB
静态描述符数组
静态分配的描述符数组 (desc1[MAX_DESC_NUMS]):
1 | desc1[0] |
软硬件执行流程图
软件配置流程:
1 | 1. 分配描述符数组 (64 字节对齐) |
硬件执行流程:
1 | DMA 引擎取指 desc[0] → 执行传输 → 完成中断 (可选) |
关键参数
AXI DMAC 关键参数汇总表
| 参数名称 | 最小值 | 最大值 | 默认值 | 决定因素 | 相关寄存器/位 |
|---|---|---|---|---|---|
| Transfer Width (TR_WIDTH) | 8 bit | 128 bit | - | 软件可编程 | CHx_CTL.SRC_TR_WIDTH[14:12], CHx_CTL.DST_TR_WIDTH[10:8] |
| Burst Size (MSIZE) | 1 beat | 32 beats | - | 软件可编程 | CHx_CTL.SRC_MSIZE[28:26], CHx_CTL.DST_MSIZE[24:22] |
| 最大通道数量 | 1 | 32 | 1 | 配置参数 DMAX_NUM_CHANNELS | - |
| 同时并行工作通道数 | 1 | 配置值 | - | 由仲裁器和配置决定 | CHx_CFG_H.CH_PRIOR |
| 最大 Block Size (BLOCK_TS) | 1 | 0x40000 (256K) | - | 硬件固定限制 | CHx_BLOCK_TS[17:0] |
| 硬件握手接口数量 | 0 | 64 | 2 | 配置参数 DMAX_NUM_HS_IF | - |
| AXI 主接口数量 | 1 | 2 | 1 | 配置参数 DMAX_NUM_MASTER_IF | - |
| AXI 数据总线宽度 | 32 bit | 512 bit | - | 配置参数 DMAX_M_DATA_WIDTH | - |
| 通道优先级 | 0 | DMAX_NUM_CHANNELS-1 | - | 软件可编程 | CHx_CFG_H.CH_PRIOR[44:42] |
| FIFO 深度 | 8 | 可配置 | - | 配置参数 DMAX_CHx_FIFO_DEPTH | - |
| FIFO 宽度 | 32 bit | 128 bit | - | 配置参数 DMAX_CHx_FIFO_WIDTH | - |
| LLI 描述符大小 | - | 64 bytes | - | 硬件固定 | - |
| LLP 对齐要求 | - | 64-byte | - | 硬件固定(低 6 位必须为 0) | CHx_LLP[31:6] |
| 最大 outstanding 请求数 | 16 | 128 | 16 | 配置参数 DMAX_MSTIF_OSR_LMT | CHx_CFG_H.SRC_OSR_LMT, DST_OSR_LMT |
Transfer width
传输宽度编码表:
| 编码值 | 传输宽度 | 说明 |
|---|---|---|
| 0 | 8 bit (1 byte) | 字节传输 |
| 1 | 16 bit (2 bytes) | 半字传输 |
| 2 | 32 bit (4 bytes) | 字传输 |
| 3 | 64 bit (8 bytes) | 双字传输 |
| 4 | 128 bit (16 bytes) | 128 位传输 |
寄存器位置:
- CHx_CTL.SRC_TR_WIDTH[14:12] - 源传输宽度
- CHx_CTL.DST_TR_WIDTH[10:8] - 目的传输宽度
Burst size
Burst 长度编码表:
| 编码值 | Burst 长度 | 说明 |
|---|---|---|
| 0 | 1 beat | 单次传输 |
| 1 | 4 beats | 4 拍突发 |
| 2 | 8 beats | 8 拍突发 |
| 3 | 16 beats | 16 拍突发 |
| 4 | 32 beats | 32 拍突发 |
| 5-7 | 保留 | - |
寄存器位置:
- CHx_CTL.SRC_MSIZE[28:26] - 源突发长度
- CHx_CTL.DST_MSIZE[24:22] - 目的突发长度
Block size
Block Size 参数表:
| 参数 | 值 |
|---|---|
| 最大值 | 0x40000 (256K 传输单元) |
| 寄存器 | CHx_BLOCK_TS[17:0] |
| 实际字节数 | BLOCK_TS × TR_WIDTH/8 |
计算公式:
1 | 实际传输字节数 = (BLOCK_TS + 1) × (2^TR_WIDTH) / 8 |
示例:
- TR_WIDTH=2 (32bit), BLOCK_TS=0x40000 → 最大 1MB
- TR_WIDTH=3 (64bit), BLOCK_TS=0x40000 → 最大 2MB
FIFO
FIFO 参数表:
| 参数 | 范围 | 默认值 | 配置参数 |
|---|---|---|---|
| FIFO 深度 | 8 ~ 可配置 | - | DMAX_CHx_FIFO_DEPTH |
| FIFO 宽度 | 32/64/128 bit | - | DMAX_CHx_FIFO_WIDTH |
| ECC 保护 | Yes/No | No | DMAX_ECC_MEMIF_EN |
FIFO 与 ECC 开销
FIFO 宽度与 ECC 开销表:
| FIFO 宽度 | FIFO 深度 | ECC 前数据宽度 | ECC 校验位 | ECC 后总宽度 |
|---|---|---|---|---|
| 32 bit | 8 | 35 | 7 | 42 |
| 32 bit | 32 | 37 | 7 | 44 |
| 64 bit | 8 | 67 | 8 | 75 |
| 64 bit | 32 | 69 | 8 | 77 |
| 128 bit | 32 | 133 | 9 | 142 |
中断输出配置
一般使用 comb 中断?
中断输出模式表:
| 模式 | 输出信号 |
|---|---|
| COMBINED_ONLY (0) | intr(所有中断组合) |
| CHANNEL_AND_COMMONREG (1) | intr_ch, intr_cmreg |
| ALL_INTERRUPT_OUTPUTS (2) | intr, intr_ch, intr_cmreg |
握手信号
核心目的
是的,握手信号的设计就是用来做 Flow Control (流量控制) 的。
握手信号在 DMA 传输中起到以下关键作用:
- 协调 DMA 与外设之间的数据传输节奏 - 确保外设准备好接收/发送数据时 DMA 才动作
- 支持可变长度的块传输 - 外设可以动态控制何时结束一个 block
- 区分单次传输和突发传输 - 外设可以请求不同类型的传输
- 支持两种 Flow Controller 模式 - DMA 作为流控制器 或 外设作为流控制器
硬件握手信号
握手信号定义表:
| 信号名 | 方向 | 含义 |
|---|---|---|
| dma_req | 外设→DMAC | 突发传输请求 |
| dma_single | 外设→DMAC | 单次传输请求/状态 |
| dma_last | 外设→DMAC | 最后一次传输指示 |
| dma_ack | DMAC→外设 | DMAC 确认 |
| dma_finish | DMAC→外设 | 块传输完成指示 |
两种流控模式
这是理解握手信号的关键。DMAC 支持两种流控模式:
模式 1:DMAC 作为 Flow Controller(外设不是流控器)
适用场景: 传输长度已知的固定长度数据块
| 信号 | 行为 |
|---|---|
| dma_req | 请求突发传输,必须保持到 dma_ack 到来 |
| dma_single | 仅在 Single Transaction Region 有效,表示外设能接收/发送至少 1 个数据 |
| dma_last | 被忽略,无意义 |
| dma_ack | 传输完成后 assertion,等待外设撤销请求后 de-assert |
| dma_finish | Block 传输完成时 assertion |
时序规则:
1 | 外设:dma_req 断言 ───────┐ |
模式 2:外设作为 Flow Controller
适用场景: 传输长度未知的可变长度数据块(如 FIFO 数据)
| 信号 | 行为 |
|---|---|
| dma_req | 必须与 dma_single 或 dma_last 同时 assertion 才有效 |
| dma_single | 与 dma_req 同时 assertion = 请求单次传输 |
| dma_last | 与 dma_req 同时 assertion = 这是最后一次传输 |
| dma_ack | 传输完成后 assertion,外设撤销请求后立即撤销 |
| dma_finish | 与 dma_ack 同时 assertion,表示 block 完成 |
组合逻辑(外设是流控器时):
| dma_req | dma_single | dma_last | DMAC 动作 |
|---|---|---|---|
| 0 | X | X | 无效请求 |
| 1 | 0 | 0 | 突发传输(非最后) |
| 1 | 0 | 1 | 突发传输(最后一次) |
| 1 | 1 | 0 | 单次传输(非最后) |
| 1 | 1 | 1 | 单次传输(最后) |
握手接口映射的硬件设计和软件配置
握手配置代码实现:
1 |
|
硬件预设外设与 DMAC 的握手信号的 HS_IF 编号示例:
| 外设 | 推荐 HS_IF 编号 | Flow Controller | SRC_HS_IF | DST_HS_IF | 说明 |
|---|---|---|---|---|---|
| UART RX | 0 | DMAC | 0 | N/A | UART 作为源,FIFO 满阈值请求 |
| UART TX | 1 | DMAC | N/A | 1 | UART 作为目的,FIFO 空阈值请求 |
| SPI RX | 2 | DMAC | 2 | N/A | SPI RX FIFO 数据就绪请求 |
| SPI TX | 3 | DMAC | N/A | 3 | SPI TX FIFO 有空位请求 |
| I2C RX | 4 | DMAC | 4 | N/A | I2C 字节接收完成请求 |
| I2C TX | 5 | DMAC | N/A | 5 | I2C TX FIFO 空请求 |
握手接口映射配置寄存器说明:
CHx_CFG_L 寄存器 - SRC_PER 字段:
SRC_PER 字段 Assigns a hardware handshaking interface (0 - DMAX_NUM_HS_IF-1) to the source of Channelx if the CHx_CFG.HS_SEL_SRC field is 0; otherwise, this field is ignored.
注意: For correct DW_axi_dmac operation, only one peripheral (source or destination) should be assigned to the same handshaking interface.
SRC_PER 就是 DMA 通道到源外设握手接口的 “接线开关”:
你选一个接口号 → 这个通道就和对应外设的 req/ack 线连上了。
接口数量决定了这个字段的位宽,最多支持 DMAX_NUM_HS_IF 个外设同时握手。
注意,多个外设可以使用同一 HS_IF,但同一时间只能一个通道使用
注意事项汇总表:
| 注意事项 | 说明 |
|---|---|
| 1. 握手信号时序 | dma_req/dma_single assertion 后必须保持到 dma_ack 到来 |
| 2. 跨时钟域处理 | 外设时钟与 DMAC 时钟不同步时,需使能 DMAX_ASYNC_HS_EN |
| 3. Burst 长度选择 | 根据外设 FIFO 深度选择,通常 FIFO 深度的 1/2 或 1/4 |
| 4. Flow Controller 选择 | 固定长度传输用 DMAC 流控,可变长度用外设流控 |
| 5. 握手接口复用 | 多个外设可共享同一 HS_IF,但同一时间只能一个通道使用 |
| 6. Single Transaction Region | 块传输的尾部区域,剩余数据不足一次 Burst 时使用单次传输 |
总结
握手信号常见问题解答:
| 问题 | 答案 |
|---|---|
| 握手信号是用来做 Flow Control 的吗? | 是的,核心目的就是流量控制 |
| 软件需要做什么配置? | 配置 Flow Controller 角色、握手类型、握手接口映射、Burst 长度 |
| 硬件设计要注意什么? | dma_req/dma_single/dma_last assertion 后必须保持到 dma_ack 到来 |
| 两种 Flow Controller 模式的区别? | DMAC 流控 = 固定长度传输;外设流控 = 可变长度传输 |
| Single Transaction Region 是什么? | 块传输的尾部区域,剩余数据不足一次 Burst 时使用单次传输 |