本文针对 STM32H5 GPDMA 中几个与 DMA 请求有关的寄存器控制位及其相互关系,做些力所能及的解读,供阅读参考。它们分别是下面几个寄存器控制位【或位段】:SWREQ、REQSEL、DREQ、BREQ、PFREQ。
一、 burst 和 block
在解释各类DMA request术语及概念之前,我们有必要对GPDMA中的burst和block先作个简单解读。
1.1 burst:基本传输单位
一个 burst 由多个 beat 组成,一个 beat 对应一次数据传输。其中,一个 burst 传输所包含的beat个数称之为burst长度。通常,GPDMA以BURST为基本传输单位。beat数据宽度由以下字段决定:源宽度:SDW_LOG2目的宽度:DDW_LOG2可以是:1 byte、2 bytes、4 bytes。burst 长度相关字段:源burst 长度:SBL_1 + 1目的burst 长度:DBL_1 + 1burst 主要描述的是:一次性从 source 到 FIFO 拉取的一组数据;一次性从 FIFO 到 destination 推送的一组数据;地址在 burst 结束后如何更新;仲裁与总线访问的节奏;
1.2 block:整块传输任务
一个 block 是当前 DMA传输项中要完成的一整块数据搬运。例如:每个源burst传输的数据长度是16 bytes,且BNDT = 64,则该 block 通常需要 4 个 burst 传输才完成。【注:BNDT是当前 block 要从源端搬运的总字节数。】block 主要描述的是:这一块任务何时算完成;何时产生complete / half-transfer 事件;何时切换到下一LLI;
1.3 block 和 burst 的关系
beat:对应一次数据传输动作。
burst:对应一组数据传输操作,由1次或多次连贯beat动作组成。
block:对应多组burst传输操作。
通常DMA 内部会尽量按 burst 节奏运行,最终以 block 为单位完成目标。
关于 beat、burst、block,不妨打个通俗比方来直观理解。
某人把一卡车停在一堆板砖旁,希望有人把 2000块砖搬到车上。如果把 1块砖对应 1 个字节,那么这 2000 块砖就相当于 DMA 传输里的一个 block,也就是这一整块要完成的数据总量。搬砖我来。我不是一块一块零散地搬,而是每次动手就往车上搬 20块砖。【完成这20块的搬砖过程中不接电话、不刷手机、不找水喝、不歇息。。。】
不过,虽然每次动手的目标是20 块砖,我实际操作并不能“一下子”完成,而是:分4次,每次搬5块。
简单类比下:这里每搬20块砖就对应一个BURST操作,该操作又细分为4次,即4 个beat,burst长度为4 ,每个beat 对应5块砖的搬运。完成 2000 块砖的搬运,就对应完成一个 block 传输。
二、几个跟DMA请求有关的寄存器控制位
2.1 SWREQ
所属寄存器是GPDMA_CxTR2.SWREQ。SWREQ 用来决定这次传输是软件直接触发,还是由外设请求驱动。
SWREQ = 1 表示该传输由软件直接触发,不依赖外设 request 信号,也不涉及外设握手机制,常见于 memory-to-memory。软件说“现在开始搬”,DMA 就按配置执行。
此时 REQSEL、DREQ、BREQ、PFREQ 都被忽略。SWREQ = 0 表示该传输由外设硬件 request 驱动,同时需要结合 REQSEL、DREQ、BREQ、PFREQ 的配置来实现传输。简言之,SWREQ 决定这次传输是“软件直接触发”,还是“由外设请求驱动”。
2.2 REQSEL
所属寄存器:GPDMA_CxTR2.REQSEL。仅当 SWREQ = 0 时有效。当 DMA 由外设硬件 request 驱动时,REQSEL 用来选择当前 DMA 通道要连接并响应的是哪一个外设 request 信号。
也就是说,它回答的是:到底是哪一个外设 request 被选来驱动这条 DMA 传输。例如,它可以选择 uart_rx_dma、spi_tx_dma、i3c1_rx_dma 等。
2.3 DREQ
所属寄存器:GPDMA_CxTR2.DREQ,仅当 SWREQ = 0 时有效。DREQ 用来决定这个外设 request 来自源端还是目的端。DREQ = 0 表示request 来自源外设一侧,典型场景就是常见的peripheral-to-memory。
DREQ = 1表示request 来自目的外设一侧,典型场景就是常见的memory-to-peripheral。简言之,DREQ 决定是哪一端的外设发 request。
2.4 BREQ
所属寄存器:GPDMA_CxTR2.BREQ。仅当 SWREQ = 0 时有效。它不是在定义 burst 或 block,而是在决定外设发来的request,应该按 burst 粒度理解,还是按block 粒度理解。
BREQ = 0 表示这是 burst 级 request,即外设每次发来的 request,对应推进一个 burst 级传输。BREQ = 1 表示这是 block 级 request,外设每次发来 request,对应推进一整块,也就是一个 block 级传输。
何时必须用 BREQ = 1?
STM32H5 手册明确指出,某些请求必须配置为 block request,例如:lptim1_ue_dma 、lptim2_ue_dma、lptim3_ue_dma等。这些场景下若 BREQ 配错,硬件行为可能不符合预期。简言之,BREQ 决定外设 request 管的是“一小段 burst”,还是“一整块 block”的传输。
2.5 PFREQ
所属寄存器:GPDMA_CxTR2.PFREQ。仅当 SWREQ = 0 时有效,且不是所有通道都支持。
PFREQ 用来决定当前block 是否必须等 BNDT 传完才结束,还是允许外设提前通知结束。
PFREQ = 0 表示普通模式,即非外设流控模式,此时DMA 按自己的配置规则,尤其计数规则实现搬运。通常 BNDT= 0 时,block传输才告完成。
PFREQ = 1 表示进入 peripheral flow-control mode。
此时,当前block 不一定非要等 BNDT = 0,外设可以提前通知“这块传输已经结束了”。
简言之,PFREQ 决定当前 block 是否允许由外设提前结束传输。至于early termination,它是PFREQ = 1 模式下的具体行为。
发生early termination 时,当前block 被视为完成,BNDT 可能不为0。手册给出的支持early termination 的请求包括:i3c1_rx_dmai3c2_rx_dma(部分器件限制)基于上面内容,我做了一张表,用于对比理解。
三、几个典型场景时请求配置
3.1 memory-to-memory
配置特点:SWREQ = 1其余DREQ、BREQ 、PFREQ 、REQSEL 均被忽略。软件直接发起DMA搬运请求,从而实施数据从源端到目的端的搬运,不依赖外设request。
3.2 peripheral-to-memory
配置特点:SWREQ = 0REQSEL = uart_rx_dma;例如 UART RXDREQ = 0BREQ = 0(通常)PFREQ = 0源外设发request,DMA 根据请求将源端数据搬运到目的端。
3.3 memory-to-peripheral
配置特点:SWREQ = 0REQSEL = uart_tx_dma / spi_tx_dma ;例如 UART TX / SPI TXDREQ = 1BREQ =0(通常)PFREQ = 0目的外设发 request,DMA 根据请求将源端数据搬运至目的端。
3.4 peripheral flow-control + early termination
配置特点:SWREQ = 0REQSEL = i3c1_rx_dma,例如 I3C RXDREQ = 0PFREQ = 1相关通道、相关 DMA 请求都必须支持 PFREQ = 1 的外设流控模式。
该传输仍由外设硬件 request 驱动;当前 block 在 BNDT 未递减到 0 的情况下,外设可以提前通知该 block 结束。不过,该模式仅支持 peripheral-to-memory。
四、容易误解的几点
4.1 SWREQ = 1 时还需要关心 DREQ/BREQ/PFREQ 吗?
不需要。这时根本不走外设 request 机制。
4.2 BREQ = 1 是否等于外设流控?
不等于。BREQ决定一次外设 request 是按 burst 级还是按 block 级来理解和响应,而PFREQ 才控制当前 block 是否允许外设提前结束。
4.3 PFREQ 是否会改变 burst 大小?
不会。PFREQ 只影响 block 的结束条件。
4.4 STM32H5 GPDMA 支持 memory-to-peripheral 吗?
支持。但限于普通模式,即非外设流控模式。 PFREQ = 1 时,仅支持 peripheral-to-memory,不支持 memory-to-peripheral。
五、小结
SWREQ:决定是软件还是硬件来触发传输;
DREQ:决定哪一端外设发 request;
REQSEL:决定选哪一路外设 request;
BREQ:决定一次外设 request 是按 burst 级还是 block 级理解 和响应;
PFREQ:决定这一整块能不能让外设提前结束;
个人以为,了解上面DMA 相关术语和基本概念还是有必要的,只有把 beat、burst、block 这些传输层级,以及 SWREQ、DREQ、BREQ、PFREQ 这类DMA请求术语真正理解清楚后,我们才可能在 STM32 DMA 应用中,真正明白一条数据流是谁在驱动、按多大粒度推进、以什么节奏传输、在什么条件下结束。
OK,今天的话题就聊到这里。
134