0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

SPI NAND驱动性能测试分析与优化

嵌入式USB开发 来源:嵌入式USB开发 作者:嵌入式USB开发 2023-06-21 17:29 次阅读

本文转自公众号,欢迎关注

SPI NAND驱动性能测试分析与优化 (qq.com)

一.前言

https://mp.weixin.qq.com/s/hgogGTFzBDx83sFjDX8lVw一文中我们详细介绍了SPI NAND,也实现了相关的驱动(如果需要驱动源码可以和我联系)。X1和x4模式的擦除,写,读等都测试OK了。现在我们需要进行性能测试和优化。https://mp.weixin.qq.com/s/uLraKF5kWMTHLpTggh2Q4Q一文中也介绍了ONFI。

二. 性能测试

既然是追求性能,所以我们后面就都基于X4模式进行了。

我们分别进行擦除,写,读全盘测试(128MB),然后使用定时器计算操作的时间。

性能测试代码如下:

nand_set_qe(1,3); /* 使能QE模式 */
    /* 擦除 */
    pre = iot_timer_get_time();
    for(uint32_t block=0; block <   dev.blocks_per_lun*dev.luns; block++)
    {
        if(0 != (res = nand_block_erase(block*dev.pages_per_block)))
        {
            iot_printf("block %d erase err

",block,res);
        }
    }
    cur = iot_timer_get_time();
    if(cur <   pre)
    {   
        used = 0xFFFFFFFF - pre + cur;
    }
    else
    {
        used = cur-pre;
    }
    printf("erase time:%duS

",used);

    /* 编程 */
    memset(w_buffer,0xFF,sizeof(w_buffer));
    w_buffer[dev.page_size] = 0xFF;  /* 坏块标志不能擦除 */
    pre = iot_timer_get_time();
    for(uint32_t block=0; block <   dev.blocks_per_lun*dev.luns; block++)
    {
        for(uint32_t page=0; page<  dev.pages_per_block; page++)
        {
            if(0 != (res = nand_write_page_x4(w_buffer, block*dev.pages_per_block+page, 0, dev.page_size+dev.page_spare_size)))
            {
                iot_printf("write page %d err %d

",block*dev.pages_per_block+page,res);
            }
        }
    }
    cur = iot_timer_get_time();
    if(cur <   pre)
    {   
        used = 0xFFFFFFFF - pre + cur;
    }
    else
    {
        used = cur-pre;
    }
    printf("write time:%duS

",(cur-pre));

    /* 读 */
    pre = iot_timer_get_time();
    for(uint32_t block=0; block <   dev.blocks_per_lun*dev.luns; block++)
    {
        for(uint32_t page=0; page<  dev.pages_per_block; page++)
        {
            if(0 != (res = nand_read_page_x4(r_buffer, block*dev.pages_per_block+page, 0, dev.page_size+dev.page_spare_size)))
            {
                iot_printf("write page %d err %d

",block*dev.pages_per_block+page,res);
            }
        }
    }
    cur = iot_timer_get_time();
    if(cur <   pre)
    {   
        used = 0xFFFFFFFF - pre + cur;
    }
    else
    {
        used = cur-pre;
    }
    printf("read time:%duS

",(cur-pre));

测试结果如下

图片

对于写

128MB花了17.40S

所以速度是7.36MB/S

三. 性能分析

我们使用逻辑分析仪抓取总线波形,用于进行性能分析

参考文章https://mp.weixin.qq.com/s/bCdgCNsGPbYjSzjv8VJyRA

我们以编程为例,擦除和读类似。

编程PAGE的代码如下,有三个步骤

即先写数据到CACHE,然后写使能,最后执行CACHE到PAGE的数据编程。

int nand_write_page_x4(uint8_t* buffer, uint32_t pageaddr, uint16_t start, uint16_t len)
{
    int res = 0;
    res = nand_write_to_cache_x4(start, len, buffer);
    if(res == 0)
    {
        res = nand_write_enable();
        if(res == 0)
        {
            res = nand_write_cache_to_page(pageaddr,NAND_PROG_CHECK_RETRY);
            if(res == 0)
            {
                return 0;
            }
            else
            {
                return -3;
            }
        }
        else
        {
            return -2;
        }
    }
    else
    {
        return -1;
    }
}

查看逻辑分析仪抓取到的数据如下,对应如下三个步骤

图片

(1)总线上写数据到NAND的Cache

(2)写使能,并查询写使能OK

(3)执行CACHE到PAGE编程,并查询完成

从以上时间戳可以看到三个步骤分别对应的时间是

第一次开始

19:48:31.513.198.648,PROGRAM LOAD x4(32),0000, ,FF,FF,FF,FF,FF,FF,FF,FF,........,

开始写使能

19:48:31.513.259.134,WRITE ENABLE(06), , , , , , , , , , , ,

开始编程

19:48:31.513.273.890,PROGRAM EXECUTE(10),0040BE, , , , , , , , , , ,

编程完成

19:48:31.513.344.141,GET FEATURE(0F),C0, ,00, , , , , , , ,.,

下一次开始

19:48:31.513.435.474,PROGRAM LOAD x4(32),0000, ,FF,FF,FF,FF,FF,FF,FF,FF,........,

一个PAGE编程的周期

所以一个PAGE的编程时间是下一次开始和前一次开始的时间间隔

435.474-198.648=236.826uS

一次操作是写2048+128字节,对应236.826uS,换算就是8.76MB/S比使用软件定时器测试的7.36MB/S大一点,因为软件额外一些逻辑处理需要一些时间,比如获取定时器时间,块之间的循环切换等。

波形如下

图片

总线上数据传输时间

总线写数据时间即第一次开始到开始写使能,

259.134-198.648=60.486uS

如下如图,后面6.96uS是两次传输之间的间隔,即软件完成一次传输到下一次传输之间的时间,也算在这个阶段了。

图片

写使能时间

由于编程完之后,NAND会自动写禁止,所以每次都需要重新写使能。

执行写使能后要回读是否设置成功(当然回读也可以省略但是出于可靠性考虑还是建议回读,如果回读未使能再重试)。

对应如下

273.890-259.134=14.756uS

图片

编程时间

344.141-273.890=70.251

图片

软件处理时间

从下可以看出编程完成到下一次开始,还有

91uS

图片

这一部分是软件处理时间,主要是软件从NAND控制器的缓存区中将数据搬运到用户存储中去。

所以整理下各阶段的时间消耗如下

总线传输 写使能 编程 软件处理
时间 60.49 14.76 70.25 91 236.5
占比 25.58% 6.24% 29.7% 38.48% 100%

可以看出软件处理实际占用时间比例最大,主要是从控制器的缓冲区中将数据搬运到用户存储的时间。

四. 性能优化

针对以上性能分析过程,对各个阶段考虑优化

1. 总线传输

已经使用了X4模式, 如果还要缩短该阶段的时间,只能继续提高频率了,目前是80M的时钟,手册中参数是3.3V快读可达133MHz。

针对读还可以使用DTR双边沿模式但是这时最大时钟频率只有70MHz,双边沿也就是140M所以比133M也大不了多少。

图片

2. 写使能时间

由于每次编程之后,NAND自动写禁止,所以该步骤不能少,可以减少回读操作大约节省7uS,但是出于可靠性设计,建议还是回读,如果回读不成功则重试。

3. 编程时间

手册中描述的时间是不使能ECC也最少要300uS,我们实测是70uS左右,所以手册已经写的很保守了,这里也没有优化空间了。

图片

4软件处理时间

这一部分主要是软件在用户存储和NAND控制器的缓存之间拷贝数据的时间。

可以使用DMA或者提高Burst来减少该时间,

最好是这一部分工作由控制器完成,而不是软件去搬运,比如软件指定一个地址,控制器自动从这个地址读,或者写入这个地址,而不是通过缓存再转一遍,减少拷贝时间。

软件时间还包括逻辑处理时间,比如一次传输到下一次传输,需要配置寄存器,进行判断,等逻辑处理。

由于软件是分层设计包括HW层寄存器的封装,HAL层传输的接口,以设备驱动层,

对于HW层封装可以使用宏或者内联函数替代函数,减少函数调用时间,HW层和HAL不做参数检查,因为接口调用频繁等,在设备驱动层做参数检查。

/**
 * n        int nfc_set_datalen(uint8_t id, uint16_t len)
 * param[in] id port id
 * param[in] len data len
 * 
etval    0  ok
 * 
etval    < 0 param err
 * 
*/
NFC_INLINE int nfc_set_datalen(uint8_t id, uint16_t len)
{
    uint32_t tmp;
    (void)id;
    tmp = NFC_READ_REG(CFG_NFC_ENA_ADDR);
    tmp &= ~NFC_DATA_LEN_MASK;
    tmp |= (len < < NFC_DATA_LEN_OFFSET);
    NFC_WRITE_REG(CFG_NFC_ENA_ADDR,tmp);
    return 0;
}

六.波形文件

这里分享一些实际抓取到的波形文件供参考

波形文件使用软件Acute TravelLogic Analyzer打开查看。

链接:https://pan.baidu.com/s/103HHT4qcvFjGn1q-jJhAUg?pwd=iqlm
提取码:iqlm

七. 总结

从以上分析可以看出最大的优化空间是减少软件从控制器缓冲区去搬运数据的时间,这一部分时间占最大头,可IP设计优化直接硬件搬运数据到用户存储。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • NAND
    +关注

    关注

    16

    文章

    1546

    浏览量

    134816
  • 存储
    +关注

    关注

    12

    文章

    3863

    浏览量

    84681
  • SPI
    SPI
    +关注

    关注

    17

    文章

    1615

    浏览量

    89669
  • 性能测试
    +关注

    关注

    0

    文章

    189

    浏览量

    21214
收藏 人收藏

    评论

    相关推荐

    使用逻辑分析仪Acute TravelLogic Analyzer进行SPI NAND驱动开发调试

    使用逻辑分析仪Acute TravelLogic Analyzer进行SPI NAND驱动开发调试
    的头像 发表于 06-08 11:13 3301次阅读
    使用逻辑<b class='flag-5'>分析</b>仪Acute TravelLogic Analyzer进行<b class='flag-5'>SPI</b> <b class='flag-5'>NAND</b><b class='flag-5'>驱动</b>开发调试

    SPI NAND FLASH 的简介和优点

    ,充分节省了PCB板的空间,已经管脚的数量,从而可以减小PCB的尺寸及层数,既满足了小型化的需求也降低了产品的成本。从上面我们了解到了 SPI NAND flash的这么多优点,那么他的性能相比于传统
    发表于 08-07 17:01

    驱动电机电磁性能分析

    为了确保计算的准确性,有必要针对驱动电机的电磁性能进行分析与校核。在此利用有限元法对驱动电机进行在空载、转矩过载、高速弱磁等工况以及短路去磁情况进行了
    发表于 10-31 10:53

    探讨一下SPI Nand Flash

    1.SPI Nand Flash简介SPI Nand Flash顾名思义就是串行接口的Nand Flash,它和普通并行的
    发表于 01-26 07:58

    怎样对基于NK-980IOT开发板的SPI NAND Flash进行读写测试

    flash作文件系统,spi nor flash对接是SFUD通用的spi flash 驱动,没细看这个spi nand flash对接是
    发表于 06-23 12:05

    SPI Nand Flash 简介

    一般可通过PAD连接闪存,比如Cadence公司的Octal-SPI NAND Flash controller, 支持8-bit的数据和地址传输,这样的速度会比传统的单比特串行SPI快很多。因为
    发表于 07-01 10:28

    《现代CPU性能分析优化》---精简的优化

    《现代CPU性能分析优化》是一本非常实用的书籍,对于从事性能关键型应用程序开发和进行系统底层优化的技术人员来说是不可或缺的。这本书也很适合
    发表于 04-18 16:03

    《现代CPU性能分析优化》--读书心得笔记

    很荣幸拿到这本<<现代CPU性能分析优化>>,花了几天的时间浏览了一遍,书比较单薄,正文只有不到200页,但是里面的内容确是非常丰富的,一般
    发表于 04-24 15:31

    没有SPI-Nand, NAND无法启动怎么解决?

    没有SPI-Nand, NAND 无法启动
    发表于 09-06 06:24

    如何做Linpack测试性能优化

    本文主要说明如何利用Linpack测试完成HPL测试,并介绍了一些简单的性能优化方法。
    发表于 11-03 13:03 9次下载

    NAND_Flash结构与驱动分析

    NAND_Flash结构与驱动分析NAND_Flash结构与驱动分析
    发表于 03-17 14:14 37次下载

    永磁驱动电机接线盒结构优化性能分析_丁树业

    永磁驱动电机接线盒结构优化性能分析_丁树业
    发表于 01-08 13:49 0次下载

    linux spi应用层驱动以及回环测试代码

    linux spi应用层驱动以及回环测试代码
    发表于 10-22 15:47 2次下载

    SPI Nand Flash简介

    1.SPI Nand Flash简介SPI Nand Flash顾名思义就是串行接口的Nand Flash,它和普通并行的
    发表于 12-02 10:51 33次下载
    <b class='flag-5'>SPI</b> <b class='flag-5'>Nand</b> Flash简介

    如何优化MCU SPI驱动程序以实现高ADC吞吐速率

    如何优化MCU SPI驱动程序以实现高ADC吞吐速率
    的头像 发表于 10-24 16:03 330次阅读
    如何<b class='flag-5'>优化</b>MCU <b class='flag-5'>SPI</b><b class='flag-5'>驱动</b>程序以实现高ADC吞吐速率