02
2025
07
01:13:44

嵌入式面试指南:你必须掌握的Flash知识

在嵌入式开发中,Flash存储器是核心的非易失性存储介质(NVM),用于存储固件、配置参数、日志数据等。理解Flash的特性、操作方式和限制对设计可靠、高效的嵌入式系统至关重要。

一、Flash存储器基础

  1. 1. 基本类型:
    • • Nor Flash:
      • • 特点: 支持XIP,随机访问速度快(读接近RAM),按字节/字读取。擦除和写入速度慢
      • • 接口: 通常并行或SPI接口,可直接连接到CPU地址/数据总线。
      • • 结构: 存储单元并联,允许直接访问任意地址。
      • • 用途: 主要存储启动代码、操作系统内核、应用程序代码(尤其在需要XIP的场景),小容量配置数据。
    • • Nand Flash:
      • • 特点: 不支持XIP,按页读取,按块擦除。顺序访问速度快,容量/成本比高,擦写寿命有限。存在坏块。
      • • 接口: 复杂接口(需要控制器),常见类型有原始NAND、eMMC、SD卡、U盘、SSD(内部都是NAND)。
      • • 结构: 存储单元串联,访问以页为单位。
      • • 用途: 主要存储大容量数据,如文件系统、用户数据、媒体文件、操作系统映像(需加载到RAM运行)。是现代嵌入式系统大容量存储的主力。
  2. 2. 关键特性:
    • • 非易失性: 断电后数据不丢失。
    • • 写入前需擦除: Flash单元只能从1写成0。要将0改回1(或写入新数据),必须先擦除(通常是整块/整扇区擦除为全1),然后再写入。这是Flash操作最根本的限制。
    • • 有限擦写寿命:
      • • Nor Flash: 典型擦写次数 10万 - 100万次
      • • Nand Flash:
        • • SLC: 10万 - 100万次
        • • MLC: 3千 - 1万次
        • • TLC: 500 - 3千次
        • • QLC: 更低
      • • 重要性: 直接影响系统寿命和可靠性。设计时必须考虑磨损均衡。
    • • 读写不对称性:
      • • 读操作: 快,相对简单(Nor接近RAM,Nand按页读也较快)。
      • • 写操作: 慢且复杂,必须先擦除(更慢)再写入。
    • • 操作单位:
      • • 读: Nor可按字节/字,Nand按页(典型512B, 2KB, 4KB, 8KB, 16KB)。
      • • 写: 按页编程(Nand)或按字/字节(Nor,但需擦除整个块)。
      • • 擦除: 按块/扇区进行(大小从几KB到几百KB甚至MB)。
    • • 坏块: 主要存在于Nand Flash中。出厂时或使用过程中可能产生无法可靠存储数据的块。管理坏块是Nand驱动/文件系统的核心任务之一。
    • • 位翻转: Nand Flash在读写过程中可能偶然发生单个或多个比特的错误。需要ECC进行检测和纠正。
    • • 功耗: 擦除和写入操作功耗远高于读操作。

二、嵌入式系统中的Flash操作

  1. 1. Bootloader与固件存储:
    • • 系统上电后,CPU从Flash(通常是Nor Flash或芯片内部Flash)的固定地址(复位向量)开始执行Bootloader。
    • • Bootloader初始化硬件,然后将应用程序固件从Flash(可能是Nor或Nand)加载到RAM中执行(XIP除外),或直接XIP执行。
    • • 固件更新通常涉及擦除Flash的应用程序区域,写入新固件映像。
  2. 2. 数据存储:
    • • 系统配置参数、校准数据、用户设置、运行日志、事件记录等需要掉电保存的数据存储在Flash中。
    • • 需要特别注意更新频率擦写寿命,避免频繁写入同一区域导致提前损坏。常采用:
      • • 写平衡: 将数据写到不同位置,避免集中磨损。
      • • 状态标记: 使用标志位标识数据有效/无效。
      • • 日志式结构: 追加新记录,定期清理旧数据。
  3. 3. 文件系统:
    • • 对于需要存储大量文件或复杂数据结构的应用(如使用SD卡、eMMC),需要在Flash(主要是Nand)上实现文件系统。
    • • 常见嵌入式文件系统:
      • • FAT/exFAT: 兼容性好(PC可读),简单,但可靠性一般(掉电易损坏),无坏块管理/磨损均衡。
      • • YAFFS/YAFFS2: 专为Nand设计,直接管理物理特性(坏块、ECC),性能好,但授权可能受限。
      • • JFFS/JFFS2: 日志型,为Nor设计,也可用于Nand(效率较低)。直接在MTD上运行。
      • • UBIFS: 基于UBI卷管理层,专为现代大容量Nand设计,提供比JFFS2更好的性能和扩展性。
      • • SPIFFS/LittleFS: 轻量级,专为SPI Nor设计,资源占用小,抗掉电能力强。
      • • Ext2/3/4, Btrfs: 更通用,但通常需要Linux等OS支持,开销较大。
    • • MTD层: 在Linux等系统中,MTD提供统一的抽象接口访问原始Flash设备(Nor/Nand),文件系统构建在MTD之上。
  4. 4. Flash控制器与驱动:
    • • 大多数MCU内置了Flash控制器,用于管理内部Flash的读写擦除操作,提供编程接口(寄存器操作或库函数)。
    • • 外部Flash需要开发者:
      • • 根据接口(SPI, QSPI, Parallel)实现底层驱动(GPIO模拟或使用外设控制器)。
      • • 严格按照Flash芯片手册的时序要求进行操作(发送命令序列、等待操作完成)。
      • • 处理擦写寿命、坏块(Nand)、位翻转(ECC)。

三、Flash编程的关键技术与挑战

  1. 1. 擦除管理:
    • • 理解最小擦除单位(扇区/块)。
    • • 规划存储布局,避免频繁擦除小块。
    • • 在更新小块数据时,常采用“读-改-写”策略:
      1. 1. 将目标块数据读入RAM缓冲区。
      2. 2. 在RAM中修改需要更新的部分。
      3. 3. 擦除整个Flash块。
      4. 4. 将修改后的整个缓冲区写回Flash块。
    • • 这需要额外的RAM缓冲区。
  2. 2. 磨损均衡:
    • • 目标: 让Flash的所有块(或可写区域)的擦写次数尽可能平均,延长整体寿命。
    • • 方法:
      • • 动态: 记录每个块的擦写计数,优先选择擦写次数最少的块写入新数据(需要元数据存储和查找)。
      • • 静态: 将不常修改的数据(如代码)迁移到擦写次数较多的块,腾出擦写次数少的块给频繁修改的数据(更复杂)。
    • • 重要性: 对Nand和使用Flash存储频繁更新数据的场景至关重要。文件系统(如UBIFS, YAFFS2)或专用库(如LittleFS的磨损均衡)通常内置此功能。
  3. 3. 坏块管理:
    • • Nand专属问题。
    • • 出厂坏块: 芯片出厂时标记(特定地址有非FF值)。驱动初始化时必须扫描并建立坏块表。
    • • 运行时坏块: 使用过程中出现。驱动/文件系统在写入或擦除失败(或ECC无法纠正的读错误)后需标记该块为坏块,并将数据重映射到备用块。
    • • 方法: 通常通过坏块表实现,表本身需要存储在Flash可靠位置(如预留块),并考虑其自身的备份和更新。
  4. 4. ECC:
    • • 必要性: 检测和纠正Nand Flash读写过程中发生的位翻转错误。
    • • 原理: 为写入的数据页计算校验码(如Hamming码, BCH码, LDPC码),并将校验码存储在Flash的OOB/Spare区域。读取时重新计算校验码并与存储的比较,检测并纠正错误。
    • • 硬件支持: 许多现代MCU/SoC内置硬件ECC引擎,效率高。软件实现开销大。
    • • 强度: 不同ECC算法纠错能力不同(如BCH可纠多比特错误),需根据Flash类型和可靠性要求选择。
  5. 5. 掉电保护:
    • • 风险: 在擦除或写入操作过程中断电,可能导致数据损坏或元数据不一致(文件系统崩溃)。
    • • 策略:
      • • 原子操作: 确保关键操作(如更新标志位、文件系统元数据)要么完全完成,要么像没发生过一样。设计状态机。
      • • 日志/事务: 先在日志区记录要做的操作,完成后再更新主数据区。故障恢复时检查日志。
      • • 写前拷贝: 修改数据时,先写到新位置,更新指针指向新位置,最后擦除旧位置。
      • • 备份: 关键数据存储多份。
      • • 超级电容/UPS: 提供短暂电力完成关键操作。
      • • 文件系统特性: 选择抗掉电能力强的文件系统(如LittleFS, SPIFFS, UBIFS)。
  6. 6. 性能优化:
    • • 缓存: 对频繁读取的数据进行缓存。
    • • 批量写入: 累积足够数据再写入,减少擦写次数和碎片。
    • • 双缓冲/乒乓缓冲: 在写入一个缓冲区时,应用程序填充另一个缓冲区,提高吞吐量。
    • • 预取/后台擦除: 提前擦除可能需要的空闲块。
    • • 选择高速接口: QSPI > SPI, ONFI/Toggle NAND > 传统异步NAND。

四、安全考虑

  1. 1. 代码保护/读保护: 防止通过调试接口读取Flash中的固件代码。MCU通常提供读保护位/选项字节设置。
  2. 2. 写保护: 防止固件被意外或恶意修改。可通过硬件写保护引脚或软件配置保护区域实现。
  3. 3. 安全启动: 验证从Flash加载的固件的完整性和来源合法性(使用数字签名、哈希)。
  4. 4. 加密存储: 对存储在Flash中的敏感数据(如密钥、用户数据)进行加密。
  5. 五、Flash实战之读擦写

    1. 图片
      以GD25WQ40E SPI Nor Flash举例,结合DataSheet介绍常用功能:
    2. 1. 状态寄存器(Status Register):

    1. 图片

  6. 2. Write Enable(cmd:0x06):
    图片

  7. 3. Read Data Bytes(cmd:0x03):
    图片

    4. Dual I/O Fast Read(cmd:0xBB):
  8. 图片

    5. Quad I/O Fast Read(cmd:0xEB):
    图片

    6. Sector Erase(cmd:0x20):
    图片

    7.  Chip Erase(cmd:0x60/0xC7):
    图片

    1. 8.  Page Program(cmd:0x02):
    图片

    1. 9.  Quad Page Program(cmd:0x32):
    图片

    通过查阅Flash对应的DataSheet我们可以获取Flash的操作command,通过cmd + address + data 完成我们想要的FLash通信。

    总结

    深入理解嵌入式Flash存储器的物理特性(擦除、寿命、坏块、位翻转)、操作方式(读写擦除单位)和关键技术(磨损均衡、坏块管理、ECC、掉电保护),是开发稳定、可靠、长寿命嵌入式系统的基石。

    根据应用需求(容量、速度、寿命、成本、可靠性)选择合适的Flash类型(Nor/Nand/SLC/MLC/TLC)和配套的软件方案(驱动、文件系统、存储管理库)至关重要。务必仔细阅读所使用Flash芯片和MCU的参考手册。




    推荐本站淘宝优惠价购买喜欢的宝贝:

    image.png

    本文链接:https://www.hqyman.cn/post/12053.html 非本站原创文章欢迎转载,原创文章需保留本站地址!

    分享到:
    打赏





    休息一下~~


    « 上一篇 下一篇 »

    发表评论:

    ◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

    请先 登录 再评论,若不是会员请先 注册

    您的IP地址是: