一、题外话
本文主要是使用NOR flash作为从机设备,以此验证SPI主机性能,不限与驱动flash器件。
对于真正有实际nor flash器件驱动的需求,先楫提供了更为方便性能更优的外设-XPI外设。不但支持多种外部存储器,而且这次1/2/4/8数据模式,重点是只需要调用ROM API接口,无需自己写驱动!
本文主要介绍SPI外设,XPI外设不在本文讨论范围。
二、目的
在系列中的前三篇中,分别介绍了SPI外设的收发性能最大化实现方案以及谈谈先楫hpm_sdk的组件serial_nor--SFDP定义。sfdp可以帮助我们得到flash器件的相关器件,比如擦除、读写指令。由于先楫HPM6000系列一次收发传输是512字节(据说后续的新系列不会限制在512字节),对于flash器件来说,从读flash上来看,可以读取超过512字节的地址数据长度,从写flash来看,最多一次写一页(256字节或者512字节)。所以从实际应用出发来看,SPI传输不会限制在512字节内。
要使用超过512字节的传输量,单从性能角度出发,无论是1线还是4线传输模式,肯定是DMA方式效果最佳。这也是本文的讨论重点和目的。
三、理论读写性能
在验证SPI主机性能之前,我们需要知道从机器件的性能。比如写一页256字节和擦除一个sector或者block的性能。
本文使用的器件还是华邦W25Q64JV,从页编程来看,一次页编程经典是0.3ms,擦除4K sector需要45ms经典值,假设从单纯编程上看,写速度大概是625KB/S经典值.
从读来看,主要看flash支持的SPI频率。从手册看,读取03H普通读取指令以外的指令(比如EBh 四线读取)可以到133M,那么理论上四线SPI可以到66.5MB/S最大值,单线SPI主要只能对接03H指令,那么最大50M频率,最大可以6.28MB/S
本文限制于杜邦线连接FLASH,所以四线QSPI四线速度限制在50M,当然如果接在PCB上,那么SPI外设的80M想必也没什么问题。
所以,在四线QSPI频率50M下,对本文所用的flash器件,理论编程速度应该是625KB/s,而读取速度理论应该要25MB/S.
三、验证理论读写性能。
(一)先楫HPM6000的DMA概述
先楫的HPM6000系列的DMA包括两个控制器,一个XDMA,64位总线宽度,连接在AXI总线上;一个HDMA,32位总线宽度,连接在AHB外设总线上。DMA请求路由器一共16个通道,两个控制各划分为8个。
DMA支持非链式传输,也支持链式传输。链式传输可以在CPU不干预的情况下,连续完成多个不同的配置传输任务。也就是说,每个链存放着配置传输的描述符,但每个链传输完毕,只要下一个链地址是合法的,那就接下去传输。但需要注意的是,描述符最多只能4K内存。而每个描述符的格式占用32字节。
本文就以非链式DMA和链式DMA来进行说明传输性能的优化。
(二)SPI启动传输流程
在配置好SPI的相关初始化之后,比如引脚初始化、SPI模式、时钟分配等。之后就是传输过程。
传输过程需要以下三步:
1、配置TRANSCTRL寄存器,该寄存器主要是配置地址段和命令段使能和禁能、数据段格式(1/2/4线)、传输模式(比如同时读写、只读、填充dummy后读等)、写入长度、读取长度等
2、配置CMD寄存器,该寄存器在SPI作为主机下,无论是否禁止命令,都需要为之赋值,因为一旦赋值就是标志开始传输,根据需要传输的写入或者读取长度发出相对的SCLK时钟数量。
3、之后在DATA寄存器读取或者写入对应的数据,如果是轮询读写FIFO方式,那么就是阻塞收发FIFO,如果是DMA方式那么则需要配置DMA的源地址和设备地址等参数。
对于这些传输过程,hpm_sdk已经有对应的API接口:
对于轮询方式,可以见该文章《先楫hpm6000的SPI外设使用四线模式操作读写华邦flash》,本文不再做相关阐述
对于DMA方式,SDK提供的API接口是spi_setup_dma_transfer,之后开发者需要自己配置好DMA参数,然后再调用dma_setup_channel这个API即可开启传输。无论是发送还是接受,均可使用该接口。详细参考也可以看hpm_sdk中的sample/drivers/spi文件夹下的DMA例子。
(三)非链式DMA传输
由于flash在读写操作API上,从用户的角度看,接口传参只要读写的buffer地址,以及传输的长度即可。内部逻辑并不做任何关心,在这里本文也封装了两个接口。分别是program和read APIS。
从program API看,内部需要对其传入的编程长度进行拆分,对应也对编程地址和buffer地址进行对应的拆分长度偏移,再者根据flash的地址模式(24位还是32位)通过SFDP获取到的对应的Program指令。加上还需要配置DMA参数,所以这部分也需要一定的指令执行时间损耗。在循环DMA写入页的时候还需要等待页编程完成,也就是需要0.4ms的等待时间。
从read API看,由于hpm6000的最大收发长度为512字节,内部也需要对齐进行读取长度的拆分,然后也需要根据flash的地址模式(24位还是32位)通过SFDP获取到的对应的Program指令。加上还需要配置DMA参数,也需要一定的指令时间,但在读取的过程中,不需要等待flash busy状态,发完512之后继续再发下一帧512字节,以此循环。
为了最大减少指令的执行时间,对于HPM的DMA来说,每次传输完之后需要重新配置传输长度以及传输的源地址和设备地址,再重新启动DMA,这些单独的配置同样HPM也有提供。可以以此做个独立的API接口。
为了验证大数据量下的DMA方式读写flash收发传输性能,本文以SPI频率50M, 15K数据进行读写flash,开启最大优化O3。另外加个IO来测试上述API的执行时间。
以计时差计算15K传输的速度,如下所示。从上述自身flash器件的编程性能630KB/S.在这里是明显达到编程性能的。但是从读速度来看,理论25MB/S,但实际22MB/S。
通过逻辑分析仪抓取SCLK、CS、还有IO测试脚看到:
在进入读取API的时候,并不是立马就执行发送,而是有个配置逻辑处理时间,以及每包的DMA配置时间。
1、测试读取API,接收15K数据,总的耗时是692.742us,也就是22.172MB/S,与打印的一致。
2、总的耗时,主要费在入口拆包以及传输配置耗时11.666us,还有每个512字节包DMA配置传输的总耗时56.5us.两者费时68.166us
3、那么实际传输数据的就692.742 - 68.166 = 68.166us.也就是15360/624.576 = 24.6MB/S. 这段还包括了地址和指令的传输,这样看来,DMA实际传输还是能明显达到理论的25MB/S
(四)链式DMA传输
在DMA非链式传输当中,主要费时还是在于每包512字节传输后再次配置DMA的耗时,虽然每包耗时1.8us左右,但总包数累加,还是有一定的时间损耗。那么有没有办法消除该每包之间的间隔呢。由上述的说明可知道,链式DMA只要在传输之前把SPI的传输流程放在DMA描述符当中,那么这样就不需要CPU去干预,而让DMA自己去执行。这个思路也一同验证下。
1、SPI一次传输需要配置TRANSCTRL、CMD、DATABUF DMA配置,所以每组SPI传输链需要三个DMA描述符,每个描述符占用32字节,DMA描述符边界长度是4K,那么非链式传输最大可以传输4096/(32 * 3) * 512= 21845字节,也就是21K传输长度。描述符的写入同样也有对应的API接口-> dma_config_linked_descriptor
2、那么启用第一次DMA传输的时候,只需要把linked_ptr地址指向写好的描述符空间首地址即可。
再次验证下,可以看到链式DMA反而比非链式DMA提升不大,而且还慢了些。
一样通过逻辑分析仪测试SCLK ,CS,测试IO上看。
为什么链式DMA传输会比非链式传输慢了点,从分析仪可以看到,有以下几个原因:
1、配置DMA描述符等工作执行耗时较久,耗时49.088us。这由于数据地址和数据长度的不确定,描述符在接口内部填充是无可避免的。
2、链与链之间会有间隔时间,也就是图中的1.266us,这是执行CTRL和CMD寄存器以及写CMD确定发送的延时间隔,这时间合理,也是无可避免。
3、由于SPI一次传输,DMA描述符里面有两个寄存器的DMA传输,但DMA传输对于大数据量传输能减少时间,但对于寄存器的赋值,hpm6000高达几百兆的主频,往往几个指令就能搞定的事情,所以与非链式DMA上每包传输的配置DMA间隔也跟链式DMA链间隔时间差不多,设置CPU的能够更快。
4、那么实际传输数据的就613us(650 - 1.26 * 30).也就是15360/650 = 25.03MB/S. 这段还包括了地址和指令的传输,这样看来,DMA实际传输也是能明显达到理论的25MB/S,甚至比非链式DMA快。
四、总结
1、先楫HPM6000的SPI外设由于传输长度限制512字节的原因,在大数据量传输中,需要进行分包非链式DMA传输,或者使用链式DMA传输,在指令优化下,也同样能达到理想速度。
2、对于SPI外设来说,链式DMA传输,需要一部分执行时间用来填充DMA描述符,但填充完之后的DMA数据传输不需要CPU干预,这比分包非链式DMA传输更加快些。
3、非链式DMA,每包需要重新配置DMA,这会带来每包的间隔时间,这需要开发者自身优化,但由于hpm的主频足够高,一般间隔也不会超过1.28us。
4、链式DMA传输,如果传输的是大数据量的数据,那么优势最为明显,但是对于一个寄存器的DMA传输,hpm的主频优势,CPU执行赋值会比DMA更加快。
5、从SPI外设来看,链式DMA由于每组SPI传输需要传输两个寄存器值,效果上没有比分包非链式DMA效果明显,从易用性来看,优先考虑分包非链式DMA传输方案。
6、hpm的SPI外设主机功能,至此结束。