打印
[其他]

RT thread 之 Nand flash 读写过程分析

[复制链接]
400|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
观海|  楼主 | 2023-8-24 11:12 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
前言:什么是Nand Flash?
NAND Flash 是一种常见的闪存存储器类型,广泛应用于各种电子设备中,如手机、平板电脑、嵌入式系统等。它是一种非易失性存储器,可以持久地保存数据即使在断电情况下。

NAND Flash 与传统的 NOR Flash 相比具有较高的存储密度和较低的成本,但其随机访问速度较慢。它使用了一种称为 NAND 门的逻辑结构,使得数据存储和读取操作更加高效。

NAND Flash 存储器被组织为多个块(Block),每个块又由多个页(Page)组成。每个页通常包含一个数据区域和一个擦除区域,数据区域用于存储实际的用户数据,擦除区域用于擦除整个块。

NAND Flash 的基本操作包括读取、写入和擦除。读取操作通过指定页地址和偏移量来获取存储在特定位置的数据。写入操作将数据写入指定的页地址和偏移量。擦除操作会将整个块的数据擦除,使其变为可写状态。

在嵌入式系统中,使用 NAND Flash 存储器通常需要通过驱动程序与操作系统进行交互。驱动程序负责管理 NAND Flash 的读取、写入和擦除操作,并提供文件系统层面的接口供应用程序使用。

总的来说,NAND Flash 是一种常见的闪存存储器,具有高存储密度和低成本的优势。它在各种电子设备中广泛应用,并通过驱动程序与操作系统进行交互,提供数据存储和读取功能。

1、Nand Flash 读取步骤
NAND Flash 的读取步骤通常包括以下几个关键步骤:

选择芯片(Chip Select):如果系统中同时连接了多个 NAND Flash 芯片,首先需要选择要读取的芯片。这通常通过将芯片的片选引脚(CE)置为逻辑低电平来实现。

发送读取命令:向 NAND Flash 发送读取命令,以指示要读取的页地址和偏移量。读取命令通常是通过将命令字节序列发送到 NAND Flash 的命令/地址总线上实现的。

等待就绪状态:发送读取命令后,需要等待 NAND Flash 进入就绪状态,表示它已准备好进行读取操作。可以通过检查状态寄存器或等待足够的时间来实现等待。

读取数据:一旦 NAND Flash 进入就绪状态,就可以开始读取数据。读取的数据通常通过数据总线传输,并存储到指定的缓冲区中。

解码和处理数据:读取的数据可能需要进行解码和处理,以还原原始的用户数据。这通常涉及到 ECC(错误检测和纠正)算法,用于检测和纠正可能存在的位错误。

取消芯片选择:读取操作完成后,需要取消对芯片的选择,以释放总线资源。通常通过将芯片的片选引脚(CE)置为逻辑高电平来实现。

需要注意的是,具体的 NAND Flash 读取步骤可能会因芯片厂商和控制器的不同而有所差异。因此,在实际应用中,需要参考 NAND Flash 芯片的规格手册和相关的驱动程序文档,以了解具体的读取流程和命令序列。

从主存中读到Cache
从Cache读取数据

2、从主存读到Cache
2.1 在标准spi接口下读取过程

发送Page Read to Cache command(13H)
发送page地址 24位
检查寄存器位OIP,读取flash状态,等待主存读cache操作完成
读取hwecc位,判断是否超过ecc纠错的最大限度

rt_err_t spinand_read_dataload(struct rt_spi_device *spi,  uint8_t u8Addr2, uint8_t u8Addr1, uint8_t u8Addr0)
{
    rt_err_t result = RT_EOK;
    uint8_t au8Cmd[4] = {CMD_PAGE_READ_TO_CACHE, u8Addr2, u8Addr1, u8Addr0};
    uint8_t u8SR;


    if ((result = rt_spi_send(spi, &au8Cmd[0], sizeof(au8Cmd))) == 0)
        goto exit_spinand_read_dataload;

    if (spinand_isbusy(spi))
    {
        result = -RT_EIO;
        goto exit_spinand_read_dataload;
    }

    u8SR = spinand_hwecc_status_get(spi);
    if ((u8SR != 0x00) && (u8SR != 0x01))
    {
        result = -RT_MTD_EECC;
        LOG_E("Error ECC status error[0x%x].", u8SR);
    }

exit_spinand_read_dataload:

    return result > 0 ? RT_EOK : -RT_ERROR;
}



2.2 测试时序(SPI频率30MHz)
发送读取指令和地址:

检查寄存器位OIP,读取flash状态,等待主存读cache操作完成

OIP位至0,主存读cache操作完成

整个过程消耗时间

3.从Cache读取数据
3.1在标准spi接口读取过程
发送Read From Cache command(03H)
发送page地址 24位
发送数据



        rt_err_t spinand_normal_read(struct rt_spi_device *spi, uint8_t u8AddrH, uint8_t u8AddrL, uint8_t *pu8Buff, uint32_t u32Count)
        {
            uint8_t au8Cmd[4] = {CMD_READ_FROM_CACHE, u8AddrH, u8AddrL, DUMMY_BYTE};
       
            return rt_spi_send_then_recv(spi, &au8Cmd[0], sizeof(au8Cmd), pu8Buff, u32Count);
}


测试时序
发送读取指令和地址:

————————————————
版权声明:本文为CSDN博主「墨染 锦年」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_44710568/article/details/131896353

使用特权

评论回复
沙发
houcs| | 2023-8-26 23:35 | 只看该作者
需要等待主存读cache操作完成

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

99

主题

3882

帖子

1

粉丝