文章目录
- [前言:什么是Nand Flash?](#前言:什么是Nand Flash?)
- [1、Nand Flash 读取步骤](#1、Nand Flash 读取步骤)
- 2、从主存读到Cache
-
- [2.1 在标准spi接口下读取过程](#2.1 在标准spi接口下读取过程)
- [2.2 测试时序(SPI频率30MHz)](#2.2 测试时序(SPI频率30MHz))
- 3.从Cache读取数据
前言:什么是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
纠错的最大限度
c
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位
发送数据
c
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);
}
测试时序
发送读取指令和地址: