nand flash_笔记

本文深入探讨了NAND Flash的基本概念,包括其结构、操作原理、典型特性及接口规范等内容,并对比了NOR Flash的特点,同时介绍了相关的ONFI与LBA规范,以及适用于NAND Flash的嵌入式文件系统。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考文章:http://blog.youkuaiyun.com/xgbing/article/details/18422691


名次解释:

BBM  :  Bad Block Management 坏块管理

BBT  : Bad Block Table 坏块表

ECC : Error Correction Code 错误校验码

MTD : Memory Technology Device 内存技术设备


Norflash:以块为单元,写入时需要先擦除,擦除和写入的速度很慢,但Norflash具有SRAM接口,有单独的地址总线和数据总线,接口简单,像访问ROM一样,读取速度快,能随机访问存储单元。通常用来存储启动代码,价格贵1-16M居多

Norflash有两种标准JEDEC 和CFI

JEDEC  Joint Electron Device Engineering Council 电子元件工业联合会,JEDEC用来帮助程序读取Flash的PID和VID,以确定flash的大小和算法。

CFI  Common Flash Interface 公共闪存接口。是一个公开标准的从flash中读取数据的接口,是系统软件查询已安装的flash的各种参数,市面Norflash大多支持CFI。

CFI规定先往flash数据总线写入55H,再写98H,然后从地址10H读取3Byte,如果是'Q'  'R'  'Y' ,那么遵循CFI标准。

cfi.h规定了 查询的数据结构

/* Basic Query Structure */  
struct cfi_ident {  
    uint8_t  qry[3];//’Q‘,'R','Y'  
    uint16_t P_ID;  
    uint16_t P_ADR;  
    uint16_t A_ID;  
    uint16_t A_ADR;  
    uint8_t  VccMin;  
    uint8_t  VccMax;  
    uint8_t  VppMin;  
    uint8_t  VppMax;  
    uint8_t  WordWriteTimeoutTyp;  
    uint8_t  BufWriteTimeoutTyp;  
    uint8_t  BlockEraseTimeoutTyp;  
    uint8_t  ChipEraseTimeoutTyp;  
    uint8_t  WordWriteTimeoutMax;  
    uint8_t  BufWriteTimeoutMax;  
    uint8_t  BlockEraseTimeoutMax;  
    uint8_t  ChipEraseTimeoutMax;  
    uint8_t  DevSize;  
    uint16_t InterfaceDesc;  
    uint16_t MaxBufWriteSize;  
    uint8_t  NumEraseRegions;  
    uint32_t EraseRegionInfo[0]; /* Not host ordered */  
} __attribute__((packed));  



nand flash结构图


对于flash,读取/写入的最小单元 是 Page/页,一般大小是2KB 4KB 8KB

擦除的最小单元是 Block/块,一般大小是128KB  256KB  512KB


管脚说明:

IO0 - IO7 :数据/地址复用

CLE :命令锁存

ALE :地址锁存

CE :芯片使能

RE :读使能

WE :写使能

WP :写保护

R/B :就绪/忙


典型特性:

1、页擦除时间是200us,慢的800us

2、块擦除时间是1.5ms

3、页数据读取到数据寄存器一般时间是20us

4、串行访问一个数据的时间是25ns

5、页寄存器(Page Register),对于每一片plane,都有用于缓存将要读写的一页数据,又叫页缓存

nand flash的读写数据流向:


举例:nand flash 数据读取时序图



物理地址 = 块大小 * 块号  +  页大小 * 页号  +  页内地址


案例:

型号K9K8G08U0A,8192个块,每个块64页,每个页2K

访问第7000个块中的第64页的1208字节的地址,物理地址 = 128K *7000 + 2K *64 +1208 = 0x36B204B8

nand flash的地址周期组成:


nand flash的地址周期有5个,2个列周期column address,3个行周期row address

A0 - A10是业内地址,范围0 - 2047

A11用于表示业内的oob区域,其大小是64字节

A12 - A30 是页号

A18 - A30 是块号

所以:0x36B204B8 = 11  0110  1011  0010  0000  0100  1011  1000

周期1  : A0 - A7        1011 1000       0xB8

周期2  : A10 - A8                  100       0x04

周期3  : A19 - A11    010 0000 0      0x40

周期4  : A27 - A20    110 1011 0       0xD6

周期5  : A30 - A28                 11 0       0x06

注意:A11用于oob位置,只有当页内地址属于2048-2111的时候,A11才会有效果

在Linux源码/drivers/mtd/nand/nand_base.c中,是这样处理的:

static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
                int column, int page_addr)
{
......
        /* Serially input address */
        if (column != -1) {
......
            chip->cmd_ctrl(mtd, column1, ctrl); /* 发送Col Addr 1 */
            ctrl &= ~NAND_CTRL_CHANGE;
            chip->cmd_ctrl(mtd, column >> 8, ctrl); /* 发送Col Addr 2 */
        }
        if (page_addr != -1) {
            chip->cmd_ctrl(mtd, page_addr2, ctrl); /* 发送Row Addr 1 */
            chip->cmd_ctrl(mtd, page_addr >> 8, /* 发送Row Addr 2 */
                       NAND_NCE | NAND_ALE); 
            /* One more address cycle for devices > 128MiB */
            if (chip->chipsize > (128 << 20))
                chip->cmd_ctrl(mtd, page_addr >> 16, /* 发送Row Addr 3 */
                           NAND_NCE | NAND_ALE); 
        }
}

虽然操作是读取页内部分数据,但硬件仍会将整个页读取到页缓存中。


nand flash相关规范

ONFI 规范   Open Nand Flash Interface specification

有Intel主导,统一了nand flash的操作接口包括操作命令。

http://onfi.org/specifications/


LBA规范

LBA Nand Flash : Logical Block Address,逻辑块寻址的Nand Flash,Toshiba主导

普通nand flash是按物理块寻址,缺点是坏块情况下的软件工作量繁重。

LBA把ECC校验、坏块管理、负载平衡的工作放在硬件上实现。

http://www.toshiba-components.com/prpdf/5678E.pdf


嵌入式常用文件系统:

JFFS2 是RedHat基于JFFS开发的闪存文件系统。可读,可压缩的日志型文件系统,提供崩溃/掉电安全保护,使用了基于哈希表的日志节点结构,加快了对节点操作速度,支持数据压缩,提供“写平衡”支持,是目前最流行的文件系统。缺点是:文件系统已满,或者接近于满时,JFFS2运行变慢,因为碎片收集的问题

Yaffs 和jffs2类似的闪存文件系统,专为嵌入式系统使用Nand型闪存而设计的一种日志文件系统。比jffs2少了一个功能,因此速度更快,对内存要求比较小。自带Nand芯片驱动,提供了直接访问文件系统的API。用户可以直接对文件系统操作。相反,Jffs2在Nand闪存上表现得并不稳定,更适合Nor闪存












<think>嗯,用户想了解关于ZYNQ从NAND Flash启动的应用笔记。首先,我需要回忆一下ZYNQ的启动流程。ZYNQ是Xilinx的SoC,结合了ARM处理器和FPGA。启动过程涉及多个阶段,包括BootROM、FSBL,可能还有U-Boot和应用程序。 用户的问题是关于从NAND启动,所以需要明确启动配置。首先,ZYNQ的启动模式由引脚设置,比如MIO[5:0]的状态。需要确认用户是否了解如何设置这些引脚为NAND启动模式,比如设置为001010。 接下来,系统需要正确的启动文件。首先是FSBL(First Stage Boot Loader),它负责初始化硬件和加载后续镜像。FSBL需要配置成支持NAND接口,可能需要在Vivado中设置硬件参数,比如NAND的时序、总线宽度等。 然后是镜像的生成。ZYNQ的启动镜像通常包括FSBL、FPGA比特流和应用程序(如U-Boot或裸机应用)。这些需要打包成BOOT.BIN文件。用户可能需要使用Xilinx的工具,如BootGen,来正确配置分区和加载顺序。 另外,NAND Flash的驱动支持也很重要。FSBL需要能够与NAND Flash通信,这涉及到控制器初始化和坏块管理。可能需要检查FSBL的代码是否包含NAND的驱动,并正确配置相关参数,比如页大小、块大小、ECC等。 硬件连接方面,用户需要确保ZYNQ的NAND接口与实际的NAND Flash芯片正确连接,包括数据线、控制信号和电源。电气特性的匹配也很关键,比如电压和信号完整性。 还有可能遇到的问题是坏块处理。NAND Flash通常有坏块,启动过程中需要跳过这些坏块。FSBL或后续的引导程序需要实现坏块管理策略,例如在写入镜像时预留备用块,或者在读取时检测并跳过坏块。 最后,调试阶段可能会用到JTAG或串口输出,以查看启动过程中的错误信息。例如,如果FSBL无法加载镜像,可能需要检查NAND的初始化是否正确,或者镜像文件是否正确烧录。 总结来说,用户可能需要逐步设置启动模式、配置硬件、生成正确的启动镜像、处理NAND的驱动和坏块管理,并进行调试。需要确保每个步骤的细节正确,比如Vivado中的配置和BootGen的设置,才能成功从NAND启动。</think>以下是ZYNQ从NAND Flash启动的关键步骤说明,按系统级启动流程分步呈现: $$ \text{启动流程} = \text{BootROM} \rightarrow \text{FSBL} \rightarrow \text{用户应用} $$ ### 一、硬件配置要求 1. **NAND接口配置** - 在Vivado中设置Quad-SPI控制器为NAND模式 - 验证MIO引脚分配符合硬件原理图,例如: $$ \text{数据总线宽度} = 8 \text{位} \quad \text{或} \quad 16 \text{位} $$ - 配置时序参数: $$ t_{RC}/t_{WC} \leq 30ns \quad \text{(典型值)} $$ 2. **启动模式设置** - 设置MIO[5:0]=001010(NAND 8位模式) - 或MIO[5:0]=001011(NAND 16位模式) ### 二、软件镜像生成 1. **镜像组成结构** $$ \text{BOOT.BIN} = \text{FSBL} + \text{比特流} + \text{应用程序} $$ 2. **FSBL特殊配置** ```c // 在xparameters.h中启用NAND支持 #define XPAR_PS7_NAND_0_DEVICE_ID 0 #define XPAR_PS7_QSPI_0_DEVICE_ID 1 ``` ### 三、烧录操作流程 1. **Flash编程器配置** - 使用Vivado Hardware Manager - 选择NAND参数: $$ \text{Page Size} = 2048 \text{字节}, \quad \text{Block Size} = 128 \text{KB} $$ 2. **地址映射规范 | 镜像部件 | 起始地址 | 长度 | |------------|----------|------------| | Boot Header| 0x000000 | 0x800 | | FSBL | 0x000800 | 0x10000 | | 比特流 | 0x010800 | 可变长度 | | 应用程序 | 后续地址 | 可变长度 | ### 四、坏块处理机制 1. **坏块检测算法** $$ \text{坏块标志} = \begin{cases} 0xFF & \text{正常块} \\ \neq 0xFF & \text{坏块} \end{cases} \quad \text{(位于每个块的第1/2页备用区)} $$ 2. **跳过策略** ```c while(current_block < total_blocks){ if(is_bad_block(current_block)){ current_block++; continue; } // 执行正常操作 } ``` ### 五、启动时序分析 $$ T_{boot} = T_{BootROM} + T_{FSBL} + T_{PL} + T_{App} $$ - 典型值参考: - BootROM阶段:约200ms - FSBL加载:取决于镜像大小,每MB约50ms ### 调试建议 1. **Xilinx SDK调试技巧** - 在FSBL中启用调试打印: ```c #define FSBL_DEBUG_INFO ``` - 通过UART查看启动日志 2. **常见故障代码** - **0x0000000C**: NAND控制器初始化失败 - **0x0000001A**: ECC校验错误 实际开发时建议结合Xilinx官方文档《UG821》和《UG585》进行参数校准,建议预留至少2%的备用块空间用于坏块替换。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值