手册1.3,3.4,3.5,3.6,3.7.1。DMA(直接存储器访问)控制器
基本概念
1. Source peripheral(源外设)
- 定义:源外设是DMA控制器(DW_ahb_dmac)读取数据的设备,通常位于AHB总线层级。DMA控制器将从源外设读取的数据存储在通道FIFO(先进先出队列)中。
- 角色:源外设与目标外设一起组成DMA通道。源外设可以是AHB或APB从设备。如果是APB从设备,则通过AHB-APB桥接器访问。
2. Destination peripheral(目标外设)
- 定义:目标外设是DMA控制器将FIFO中存储的数据写入的设备。
- 角色:目标外设也可以是AHB或APB从设备。如果是APB从设备,则同样需要通过AHB-APB桥接器访问。
3. Memory(内存)
- 定义:内存是源或目标外设的一种形式,通常表示不需要握手接口即可与DMA控制器交互的数据源或目标。内存外设不需要等待信号,而是“随时准备”进行DMA传输。
- 条件:如果外设插入的等待状态超过16个,则不能作为内存外设,而需要通过握手接口来与DMA控制器交互。如果外设的等待状态较少,则可以将其配置为内存外设。
4. Channel(通道)
- 定义:通道是源外设和目标外设之间的数据传输路径。数据通过通道的FIFO从源外设传输到目标外设。
- 特征:如果源外设不是内存,则通道会有一个源握手接口;如果目标外设不是内存,则会有目标握手接口。可以动态配置这些握手接口。
5. Master interface(主接口)
- 定义:DMA控制器在AHB总线上充当主设备,读取源外设的数据并将其写入目标外设。DMA控制器最多可以有四个主接口,这意味着最多可以同时运行四个独立的源和目标通道。
- 作用:每个通道需要竞争主接口。如果源和目标外设位于不同的AHB层上,则需要多个主接口。
6. Slave interface(从接口)
- 定义:这是DMA控制器用来配置的AHB接口。这个从接口可以与主接口在同一层级,也可以位于不同的层级。
7. Handshaking interface(握手接口)
- 定义:握手接口是用来控制DMA传输的信号或软件寄存器集合,它遵循特定的协议,用于请求、确认和控制DMA事务。握手接口有三种类型:
- Hardware handshaking interface(硬件握手接口):通过硬件信号控制DMA传输。适用于要求实时传输控制的情况。
- Software handshaking interface(软件握手接口):通过软件寄存器控制DMA传输。适用于无需修改外设硬件的情况下,可以方便地与现有外设进行DMA交互。
- Peripheral interrupt handshaking interface(外设中断握手接口):使用外设中断信号作为握手接口,控制DMA传输。
8. Flow controller(流控制器)
- 定义:流控制器是决定DMA块传输长度并终止传输的设备。流控制器可以是DMA控制器本身,也可以是源或目标外设。
- 情况:
- 如果传输块的长度已知,可以由DMA控制器充当流控制器。
- 如果传输块的长度不确定,外设充当流控制器,控制数据块的结束。
9. Flow control mode (CFGx.FCMODE)(流控制模式)
- 定义:只有在目标外设作为流控制器时,这种模式才适用。它控制从源外设的数据预取(pre-fetch)方式。
10. Transfer hierarchy(传输层次结构)
- 定义:下图说明了DW_ahb_dmac传输、块传输、事务(单次或突发)和AHB总线传输之间的层次关系。它显示了DMA控制器如何管理不同类型的传输,并进行调度。(对于内存外设是没有DMA Transaction Level的,这一点很重要)
和内存的通信
Block(块)
- 定义:块是DMA控制器传输的数据单元,块的大小由流控制器决定。在与内存的传输中,一个块会直接分解成多个突发传输(burst)和单次传输(single transfer)。而在与非内存外设的传输中,块会被分解成多个DMA事务(单次或突发),这些事务进一步分解为AHB总线传输。
Transaction(事务)
- 定义:事务是DMA传输的基本单位,事务的类型和长度由硬件或软件握手接口决定。在与非内存外设的传输中,每个事务对应一个或多个AHB传输。事务分为两种类型:
- Single transaction(单次事务):长度为1的事务,直接转换为一个单独的AHB传输。
- Burst transaction(突发事务):长度可编程,通常与FIFO大小和源/目标外设的容量有关。突发事务会被转换为多个突发传输和AHB单次传输的序列。
DMA transfer(DMA传输)
- 定义:DMA传输由软件控制块的数量,传输完成后,DMA控制器会禁用通道,并可能产生中断来通知传输完成,之后可以重新编程通道进行新的传输。
- Single-block DMA transfer(单块DMA传输):仅包含一个块。
- Multi-block DMA transfer(多块DMA传输):可以由多个DMA块组成,支持块链(linked list)、自动重载寄存器和连续块等方式。
Linked lists (block chaining)(链表和块链)
- 定义:链表指针(LLP)指向下一个链表项的位置。每个链表项(LLI)包含描述下一个块的寄存器。DMA控制器每次传输开始时都会获取链表项。链表访问总是32位,不能更改为其他数据宽度,即使支持更宽的数据总线接口。
Auto-reloading(自动重载)
- 定义:在每个块结束时,DMA控制器自动将通道寄存器重新加载为通道最初启用时的值。这样可以简化多块传输的管理。
Contiguous blocks(连续块)
- 定义:连续块的地址选择方式是从前一个块的结束地址继续。即块与块之间的地址是连续的。
Scatter(分散)
- 定义:适用于目标传输。分散操作意味着在每到达一个分散边界时,目标地址会按程序设定的增量(或减量)变化,且软件可以控制每两个分散边界之间的AHB传输数量。
Gather(聚集)
- 定义:适用于源传输。聚集操作意味着在每到达一个聚集边界时,源地址会按程序设定的增量(或减量)变化,软件也可以控制每两个聚集边界之间的AHB传输数量。
Channel locking(通道锁定)
- 定义:软件可以将通道设置为锁定状态,这样在DMA传输、块或事务期间,DMA控制器会保持AHB主接口的控制权,防止其他模块争用总线。
Bus locking(总线锁定)
- 定义:软件可以通过总线锁定机制来保持DMA控制器对AHB总线的控制,直到DMA传输完成。总线锁定通常伴随通道锁定一起使用。
FIFO mode(FIFO模式)
- 定义:FIFO模式通过减少请求总线接口的次数来提高带宽。启用FIFO模式后,DMA通道只有在FIFO缓冲区未满一半时才会从源外设请求数据,只有在FIFO达到或超过一半时才会将数据传输到目标外设。
Pseudo fly-by operation(伪飞行操作)
- 定义:在源外设和目标外设位于不同的AHB层时,DMA控制器可以同时从源外设读取数据并将数据写入目标外设。这意味着数据既能存储到FIFO,又能从FIFO写入目标外设,从而优化了数据传输的效率。
传输计算
1. 源单次传输大小(Source single transaction size in bytes)
- 定义:源单次传输大小指的是每次DMA从源外设读取的数据量。该值由源传输宽度(
CTLx.SRC_TR_WIDTH
)决定。CTLx.SRC_TR_WIDTH
是一个寄存器字段,表示源传输的宽度(通常是一个数据宽度,单位为位)。为了得到源单次传输的字节数,必须将该宽度除以8,因为1字节等于8位。 - 公式:
$$
\text{src_single_size_bytes} = \frac{\text{CTLx.SRC_TR_WIDTH}}{8}
$$
例如,如果CTLx.SRC_TR_WIDTH = 32
,那么源单次传输大小为4字节。
2. 源突发传输大小(Source burst transaction size in bytes)
定义:源突发传输大小是指源外设在DMA传输时一次突发(burst)传输的数据量。突发传输可以包含多个单次传输,因此源突发传输大小是源单次传输大小和源突发大小(
CTLx.SRC_MSIZE
)的乘积。CTLx.SRC_MSIZE
表示源突发的大小,单位是源单次传输的数量(即一次突发中包含的源单次传输的个数)。公式:
$$
\text { src_burst_size_bytes }=\text { CTLx.SRC_MSIZE } \times \text { src_single_size_bytes }
$$
例如,如果CTLx.SRC_MSIZE = 4
且src_single_size_bytes = 4
字节,那么源突发传输大小就是16字节。
3. 目标单次传输大小(Destination single transaction size in bytes)
定义:目标单次传输大小指的是DMA写入目标外设时每次写入的数据量。它由目标传输宽度(
CTLx.DST_TR_WIDTH
)决定,CTLx.DST_TR_WIDTH
表示目标传输的宽度,单位是位。与源单次传输大小类似,它需要通过除以8来转换为字节。公式:
$$
\text { dst_single_size_bytes }=\frac{\text { CTLx.DST_TR_WIDTH }}{8}
$$
例如,如果CTLx.DST_TR_WIDTH = 32
,那么目标单次传输大小就是4字节。
4. 目标突发传输大小(Destination burst transaction size in bytes)
- 定义:目标突发传输大小是指DMA写入目标外设时一次突发(burst)传输的数据量。与源突发传输大小类似,目标突发传输大小是目标单次传输大小和目标突发大小(
CTLx.DEST_MSIZE
)的乘积。CTLx.DEST_MSIZE
表示目标突发的大小,单位是目标单次传输的数量。 - 公式:
$$
\text { dst_burst_size_bytes = CTLx.DEST_MSIZE × dst_single_size_bytes }
$$
例如,如果CTLx.DEST_MSIZE = 4
且dst_single_size_bytes = 4
字节,那么目标突发传输大小就是16字节。
5. 块大小(Block size in bytes)
- 块大小定义了DMA一次传输中要处理的数据量,可以根据不同的流控制器角色来计算:
DW_ahb_dmac作为流控制器:
- 定义:当DMA控制器本身作为流控制器时,处理器通过编程DMA控制器的
CTLx.BLOCK_TS
字段来指定每个块中要传输的数据项数(即块大小)。CTLx.SRC_TR_WIDTH
是源传输宽度,表示每个数据项的大小。 - 公式:
$$
\text { blk_size_bytes_dma = CTLx.BLOCK_TS × src_single_size_bytes }
$$
例如,如果CTLx.BLOCK_TS = 100
且src_single_size_bytes = 4
字节,那么块大小为400字节。
源外设作为块流控制器:
- 定义:当源外设作为块流控制器时,块大小是源突发传输和源单次传输的数量加权平均。它由源外设进行控制。
- 公式:
$$
\text { blk_size_bytes_src }=\text { (Number of source burst transactions in block × src_burst_size_bytes) + (Number of source single transactions in block } \times \text { src_single_size_bytes) }
$$
这表示块大小是由源突发事务和源单次事务的数量来决定的。
目标外设作为块流控制器:
- 定义:当目标外设作为块流控制器时,块大小是目标突发传输和目标单次传输的数量加权平均。它由目标外设进行控制。
- 公式:
$$
\text { blk_size_bytes_dst }=\text { (Number of destination burst transactions in block } \times \text { dst_burst_size_bytes })+ \text { (Number of destination single transactions in block } \times \text { dst_single_size_bytes) }
$$
这表示块大小由目标突发事务和目标单次事务的数量来决定。
总结:
- block size的大小要大于msize
内存外设
1. 内存外设与DMA传输的特点
- 没有握手接口(No handshaking interface):内存外设通常不具有像外设那样的握手接口(handshaking interface)。这意味着,内存外设无法直接告知DMA控制器何时准备好进行数据传输。因此,当DMA通道被启用后,数据传输会立即开始,而无需等待任何事务请求或信号。
- DMA控制器为流控制器(DMA controller as flow controller):在内存外设的情况下,DMA控制器总是充当流控制器。流控制器负责管理数据传输的调度,控制每个块的传输,而不依赖外设来控制流量。因此,对于内存外设,DMA控制器直接控制数据的读取和写入过程,不需要外设插入等待状态。
2. 等待状态(Wait States)
- 如果内存外设没有握手接口,DMA控制器将尝试执行AHB总线传输。此时,内存外设可能会因为无法接受这些传输而插入等待状态。具体来说,如果外设不能立即处理DMA请求,它会通过de-asserting hready(即使得
hready
信号不为高)来插入等待状态,表示当前没有准备好处理数据。DMA控制器将在等待状态结束后继续传输。 - 推荐不超过16个等待状态:插入过多的等待状态可能会影响总线的效率。文中建议不要让外设插入超过16个等待状态,因为过多的等待状态会导致DMA传输过程的延迟,降低数据传输的效率。
3. 握手接口的优势
- 使用握手接口(Handshaking interface):如果外设有握手接口,它可以向DMA控制器发送信号,表明它已经准备好发送或接收数据。通过这种方式,DMA控制器可以在没有等待状态的情况下与外设进行数据传输。
- 避免等待状态:通过握手接口,外设可以主动告知DMA控制器其准备情况,减少了等待状态的数量,提高了数据传输效率。
4. SRC_MSIZE
和DEST_MSIZE
在内存外设中的使用限制
- 不适用于内存外设:
SRC_MSIZE
和DEST_MSIZE
是DMA控制器配置的参数,用于定义突发传输的大小,这对于具有握手接口的外设是有意义的,因为外设可能需要规定一个突发传输的大小。然而,这两个参数不适用于内存外设。 - 内存外设不需要这两个参数:因为内存一般没有像外设那样有限的资源(比如FIFO缓存),所以内存可以直接进行DMA传输,且不需要设置突发大小。DMA控制器会根据可用的FIFO空间或块传输的要求来决定传输长度。
5. 内存外设的传输规则
- 从内存到外设的突发传输长度:从内存到外设的突发传输长度取决于通道FIFO中的可用数据项数量和块传输所需的数据项数量(两者取最小值)。
- 这意味着如果FIFO中有足够的空间,DMA将使用更长的突发传输;如果FIFO空间不足,DMA将传输较小的数据块,直到完成块传输。
- 从外设到内存的突发传输长度:从外设到内存的突发传输长度规则相似,也是取FIFO中的可用空间和块传输要求的最小值。
早期终止的突发事务
1. 早期终止的突发事务
- 什么是早期终止的突发事务?
- 突发事务通常指一次连续地传输多个数据项,而不是单独的传输。但如果DMA控制器发现剩余的数据量小于请求的突发大小(即
src_burst_size_bytes
或dst_burst_size_bytes
),那么它会提前终止这个突发事务,仅传输足够的数据以完成当前的数据块传输。 - 这种早期终止的突发事务仅在DMA控制器与外设(而不是内存)之间进行时发生,且外设不是“流控制器”时(也就是说DMA控制器负责数据的传输控制)。
- 突发事务通常指一次连续地传输多个数据项,而不是单独的传输。但如果DMA控制器发现剩余的数据量小于请求的突发大小(即
2. 何时会发生早期终止?
- 早期终止发生的条件是:
- 外设不是流控制器(也就是DMA控制器在控制传输)。
- 数据源或数据目的地外设处于单事务区(Single Transaction Region)。
- 在单事务区,DMA控制器本应进行单独的事务,但如果触发了突发请求,而此时剩余的数据量不足以完成整个突发传输,DMA控制器会提前终止突发事务。
3. 早期终止的突发事务行为
- 当DMA控制器在单事务区检测到突发请求时,但剩余的数据不足以完成整个突发,它将:
- 只传输完成当前数据块所需的数据量,而不会传输整个突发大小(
src_burst_size_bytes
或dst_burst_size_bytes
)。 - 这意味着DMA控制器只会传输剩余的数据,以完成当前块的传输,而不会传输多余的数据。
- 只传输完成当前数据块所需的数据量,而不会传输整个突发大小(
4. DMAH_INCR_BURSTS 配置位的影响
发生这种早期终止行为时,DMA控制器的配置位 DMAH_INCR_BURSTS
会影响DMA如何处理突发请求。
- 当
DMAH_INCR_BURSTS = 0
时:- 如果DMA控制器在单事务区检测到突发请求,只会发出单事务传输,即使是突发请求,也会分成单独的事务进行传输,而不会发起突发事务。
- 当
DMAH_INCR_BURSTS = 1
时:- 如果
DMAH_INCR_BURSTS
被设置为1
,DMA控制器会尝试发出递增突发(INCR类型的突发)。但这时,突发的长度会被限制为仅足够完成当前数据块的传输,而不会传输全部的src_burst_size_bytes
或dst_burst_size_bytes
。这意味着,突发的长度是未定义的:它会根据当前块的需要来确定长度,而不是按照预定的突发大小。
- 如果
5. 早期终止突发事务的总结
早期终止的突发事务发生在DMA控制器尝试执行一个突发传输,但由于剩余的数据不足以填充整个突发长度,它只会传输足够完成当前块的数据。
DMA控制器在单事务区时会自动调整突发事务的长度,确保传输的数据量足够完成数据块的传输。
DMAH_INCR_BURSTS
配置位的设置决定了DMA如何处理这种情况:如果
DMAH_INCR_BURSTS = 0
,则DMA控制器会发出单事务传输,而不是突发事务。如果
DMAH_INCR_BURSTS = 1
,DMA控制器会发出递增突发,但它的长度会根据需要传输的数据量调整,而不是传输整个预定的突发大小。
单事务区
1. 什么是单事务区(Single Transaction Region)?
- 单事务区 是指在某些情况下,当数据块的大小不足以完全通过突发事务来传输时,DMA控制器会使用单事务(Single Transaction)来完成剩余的数据传输。
- 在 DMA 数据传输过程中,如果剩余的数据量小于一个完整的突发事务所能传输的大小(即小于
src_burst_size_bytes
或dst_burst_size_bytes
),DMA控制器就会切换到单事务模式,使用单个事务来完成剩余的数据传输。
2. 为什么会进入单事务区?
- 原因:通常,数据块的大小不能完全被突发事务的长度整除,导致剩余的数据量小于一个完整的突发长度。例如,如果数据块大小为 100 字节,而突发长度为 64 字节,最后剩余的数据是 36 字节,不能通过一个 64 字节的突发事务完成。此时,DMA控制器将切换到单事务模式,只传输剩余的 36 字节数据。
3. DMA控制器和外设的交互
- 外设的单事务标志:外设通过设置单事务标志来通知 DMA 控制器,表示它准备好接收或发送一个完整的单事务数据。这是DMA控制器判断是否可以进入单事务区的一个信号。
4. 单事务区的定义和使用
- 单事务区仅在 DMA 控制器使用单事务来完成数据块传输时有效。换句话说,单事务区是在数据块传输过程中,由于剩余数据不足以进行完整的突发传输时,DMA控制器切换到的模式。
- 单事务区的外部限制:
- 在单事务区内,只使用单个数据事务(而非突发事务)。
- 在单事务区外,DMA控制器仅使用突发事务来传输数据。
5. DMA控制器为流控制器时的行为
- 如果 DMA控制器是流控制器,则只有在源外设传输的数据量不足以完成一个完整的突发传输时,才会进入单事务区。
- 源外设:如果剩余数据量小于
src_burst_size_bytes
(即源块传输所需的突发数据量),则源外设进入单事务区。如果数据块的大小能够整除突发事务大小(例如,blk_size_bytes / src_burst_size_bytes
是整数),那么源外设将一直使用突发事务,而不会进入单事务区。例如:- 假设
blk_size_bytes = 256
字节,src_burst_size_bytes = 64
字节,那么256 / 64 = 4
,意味着整个数据块可以通过 4 次 64 字节的突发事务完成,这样源外设永远不会进入单事务区。
- 假设
- 目的地外设:目的地外设则会在剩余数据量小于
dst_burst_size_bytes
时进入单事务区。与源外设类似,如果blk_size_bytes / dst_burst_size_bytes
是整数,那么目的地外设也将一直使用突发事务,不会进入单事务区。
6. DMA控制器不是流控制器时的行为
- 如果源或目的地外设是流控制器(即外设负责数据传输控制),则当外设发送信号指示最后一次事务时(例如,表示数据块的最后一部分需要传输时),DMA控制器会进入单事务区,传输剩余的数据。
- 这时,进入单事务区的条件是外设发出“最后事务”的信号,并且剩余的数据量少于突发事务的大小(即小于
src_burst_size_bytes
或dst_burst_size_bytes
)。
硬件握手接口(外设不是流控制器)
1. dma_ack(输出)
- 描述:
dma_ack
是来自DMA控制器到外设的确认信号。它在当前事务(单事务或突发事务)的数据传输完成后被激活。 - 工作原理:
- 对于 单事务:
dma_ack
在数据传输结束后保持激活,直到外设解除激活dma_single
信号,然后dma_ack
会在一个时钟周期后被取消。 - 对于 突发事务:
dma_ack
在数据传输结束后保持激活,直到外设解除激活dma_req
信号,然后dma_ack
会在一个时钟周期后被取消。
- 对于 单事务:
2. dma_finish(输出)
- 描述:
dma_finish
是由DMA控制器发出的信号,用于指示数据块的传输完成。它与dma_ack
信号具有相同的时序。 - 工作原理:
- 如果最后的事务是一个 突发事务,
dma_finish
信号会与外设的dma_req
信号形成一个握手。 - 如果最后的事务是一个 单事务,
dma_finish
信号会与外设的dma_single
信号形成一个握手。 - 在一些特殊情况下,如源外设和目的地外设角色不同时,
dma_finish
信号与dma_req
信号的时序定义可能会有所不同。
- 如果最后的事务是一个 突发事务,
3. dma_last(输入)
- 描述:
dma_last
是一个输入信号,通常由外设提供,但在某些情况下被DMA控制器忽略。由于在DMA传输过程中,外设可能不是流控制器,因此DMA控制器不会采样这个信号。 - 工作原理:当外设不是流控制器时,
dma_last
信号被忽略,DMA控制器并不依赖于该信号来判断传输是否完成。
4. dma_req(输入)
- 描述:
dma_req
是外设请求DMA突发事务的信号。无论dma_single
信号的状态如何,DMA控制器始终将dma_req
视为突发事务请求。 - 工作原理:
- 这是一个电平敏感信号,也就是说外设一旦激活
dma_req
,它必须保持激活状态,直到DMA控制器发出dma_ack
信号。 - 当DMA控制器发出
dma_ack
信号表示突发事务完成时,外设应该解除激活dma_req
信号。之后,DMA控制器才会解除激活dma_ack
信号。 - 如果在 单事务区(Single Transaction Region)内检测到
dma_req
激活,DMA控制器会执行一个提前终止的突发事务(Early-Terminated Burst Transaction)。这意味着DMA控制器会在剩余数据量较少时提前终止当前的突发事务。
- 这是一个电平敏感信号,也就是说外设一旦激活
5. dma_single(输入)
- 描述:
dma_single
是一个状态信号,由外设提供,表示外设是否准备好进行单次数据传输。 - 工作原理:
- 对于 目的地外设:当
dma_single
被激活时,表示目的地外设能够接收至少一个数据项;如果不能接收,则清除该信号。 - 对于 源外设:当
dma_single
被激活时,表示源外设能够传输至少一个数据项;如果不能传输,则清除该信号。 - 一旦
dma_single
信号被激活,它必须保持激活状态,直到DMA控制器发出dma_ack
信号,之后外设才能解除激活dma_single
信号。 dma_single
信号只在 单事务区 中被采样。在该区外,DMA控制器会使用突发事务,因此dma_single
信号会被忽略。
- 对于 目的地外设:当
本文链接: https://talent-tudou.github.io/2024/11/29/DWC/AHB-DMAC/
版权声明: 本作品采用 CC BY-NC-SA 4.0 进行许可。转载请注明出处!