在ST公司后期推出的STM32系列的GPDMA模块中,BNDT与FIFOL是两个非常重要的状态量。当下,我们容易将BNDT = 0 直接理解为DMA传输完成。这一判断在带FIFO的GPDMA应用场景下并不总是成立。
对于FIFO-based GPDMA,DMA传输实际上包含两个前后衔接的阶段:数据从source 侧进入FIFO;数据再由FIFO写入destination 侧。因此,即使调试时已经观察到:BNDT = 0;通道状态并非 IDLE;FIFOL仍在变化;这往往只能说明源侧搬运可能已经结束,但并不能据此断定整次DMA传输完成。
本文结合STM32U5/H5 GPDMA手册定义与实际测试结果,对BNDT和FIFOL的含义及其在DMA运行过程中的分工做一次梳理分享,以供参考。
一、BNDT与FIFOL的手册定义
1. BNDT
BNDT位于寄存器GPDMA_CxBR1.BNDT[15:0],手册定义为:block number of data bytes to transfer from the source.从定义可知,BNDT表示当前block中,还有多少字节需要从source侧搬运,本质上是一个面向source侧的剩余数据的字节计数器。
2. FIFOL
FIFOL位于寄存器GPDMA_CxSR.FIFOL[7:0],手册定义为:Number of available write beats in the FIFO, in units of the programmed destination data width.
这一定义可以拆解为三点:1、FIFOL不是简单的“剩余字节数”;2、它描述的是FIFO中的数据还可以支持多少次向destination侧的写操作;3、其计量单位是 destination data width。
简单点说,它表示当前FIFO中的数据还需要多少个写beat才能被destination侧完全消费。根据上面定义不能看出,BNDT与FIFOL关注的是DMA传输链路中的不同位置:BNDT 关注source -> FIFO;FIFOL 关注FIFO -> destination。
二、测试验证
1. 实验背景
为便于观察BNDT与FIFOL的行为,这里设计了两组GPDMA对照实验。共同测试条件如下:
平台:STM32U5(GPDMA1);
DMA request源:TIM1_CH1比较事件;
DMA方向:Memory to Peripheral;
Source:SRAM;Destination:固定寄存器地址(UART1 TDR);
总传输长度:8字节;通过定时器事件分次触发DMA;
期间多次采集DMA通道状态;
使用通道:GPDMA1-S2,带2-word FIFO;下图是基于本实验测试的DMA传输流程示意:
2. 两组测试的DMA配置
第一组Source width = ByteDestination width = ByteData handling =无Destination burst length = 1
第二组Source width = WordDestination width = ByteData handling = Enable + UnpackDestination burst length = 1
相较第一组,第二组主要变化有两点:source width由Byte改为Word;启用Unpack,以适配源端宽度大于目的端宽度的情况。
3. 观察方式
本次实验计划传输8字节数据,由定时器比较事件触发DMA。实际测试中,仅触发4次后即停止定时器,不再触发DMA。共记录6组DMA状态快照,分别对应:DMA使能前;DMA使能后但尚未被触发时;被触发1次至4次后的四个状态;重点关注的状态量为BNDT与FIFOL。
三、实验现象
尽管两组实验在source width与data handling配置上有所不同,但BNDT与FIFOL的变化规律完全一致。见下表【看图说话,直观明了】:
1. BNDT的变化
在DMA初始化完成并使能、但尚未触发时,BNDT = 8。在第一次触发之后,BNDT立即变为 0。这说明:当前block中需要从source端取出的8字节数据,已经在第一次触发后全部进入FIFO。同时可以观察到,SAR也同步前进了8字节。
2. FIFOL的变化
与BNDT不同,FIFOL在第一次触发后并未归零,而是随着后续触发不断发生,FIFO中的数据持续写往目标侧(UART TDR)。与此同时,BNDT始终保持为0;SAR不再继续变化。这表明:source侧的数据搬运虽然已经完成,但DMA通道仍在继续工作,因为FIFO中的数据尚未被destination侧完全消费。
四、如何理解BNDT = 0
结合手册定义与实验结果,可以得到一个结论:BNDT = 0只表示source侧的block数据已经全部被DMA取走,并不必然表示整次DMA传输已经结束。
也就是说,在带FIFO的GPDMA中,DMA传输完成包含两个阶段的完成:source -> FIFO;完成可由BNDT反映;FIFO -> destination;完成需要结合FIFOL甚至其它状态标志综合判断
;因此,若仅凭BNDT = 0就认定传输结束,在FIFO-based GPDMA场景下可能会得出错误结论。
五、小结
BNDT回答的是source侧还剩多少block数据未被DMA取走。它反映的是源端到FIFO这一段的数据推进状态。FIFOL回答的是FIFO中还剩多少数据未被destination侧消费。它反映的是FIFO到destination这一段的数据推进状态。
当然,它也从另一角度体现了FIFO的占用情况。最后顺便提醒下,对于不带FIFO的DMA模块,BNDT = 0往往就意味着本次传输已经结束。但对于FIFO-based GPDMA,BNDT = 0更准确地说只是一个源侧搬运完成的标志,而不肯定标志整次DMA传输的完成。
196