|
AT-START-F437这块板子板载了一块16MB的QSPI nor flash,接入AT32F437的QSPI控制器。nor flash型号EN25QH128,它和AT32F437的QSPI主控都支持SPI、QIO、DIO、DOUT以及QPI等模式。SPI、DIO、DOUT等因为少用了数据线,所以想都不用想性能肯定不如QIO以及QPI,所以笔者只关心QIO以及QPI性能差别能有多少。同时因为AT32F437的QSPI有DMA加持,那DMA又会影响性能吗?最终决定测试三种case:QIO no DMA、QIO DMA、QPI DMA的读、擦除、写的性能。
注:笔者理解中的QPI和QIO最大区别就是cmd阶段是否也用上4根数据线。
巧合的是雅特力的Firmware Library的示例中就有上述三种待测case的支持代码,分别是 - project/at_start_f437/examples/qspi/command_port_using_polling/
- project/at_start_f437/examples/qspi/command_port_using_dma
- project/at_start_f437/examples/qspi/command_port_using_dma_qpi_mode/
笔者直接利用这三个目录中的qspi_cmd_en25qh128a.c文件,但没用它们的测试用例,而是以nr_micro_shell和FreeRTOS为大环境写了功能测试和性能测量代码,并以nr_micro_shell的命令导出: - static void sf_cmd_init(void)
- {
- /* qspi config */
- qspi_config();
- /* switch to cmd port */
- qspi_xip_enable(QSPI1, FALSE);
- /* set sclk */
- qspi_clk_division_set(QSPI1, QSPI_CLK_DIV_4);
- /* set sck idle mode 0 */
- qspi_sck_mode_set(QSPI1, QSPI_SCK_MODE_0);
- /* set wip in bit 0 */
- qspi_busy_config(QSPI1, QSPI_BUSY_OFFSET_0);
- /* enable auto ispc */
- qspi_auto_ispc_enable(QSPI1);
- qspi_nor_init();
- }
- static void sf_cmd_demo(void)
- {
- int i;
- uint8_t *rbuf = pvPortMalloc(SECTOR_SIZE);
- uint8_t *wbuf = pvPortMalloc(SECTOR_SIZE);
- if (!rbuf || !wbuf) {
- printf("failed to alloc mem\n");
- vPortFree(rbuf);
- vPortFree(wbuf);
- return;
- }
其中sf demo命令就是先擦除一个sector(4KB),然后都会检验是否全0xff,然后再写入数据,再读回和写入数据比较,一致就说明nor flash基本能用了。而sf bench命令更关注性能方面,分别测量以4KB粒度擦除全部16MB时间、写入以及读取全部16MB所有时间。
注:擦除笔者就关心最小粒度的擦除,因为后面要上文件系统,大粒度的擦除比如block erase以及chip erase没什么意义。
编译烧录后,测试如下。 QIO未用DMA:
QIO DMA:
QPI DMA:
由此看到,QIO与QPI性能数据几乎无差别,性能数据在误差范围内;DMA可以提升读速度大概一倍,DMA可以稍微提升那么一点点写的速度,但幅度很小,估计写的时候瓶颈在nor flash自身吧;DMA反而降低了erase的速度,原因未知,笔者对比了下命令erase在用dma和未用dma情形下是一样的代码和命令,这是预料中的事:erase发个命令过去即可,未有大量数据传输,不会启动dma引擎。
|