【STM32】Flash详解

【STM32】Flash详解

文章目录

  • 【STM32】Flash详解
    • 1.Flash闪存概念
      • [1. 1核心区别:NOR Flash vs. NAND Flash](#1. 1核心区别:NOR Flash vs. NAND Flash)
      • [1.2 为什么常说的"Flash"多指 NAND Flash?](#1.2 为什么常说的“Flash”多指 NAND Flash?)
      • 1.3技术细节对比
        • [(1) 存储单元结构](#(1) 存储单元结构)
        • [(2) 应用场景](#(2) 应用场景)
        • [(3) 可靠性要求](#(3) 可靠性要求)
      • 1.4总结
    • 2.STM32内部的Flash
      • [2.1为什么是 NOR Flash?](#2.1为什么是 NOR Flash?)
      • [2.2STM32 内部 Flash 的关键特性](#2.2STM32 内部 Flash 的关键特性)
      • [2.3 与外部 NAND Flash 的对比](#2.3 与外部 NAND Flash 的对比)
      • [2.4 操作 STM32 内部 Flash 的注意事项](#2.4 操作 STM32 内部 Flash 的注意事项)
      • [2.5 常见问题](#2.5 常见问题)
        • [Q1:为什么 STM32 不集成 NAND Flash?](#Q1:为什么 STM32 不集成 NAND Flash?)
        • [Q2:如何扩展 STM32 的存储容量?](#Q2:如何扩展 STM32 的存储容量?)
    • [3.读写NAND Flash的方法](#3.读写NAND Flash的方法)
      • [3.1直接读写 NAND Flash 的方法](#3.1直接读写 NAND Flash 的方法)
        • [1. 通过专用 NAND Flash 控制器](#1. 通过专用 NAND Flash 控制器)
        • [2. 通过 SPI 接口](#2. 通过 SPI 接口)
      • [3.2间接读写 NAND Flash 的方法](#3.2间接读写 NAND Flash 的方法)
        • [1. 通过 SDIO 接口读写 SD卡(内含 NAND Flash)](#1. 通过 SDIO 接口读写 SD卡(内含 NAND Flash))
        • [2. 通过 eMMC/UFS 接口](#2. 通过 eMMC/UFS 接口)
      • [3.3SDIO 与 NAND Flash 的关系](#3.3SDIO 与 NAND Flash 的关系)
      • 3.4方法选择建议
      • 3.5代码示例对比
        • [1. 直接操作 NAND Flash(STM32 HAL 库)](#1. 直接操作 NAND Flash(STM32 HAL 库))
        • [2. 通过 SDIO 读写 SD卡(STM32 HAL 库)](#2. 通过 SDIO 读写 SD卡(STM32 HAL 库))
      • 3.6关键问题解答
        • [Q1:为什么不能直接用 SDIO 操作裸片 NAND Flash?](#Q1:为什么不能直接用 SDIO 操作裸片 NAND Flash?)
        • [Q2:如何选择直接操作 NAND Flash 还是用 SD卡?](#Q2:如何选择直接操作 NAND Flash 还是用 SD卡?)
      • 3.7总结
    • [4. NAND Flash 基础](#4. NAND Flash 基础)
      • [4.1 什么是 NAND Flash?](#4.1 什么是 NAND Flash?)
      • [4.2 NAND Flash 操作](#4.2 NAND Flash 操作)
      • [4.3 关键问题](#4.3 关键问题)
      • [4.2 STM32 与 NAND Flash 的硬件连接](#4.2 STM32 与 NAND Flash 的硬件连接)
        • [1. 接口方式](#1. 接口方式)
        • 2.FMC介绍
        • [3. 典型硬件连接](#3. 典型硬件连接)
        • [4. 硬件设计注意事项](#4. 硬件设计注意事项)
    • [5. STM32 的 NAND Flash 驱动开发](#5. STM32 的 NAND Flash 驱动开发)
      • [5.1 使用 STM32 HAL 库](#5.1 使用 STM32 HAL 库)
      • [5.2 关键代码步骤](#5.2 关键代码步骤)
      • [5.3 ECC 实现](#5.3 ECC 实现)
    • [6. 文件系统集成](#6. 文件系统集成)
      • [6.1 FATFS(通用文件系统)](#6.1 FATFS(通用文件系统))
      • [6.2 LittleFS 或 SPIFFS(嵌入式专用)](#6.2 LittleFS 或 SPIFFS(嵌入式专用))
      • [6.3 UBIFS(Linux 系统)](#6.3 UBIFS(Linux 系统))
    • 7.FTL层
      • [7.1为什么需要 FTL?](#7.1为什么需要 FTL?)
      • [7.2使用 FTL 的场景](#7.2使用 FTL 的场景)
        • [1. 必须使用 FTL 的情况](#1. 必须使用 FTL 的情况)
        • [2. 可不用 FTL 的情况](#2. 可不用 FTL 的情况)
      • [7.3FTL 的典型实现方式](#7.3FTL 的典型实现方式)
      • [7.4使用 FTL 的优缺点](#7.4使用 FTL 的优缺点)
      • [7.5示例:使用 vs. 不使用 FTL](#7.5示例:使用 vs. 不使用 FTL)
        • [1. 使用 FTL(以 SD卡为例)](#1. 使用 FTL(以 SD卡为例))
        • [2. 不使用 FTL(直接操作裸片 NAND Flash)](#2. 不使用 FTL(直接操作裸片 NAND Flash))
      • [7.6如何选择是否使用 FTL?](#7.6如何选择是否使用 FTL?)
      • 7.7常见问题
        • [Q1:FTL 和文件系统有什么区别?](#Q1:FTL 和文件系统有什么区别?)
        • [Q2:SSD 中的 FTL 是如何工作的?](#Q2:SSD 中的 FTL 是如何工作的?)
        • [Q3:自行实现 FTL 的难点是什么?](#Q3:自行实现 FTL 的难点是什么?)
      • [7.8直接操作 NAND Flash 的核心差异**](#7.8直接操作 NAND Flash 的核心差异**)
      • [7.9直接操作 NAND Flash 的必备操作**](#7.9直接操作 NAND Flash 的必备操作**)
        • [1. 坏块管理(Bad Block Management)](#1. 坏块管理(Bad Block Management))
        • [2. 磨损均衡(Wear Leveling)](#2. 磨损均衡(Wear Leveling))
        • [3. ECC 校验(Error Correction Code)](#3. ECC 校验(Error Correction Code))
        • [4. 地址映射(Address Mapping)](#4. 地址映射(Address Mapping))
        • [5. 垃圾回收(Garbage Collection)](#5. 垃圾回收(Garbage Collection))
      • [7.3直接操作 vs. 使用 FTL 的典型场景](#7.3直接操作 vs. 使用 FTL 的典型场景)
        • [1. 适合直接操作的场景](#1. 适合直接操作的场景)
        • [7.4适合使用 FTL 的场景](#7.4适合使用 FTL 的场景)
      • 7.10关键挑战与解决方案
      • 7.11总结
    • [8. 示例项目:STM32 + NAND Flash 数据记录仪](#8. 示例项目:STM32 + NAND Flash 数据记录仪)
      • [8.1 硬件配置](#8.1 硬件配置)
      • [8.2 NAND FLASH基本驱动步骤](#8.2 NAND FLASH基本驱动步骤)
      • [8. 3常见问题与调试](#8. 3常见问题与调试)
        • [1. 初始化失败](#1. 初始化失败)
        • [2. 读写错误](#2. 读写错误)
        • [3. 文件系统挂载失败](#3. 文件系统挂载失败)
      • 总结

1.Flash闪存概念

  • Flash 闪存 是一个广义的存储技术类别,包含 NOR FlashNAND Flash 两种主要类型。

NAND Flash 是 Flash 闪存的一种具体实现形式,也是目前应用最广泛的类型,所以我们本章节主要讲这个。


1. 1核心区别:NOR Flash vs. NAND Flash

特性 NOR Flash NAND Flash
存储结构 并行架构,类似内存(随机访问) 串联架构,类似硬盘(块访问)
读取速度 (支持随机读取) 较慢(按页/块读取)
写入/擦除速度 慢(按字节写入,需整块擦除) (按页写入,整块擦除)
容量与成本 容量小(MB~GB),成本高集成在芯片内 容量大(GB~TB),成本低外置
寿命(擦写次数) 约 10万次 约 1万~10万次(需磨损均衡)
接口 支持直接寻址(XIP) 需通过控制器访问(命令序列)
典型应用 存储代码(如 BIOS、固件) 存储数据(如 U盘、SSD、手机)

1.2 为什么常说的"Flash"多指 NAND Flash?

  1. 容量与成本优势

    NAND Flash 的密度高、容量大,更适合大容量存储场景(如手机、固态硬盘),而 NOR Flash 通常用于小容量代码存储。

  2. 消费电子主导市场

    日常接触的 U盘、SD卡、SSD、手机存储等均基于 NAND Flash,因此大众更熟悉"NAND Flash"这一分支。

  3. 技术进步推动

    NAND Flash 的工艺演进(如 3D NAND)进一步提升了容量和性价比,使其成为主流选择。


1.3技术细节对比

(1) 存储单元结构
  • NOR Flash :

    存储单元并联,支持直接通过地址访问任意位置,类似 RAM,适合执行代码(XIP, Execute-In-Place)。

    plaintext 复制代码
    +---+---+---+---+
    | C | C | C | C |  → 并联结构
    +---+---+---+---+
  • NAND Flash :

    存储单元串联,以页(Page)和块(Block)为单位操作,适合顺序读写。

    plaintext 复制代码
    +-+-+-+-+-+-+-+-+
    |C-C-C-C-C-C-C-C|  → 串联结构
    +-+-+-+-+-+-+-+-+
(2) 应用场景
  • NOR Flash

    • 嵌入式系统启动代码(如 STM32 的代码存储)。
    • 网络设备的固件存储。
    • 实时性要求高的场景(如汽车 ECU)。
  • NAND Flash

    • 消费电子数据存储(手机、相机、平板)。
    • 大容量存储设备(SSD、U盘、存储卡)。
    • 需要频繁擦写的场景(需配合磨损均衡算法)。
(3) 可靠性要求
  • NOR Flash

    通常无需坏块管理(出厂坏块极少),ECC 要求低。

  • NAND Flash

    必须处理坏块(出厂时可能有坏块,使用中会新增),需硬件/软件 ECC 纠正位错误。


1.4总结

  • Flash 闪存是总称,包含 NOR 和 NAND 两种技术。
  • NAND Flash 是 Flash 的子集,因容量大、成本低,成为消费电子存储的绝对主流。
  • NOR Flash 在小容量、代码直接执行的场景不可替代。

因此,当人们提到"Flash 闪存"时,若未明确说明,通常默认指 NAND Flash;但在嵌入式开发或特定工业领域,"Flash"可能特指 NOR Flash,需结合上下文区分。

2.STM32内部的Flash

STM32 微控制器内部集成的 Flash 存储器属于 NOR Flash 类型。


2.1为什么是 NOR Flash?

  1. 支持 XIP(Execute-In-Place)

    • NOR Flash 允许 CPU 直接读取并执行代码(无需将代码复制到 RAM),因此 STM32 内部 Flash 被设计为 NOR 结构,用于存储程序代码和常量数据。
  2. 随机访问特性

    • 与 NAND Flash 的块操作不同,NOR Flash 支持按字节/字随机读取,满足代码执行对实时性和灵活性的需求。
  3. 可靠性与寿命

    • STM32 内部 Flash 的擦写次数通常为 1万~10万次(具体见芯片手册),且无需复杂的坏块管理(出厂时无坏块),符合 NOR Flash 的设计特点。

2.2STM32 内部 Flash 的关键特性

  • 容量范围:从几 KB(如 STM32F0)到几 MB(如 STM32H7),适合嵌入式代码存储。
  • 分块结构
    • 扇区(Sector):擦除操作按扇区进行(如 1KB、2KB、16KB 等,不同型号有差异)。
    • 页(Page):部分型号支持按页(如 256B)编程(写入)。
  • 访问速度
    • 零等待周期访问(与 CPU 主频匹配,需配置 Flash 加速器)。
  • 代码保护:支持写保护(WRP)、读保护(RDP)等功能。

2.3 与外部 NAND Flash 的对比

特性 STM32 内部 Flash(NOR) 外部 NAND Flash
用途 存储程序代码、常量数据 大容量数据存储(如图片、日志)
访问方式 直接寻址(XIP) 需通过控制器按页/块操作
擦写寿命 1万~10万次 1万~10万次(需磨损均衡)
坏块管理 无需(出厂无坏块) 必需(出厂可能有坏块)
容量 KB~MB 级 GB~TB 级
成本 较高(集成在芯片内) 较低(外置)

2.4 操作 STM32 内部 Flash 的注意事项

  1. 擦除与写入

    • 写操作前需先擦除(擦除单位为扇区),且只能将 1 写为 0,擦除会将整个扇区恢复为全 1。
    • 写入数据时需按对齐要求操作(如 32 位字写入)。
  2. 中断与代码执行

    • 在 Flash 擦写期间,CPU 可能暂停(取决于型号),需避免在关键实时任务中操作 Flash。
  3. 代码保护

    • 启用读保护后,Flash 内容无法通过调试接口读取,但需谨慎操作(错误配置可能导致芯片锁定)。
  4. 例程(基于 HAL 库)

    c 复制代码
    // 擦除扇区示例(以 STM32F4 为例)
    HAL_FLASH_Unlock(); // 解锁 Flash
    FLASH_Erase_Sector(FLASH_SECTOR_5, VOLTAGE_RANGE_3); // 擦除第5扇区
    HAL_FLASH_Lock(); // 重新锁定
    
    // 写入数据示例(32位字)
    uint32_t address = 0x08020000; // Flash 地址
    uint32_t data = 0x12345678;
    HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data);

2.5 常见问题

Q1:为什么 STM32 不集成 NAND Flash?
  • NAND Flash 需要复杂的控制器(坏块管理、ECC 等),会增加芯片成本和面积,且嵌入式系统通常只需中小容量代码存储,NOR Flash 更合适。
Q2:如何扩展 STM32 的存储容量?
  • 通过 FSMC/FMC 或 SPI 接口外接 NAND Flash (大容量数据)或 NOR Flash(代码扩展),但需自行实现驱动和文件系统。

3.读写NAND Flash的方法

读写 NAND Flash 的方法主要取决于其硬件接口和系统设计,而 SDIO 并不是直接操作 NAND Flash 的接口,但可以通过 SD 卡(内含 NAND Flash)间接使用。

3.1直接读写 NAND Flash 的方法

若直接操作 裸片 NAND Flash 芯片(如 K9F1G08U0D),常用以下方式:

1. 通过专用 NAND Flash 控制器
  • 适用场景
    • 需要高性能、低延迟的嵌入式系统(如工业设备、高端单片机)。
    • 微控制器(如 STM32)需内置 NAND Flash 控制器(如 STM32F4/F7/H7 的 FMC 模块)。
  • 硬件连接
    • 使用 8位或16位并行接口(地址线、数据线、控制信号)。
    • 需连接以下信号:
      • CE (片选)、WE (写使能)、RE (读使能)、ALE (地址锁存)、CLE (命令锁存)、R/B(就绪/忙)。
  • 软件实现
    • 通过微控制器的寄存器或 HAL 库直接发送命令、地址和数据。
    • 需实现 ECC 校验坏块管理磨损均衡等逻辑。
  • 优点
    • 直接控制,性能高。
  • 缺点
    • 硬件设计复杂(需较多引脚和 PCB 走线)。
    • 软件需自行处理 NAND Flash 的底层操作(擦除、编程、坏块替换)。
2. 通过 SPI 接口
  • 适用场景
    • 引脚资源紧张的微控制器(如 STM32F1)。
    • 小容量或低速 NAND Flash(如 W25N01GV)。
  • 硬件连接
    • 仅需 SPI 引脚(CLK、MOSI、MISO、CS)。
  • 软件实现
    • 通过 SPI 发送特定命令(如 Page ReadPage Program)。
    • 同样需处理 ECC 和坏块管理。
  • 优点
    • 硬件简单,占用引脚少。
  • 缺点
    • 速度较慢(SPI 速率通常 ≤ 50MHz)。
    • 支持的 NAND Flash 型号有限。

3.2间接读写 NAND Flash 的方法

若通过 封装好的存储设备(如 SD卡、eMMC)使用 NAND Flash,常用以下方式:

1. 通过 SDIO 接口读写 SD卡(内含 NAND Flash)
  • 适用场景
    • 需要即插即用、大容量存储的消费类设备(如相机、手持终端)。
    • 微控制器需支持 SDIO 协议(如 STM32F4/F7)。
  • 硬件连接
    • 连接 SD卡槽的 CLK、CMD、DAT0-DAT3 引脚。
  • 软件实现
    • 使用 SDIO 协议读写 SD卡(内部 NAND Flash 由 SD卡控制器管理)。
    • 无需关心底层 NAND Flash 操作(SD卡控制器自动处理坏块、ECC、磨损均衡)。
  • 优点
    • 开发简单,无需处理 NAND Flash 的复杂性。
    • 支持文件系统(如 FAT32)直接挂载。
  • 缺点
    • 受限于 SD卡性能(速度通常低于直接操作 NAND Flash)。
    • SD卡寿命较短(频繁擦写易损坏)。
2. 通过 eMMC/UFS 接口
  • 适用场景
    • 高性能嵌入式设备(如手机、平板)。
    • 需大容量、高可靠性的工业设备。
  • 硬件连接
    • eMMC:8位并行接口;UFS:高速串行接口。
  • 软件实现
    • 通过 eMMC/UFS 控制器访问存储,完全抽象底层 NAND Flash。
  • 优点
    • 高性能、高可靠性(内置高级闪存管理)。
  • 缺点
    • 硬件和协议复杂度高,通常需专用芯片支持。

3.3SDIO 与 NAND Flash 的关系

  • SDIO 不是直接操作 NAND Flash 的方法
    SDIO 是一种通信协议,用于连接 SD卡、WiFi模块等设备。
    • 当通过 SDIO 读写 SD卡 时,实际是操作 SD卡内部的 NAND Flash,但这一过程由 SD卡控制器完成,开发者无需关心 NAND Flash 的细节。
    • 若直接操作 裸片 NAND Flash,需使用其原生接口(如并行或 SPI),而非 SDIO。

3.4方法选择建议

需求场景 推荐方法 示例硬件
快速原型开发,需大容量存储 SDIO + SD卡 STM32F407 + 32GB SD卡
低成本、小容量存储 SPI接口 NAND Flash STM32F103 + W25N01GV
高性能、直接控制 并行接口 NAND Flash STM32H750 + MT29F4G08
高可靠性工业设备 eMMC/UFS i.MX6ULL + 64GB eMMC

3.5代码示例对比

1. 直接操作 NAND Flash(STM32 HAL 库)
c 复制代码
// 擦除块(Block 2)
NAND_AddressTypeDef addr;
addr.Block = 2;
addr.Page = 0;
HAL_NAND_Erase_Block(&hnand, &addr);

// 写入数据到页(Page 5)
uint8_t buffer[4096];
memset(buffer, 0x55, 4096); // 填充测试数据
HAL_NAND_Write_Page_8b(&hnand, &addr, buffer, 1);
2. 通过 SDIO 读写 SD卡(STM32 HAL 库)
c 复制代码
// 挂载 SD卡
FATFS fs;
f_mount(&fs, "", 1);

// 写入文件
FIL file;
f_open(&file, "data.txt", FA_WRITE | FA_CREATE_ALWAYS);
f_write(&file, "Hello, NAND Flash!", 17, NULL);
f_close(&file);

3.6关键问题解答

Q1:为什么不能直接用 SDIO 操作裸片 NAND Flash?
  • 协议不兼容:SDIO 是面向 SD卡设计的协议,而裸片 NAND Flash 需要遵循其原生命令集(如 Read ID、Page Program)。
  • 硬件差异:NAND Flash 无 SD卡控制器,无法响应 SDIO 命令。
Q2:如何选择直接操作 NAND Flash 还是用 SD卡?
  • 直接操作 NAND Flash
    • 适合对存储性能、寿命、成本要求高的定制化设备。
    • 需自行实现坏块管理和磨损均衡。
  • SD卡(SDIO)
    • 适合快速开发、无需关心底层细节的场景。
    • 受限于 SD卡寿命和速度。

3.7总结

  • 读写裸片 NAND Flash:需通过并行接口或 SPI,直接发送命令控制。
  • 间接读写 NAND Flash:通过 SDIO 操作 SD卡(内部含 NAND Flash),由 SD卡控制器管理底层细节。
  • SDIO 本身不是 NAND Flash 的读写方法,但可作为访问 SD卡(内含 NAND Flash)的桥梁。

根据项目需求选择合适方案:若追求开发便捷性,选 SD卡 + SDIO;若需深度优化存储性能,选直接操作 NAND Flash。

4. NAND Flash 基础

4.1 什么是 NAND Flash?

  • 非易失性存储器:断电后数据不丢失。
  • 存储结构 :由多个块(Block)组成,每个块包含多个页(Page)。例如:
    • 页大小:4KB(数据区) + 512B(备用区,用于ECC、坏块标记等)。
    • 块大小:128 页 → 512KB。
  • 特性
    • 顺序访问:适合大块数据读写,但随机访问慢。
    • 寿命有限:每个块有擦写次数限制(通常 1万~10万次)。
    • 坏块管理:出厂时可能存在坏块,使用中也可能产生新坏块。

4.2 NAND Flash 操作

  • 读操作:按页读取(直接读取数据)。
  • 写操作:按页编程(需先擦除块)。
  • 擦除操作:按块擦除(擦除后所有位变为1)。

4.3 关键问题

  • ECC(错误校正码):必须使用硬件或软件ECC检测和纠正位错误。
  • 磨损均衡:通过算法分散擦写操作,延长寿命。
  • 坏块管理:标记并跳过坏块,防止数据丢失。

坏块管理和磨损均衡是在 NAND Flash 存储器中常见的管理策略,用于延长存储器的寿命和提高可靠性。

坏块管理:

**1.坏块识别:**在 NAND Flash 制造过程中,由于工艺等原因,会产生一些不良块(坏块)。这些坏块无法正常读写,因此需要在使用前进行识别和标记。

**2.坏块映射:**识别后的坏块需要进行映射,通常会使用一个额外的坏块表(Bad Block Table)来记录坏块的位置,以便在文件系统或存储控制器中进行管理。

2.磨损均衡:

1.数据分布均衡 :尽量保持数据在存储器中的分布均匀,避免频繁写入同一块或同一组块,以减缓块的擦写速度,延长存储器寿命。

热点数据管理:管理可能形成的热点数据,减少对热点数据的访问次数,避免某些块的过度使用。

**2.块擦写次数平衡:**监测每个块的擦写次数,对擦写次数较高的块进行数据迁移操作,将数据迁移到擦写次数较低的块上,平衡块的使用状况。
3.擦除空闲块:及时回收已经擦除的空闲块,并确保它们在下一次写入操作时被合理地利用,减少特定块的过度使用。

这些管理策略通常由存储控制器、文件系统或专门的管理软件来实现。在设计系统时,需要考虑存储器的特性和应用场景,选择合适的管理策略,以达到最佳的均衡效果。


4.2 STM32 与 NAND Flash 的硬件连接

1. 接口方式

STM32 通过 FSMC(Flexible Static Memory Controller)FMC(Flexible Memory Controller,STM32F7/H7系列) 连接 NAND Flash,支持以下模式:

  • 8位或16位数据总线
  • 地址、命令、数据复用引脚
2.FMC介绍

FMC(Flexible Memory Controller,灵活存储控制器)STM32 微控制器中用于连接和管理外部存储器的高性能接口模块,尤其在中高端型号(如 STM32F4、STM32F7、STM32H7 系列)中广泛应用。它支持多种存储器和外设类型,是扩展 STM32 内存和功能的核心硬件资源。

1. FMC 的核心功能

FMC 通过灵活的配置,提供对多种外部存储器和外设的接口支持:

支持类型 说明
SRAM/PSRAM 静态随机存储器,用于高速数据缓存或扩展内存。
SDRAM 同步动态随机存储器,适合大容量、高带宽需求(如图像处理)。
NOR Flash 支持代码直接执行(XIP),用于存储固件或数据。
NAND Flash 大容量数据存储(需配合 ECC 和坏块管理)。
LCD 控制器 驱动 RGB 接口的 TFT-LCD 屏(部分型号支持)。
其他外设 通过总线扩展 FPGA、CPLD 等设备。

3. FMC 的优势

(1) 高性能接口

  • 总线宽度:支持 8位、16位、32位数据总线(取决于型号)。
  • 时钟速度:最高可达 100MHz+(如 STM32H7),提供高速数据传输。
  • 多存储体(Bank):通常支持 4~8 个独立存储体(Bank),可同时连接不同设备。

(2) 灵活的时序配置

  • 可独立设置每个存储体的时序参数(如地址建立时间、数据保持时间),适配不同存储器需求。

(3) 硬件加速

  • DMA 支持:减少 CPU 负载,提升数据传输效率。
  • ECC 校验:针对 NAND Flash 提供硬件错误检测与纠正。

4. FMC 与 FSMC 的区别

  • FSMC(Flexible Static Memory Controller)
    • 早期 STM32F1/F2/F4 系列中的模块,仅支持静态存储器(SRAM、NOR Flash)和 LCD 接口。
  • FMC
    • FSMC 的升级版,新增对 SDRAMNAND Flash 的支持,性能更高,功能更全面。
    • 在 STM32F7/H7 系列中取代 FSMC。

5. FMC 的典型应用场景

  1. 扩展内存
    • 使用 SDRAM 扩展系统内存(如 STM32H750 外接 32MB SDRAM)。
  2. 大容量存储
    • 通过 NAND Flash 存储日志、音视频数据(需文件系统支持)。
  3. 图形显示
    • 驱动高分辨率 TFT-LCD(如 800x480 RGB 屏)。
  4. 多设备协同
    • 同时连接 SRAM(高速缓存)、NOR Flash(代码存储)和 FPGA(逻辑扩展)。
3. 典型硬件连接

8位 NAND Flash(例如 K9F1G08U0D)为例:

  • 数据线:D0-D7 → 连接 STM32 的 FSMC_DATA[0:7]。
  • 控制信号
    • CE(Chip Enable) → FSMC_NCE。
    • WE(Write Enable) → FSMC_NWE。
    • RE(Read Enable) → FSMC_NOE。
    • ALE(Address Latch Enable) → FSMC_A[x](地址线复用)。
    • CLE(Command Latch Enable) → FSMC_A[y](地址线复用)。
    • R/B(Ready/Busy) → 通过 GPIO 检测状态。
4. 硬件设计注意事项
  • 上拉电阻:数据线需要上拉(通常 4.7kΩ)。
  • 信号完整性:高频信号需考虑走线长度匹配和干扰。
  • 电源滤波:确保 NAND Flash 供电稳定。

5. STM32 的 NAND Flash 驱动开发

5.1 使用 STM32 HAL 库

STM32Cube HAL 库提供了 NAND Flash 的底层驱动接口,需配置以下内容:

  • FSMC/FMC 初始化:设置时序参数(TAR、TCLR、TWHR 等)。
  • NAND Flash 属性:定义页大小、块大小、总容量等。
  • ECC 配置:启用硬件 ECC(如果支持)或软件 ECC。

5.2 关键代码步骤

c 复制代码
// 示例代码(基于 STM32 HAL 库)
#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_nand.h"

NAND_HandleTypeDef hnand;

void NAND_Init() {
  // 1. 配置 FSMC/FMC 时序
  FSMC_NAND_PCC_TimingTypeDef Timing;
  Timing.SetupTime = 2;
  Timing.WaitSetupTime = 3;
  Timing.HoldSetupTime = 2;
  Timing.HiZSetupTime = 1;

  // 2. 初始化 NAND Flash
  hnand.Instance = FSMC_NAND_DEVICE;
  hnand.Init.NandBank = FSMC_NAND_BANK3;
  hnand.Init.MemoryDataWidth = NAND_MEMORY_WIDTH_8B;
  hnand.Init.EccComputation = ECC_ENABLE; // 启用硬件ECC
  HAL_NAND_Init(&hnand, &Timing, &Timing);
}

// 3. 读页数据示例
HAL_StatusTypeDef ReadPage(uint32_t Block, uint32_t Page, uint8_t *pBuffer) {
  NAND_AddressTypeDef addr;
  addr.Block = Block;
  addr.Page = Page;
  addr.Plane = 0; // 单Plane设备
  return HAL_NAND_Read_Page_8b(&hnand, &addr, pBuffer, 1); // 读取1页
}

5.3 ECC 实现

  • 硬件 ECC:STM32 的 FSMC/FMC 支持硬件 ECC 生成和校验(需在初始化时启用)。
  • 软件 ECC:如使用 Hamming 码或 BCH 码,需自行实现算法。

6. 文件系统集成

直接在 NAND Flash 上存储数据需结合文件系统,常用方案:

6.1 FATFS(通用文件系统)

  • 特点:轻量级、兼容性强,但需自行实现底层驱动和坏块管理。
  • 集成步骤
    1. 移植 diskio.c,实现 NAND Flash 的读写接口。
    2. 添加坏块管理逻辑(例如:通过备用区标记坏块)。
    3. 启用 FF_USE_MKFS 格式化功能。

6.2 LittleFS 或 SPIFFS(嵌入式专用)

  • 特点:专为 Flash 设计,内置磨损均衡和坏块管理。
  • 优点:更适合频繁擦写的场景(如数据日志)。

6.3 UBIFS(Linux 系统)

  • 场景:STM32 运行 Linux 时使用,需要 MTD 驱动支持。

FTL(Flash Translation Layer,闪存转换层) 是介于 文件系统物理 NAND Flash 之间的一个中间层,负责解决 NAND Flash 的物理特性与文件系统逻辑需求之间的差异。其核心作用类似于"翻译官",将文件系统的逻辑操作(如读写文件)转换为 NAND Flash 支持的底层操作(如页编程、块擦除)。以下是详细解析:


7.FTL层

7.1为什么需要 FTL?

NAND Flash 的物理特性使其无法像传统硬盘一样直接使用,主要问题包括:

  1. 覆盖写入限制
    • NAND Flash 必须先擦除(Erase)整个块(Block)后才能写入(Program),而擦除操作耗时较长。
  2. 坏块管理
    • NAND Flash 出厂时可能存在坏块,使用中也会新增坏块,需动态标记和替换。
  3. 磨损均衡(Wear Leveling)
    • 每个块的擦写次数有限(约 1万~10万次),需均匀分布写入操作以延长寿命。
  4. 写入粒度不匹配
    • 文件系统通常以"扇区"(如 512B)为单位操作,而 NAND Flash 以"页"(如 4KB)为单位写入。

FTL 的作用正是解决这些问题,通过以下机制实现透明化管理:

  • 逻辑地址映射:将文件系统的逻辑地址动态映射到物理块/页。
  • 垃圾回收(Garbage Collection):合并碎片数据,释放无效块。
  • 磨损均衡算法:分散写入操作,避免局部块过早损坏。
  • 坏块替换:用预留的备用块替换失效块。

7.2使用 FTL 的场景

1. 必须使用 FTL 的情况

当直接通过 标准文件系统(如 FAT32、ext4) 操作 NAND Flash 时,必须依赖 FTL 层,因为:

  • 文件系统无法直接处理 NAND Flash 的擦除/编程限制。
  • 例如:在 SD卡、eMMC、SSD 中,FTL 由控制器硬件实现,开发者无需关心底层细节。
2. 可不用 FTL 的情况

在以下场景中,开发者可以直接操作 NAND Flash,无需 FTL:

  • 裸片 NAND Flash 管理:自行实现坏块表、磨损均衡和地址映射(常见于嵌入式系统)。
  • 专用存储方案:使用日志结构文件系统(如 JFFS2、UBIFS)或专为 Flash 设计的文件系统(如 LittleFS、SPIFFS),它们内置了类似 FTL 的功能。
  • 低复杂度场景:仅需顺序写入且寿命要求不高的应用(如一次性数据记录仪)。

7.3FTL 的典型实现方式

实现方式 说明 示例场景
硬件 FTL 由存储设备控制器(如 eMMC、SSD 主控)实现,对上层透明。 SD卡、U盘、固态硬盘
软件 FTL 通过软件库或文件系统实现(如嵌入式系统中的 FTL 算法)。 LittleFS、YAFFS
混合管理 结合硬件和软件协同处理(如 MCU 配合 NAND Flash 控制器)。 STM32 + 外部 NAND Flash 芯片

7.4使用 FTL 的优缺点

优点

  • 简化开发:文件系统可直接操作,无需处理 NAND Flash 的物理特性。
  • 提升寿命:通过磨损均衡延长存储设备使用寿命。
  • 兼容性:支持标准文件系统(如 FAT32)。

缺点

  • 性能开销:地址映射、垃圾回收等操作会增加延迟。
  • 资源占用:需额外的 RAM 存储映射表(尤其是大容量 Flash)。
  • 黑盒化:硬件 FTL 的实现细节不透明,难以深度优化。

7.5示例:使用 vs. 不使用 FTL

1. 使用 FTL(以 SD卡为例)
  • 硬件:STM32 + SD卡(内含 FTL 控制器)。

  • 软件 :直接调用 f_write() 写入文件,无需关心底层 NAND Flash。

  • 流程

    c 复制代码
    // FATFS 文件系统操作(隐藏 FTL)
    FIL file;
    f_open(&file, "data.txt", FA_WRITE);
    f_write(&file, buffer, sizeof(buffer), &bytes_written);
    f_close(&file);
2. 不使用 FTL(直接操作裸片 NAND Flash)
  • 硬件:STM32 + 并行 NAND Flash 芯片(如 MT29F4G08)。

  • 软件:自行管理坏块表和地址映射。

  • 流程

    c 复制代码
    // 1. 擦除块
    HAL_NAND_Erase_Block(&hnand, block_addr);
    
    // 2. 写入页数据(需跳过坏块)
    if (!is_bad_block(block_addr)) {
      HAL_NAND_Write_Page_8b(&hnand, &addr, data_buffer);
    }
    
    // 3. 更新坏块表
    if (write_failed) mark_bad_block(block_addr);

7.6如何选择是否使用 FTL?

需求 推荐方案 适用场景
快速开发,兼容标准文件系统 使用 FTL(如 SD卡) 消费电子产品、通用数据存储
深度优化,控制底层细节 不用 FTL(直接管理) 工业设备、高可靠性存储系统
中等复杂度,平衡性能与开发 软件 FTL(如 LittleFS) 嵌入式系统、IoT 设备

7.7常见问题

Q1:FTL 和文件系统有什么区别?
  • 文件系统:管理文件的逻辑结构(如目录、文件名)。
  • FTL:管理物理存储介质(如 NAND Flash)的底层操作,两者协同工作。
Q2:SSD 中的 FTL 是如何工作的?

SSD 主控芯片内置硬件 FTL,实现以下功能:

  • 将逻辑块地址(LBA)映射到物理页。
  • 执行垃圾回收和磨损均衡。
  • 使用 DRAM 缓存加速映射表访问。
Q3:自行实现 FTL 的难点是什么?
  • 映射表管理:大容量 Flash 需要高效存储和检索逻辑-物理地址映射。
  • 垃圾回收策略:需平衡性能与块擦除次数。
  • 异常处理:断电保护、坏块恢复等。

7.8直接操作 NAND Flash 的核心差异**

直接操作意味着绕过 FTL 的抽象层,开发者需要手动管理所有底层操作。以下是主要区别点:

操作内容 使用 FTL 直接操作 NAND Flash
地址管理 逻辑地址自动映射到物理地址 需自行维护逻辑-物理地址映射表
坏块处理 自动检测和替换坏块 需手动扫描坏块并维护坏块表
磨损均衡 自动分散擦写操作 需实现算法(如动态/静态均衡)
写入粒度 支持任意大小写入(如 512B 扇区) 必须按页(如 4KB)写入,擦除按块(如 128页)
垃圾回收 自动合并碎片空间 需手动标记无效数据并回收块
ECC 校验 自动完成(硬件或软件) 需自行生成和校验 ECC 码
开发复杂度 低(上层无需关心底层) 高(需实现全部管理逻辑)
性能控制 受限于 FTL 实现 可深度优化(如定制垃圾回收策略)

7.9直接操作 NAND Flash 的必备操作**

若选择直接操作,必须实现以下核心功能:

1. 坏块管理(Bad Block Management)
  • 出厂坏块:首次使用时扫描并记录所有坏块(通过读取出厂标记)。
  • 运行时坏块:在擦除或写入失败时动态标记新坏块,并将数据迁移到备用块。
  • 坏块表存储:通常将坏块表存储在固定位置(如 Block 0 的备用区),需冗余备份以防损坏。
2. 磨损均衡(Wear Leveling)
  • 动态均衡:将频繁写入的数据分配到不同物理块。
  • 静态均衡:定期迁移冷数据(不常修改的数据)到高磨损块。
  • 实现方法
    • 使用磨损计数表记录每个块的擦除次数。
    • 通过算法选择磨损最少的块进行写入。
3. ECC 校验(Error Correction Code)
  • 必要性:NAND Flash 存在位翻转(Bit Flip)风险,必须通过 ECC 纠正错误。
  • 实现方式
    • 硬件 ECC:利用微控制器内置的 ECC 模块(如 STM32 的 FMC)。
    • 软件 ECC:自行实现汉明码(Hamming Code)或 BCH 码。
  • 存储位置:ECC 码通常存储在页的备用区(Spare Area)。
4. 地址映射(Address Mapping)
  • 映射策略
    • 块级映射:以块为单位映射逻辑地址(简单但浪费空间)。
    • 页级映射:以页为单位映射(灵活但映射表占用更多 RAM)。
  • 映射表存储:需将映射表持久化到 NAND Flash 中,并在启动时加载到 RAM。
5. 垃圾回收(Garbage Collection)
  • 触发条件:当空闲块不足时启动。
  • 操作步骤
    1. 选择一个包含无效数据的块。
    2. 将有效数据迁移到新块。
    3. 擦除原块并标记为空闲。

7.3直接操作 vs. 使用 FTL 的典型场景

1. 适合直接操作的场景
  • 资源受限的嵌入式系统
    • 硬件无 FTL 控制器(如低成本 MCU)。
    • 存储容量较小(如 1GB 以下),管理逻辑可简化。
  • 高实时性要求
    • 需要绕过 FTL 的延迟(如工业控制中的高速数据采集)。
  • 定制化需求
    • 需优化存储策略(如特定数据类型的快速擦写)。
7.4适合使用 FTL 的场景
  • 快速开发
    • 使用 SD卡、eMMC 等内置 FTL 的设备。
  • 大容量存储
    • 避免自行管理海量地址映射和坏块(如 TB 级 SSD)。
  • 通用文件系统兼容性
    • 需挂载 FAT32、exFAT 等标准文件系统。

7.10关键挑战与解决方案

挑战 解决方案
断电保护 - 使用 UPS 或超级电容保证关键操作完成。 - 日志记录(Journaling)恢复中间状态。
映射表丢失 - 冗余存储映射表(多备份)。 - 启动时校验并修复损坏的映射表。
性能瓶颈 - 缓存频繁访问的映射表。 - 批量合并写入请求。
ECC 纠错能力不足 - 升级更强大的 ECC 算法(如 BCH 码)。 - 增加冗余校验位。

7.11总结

  • 可以不用 FTL:直接操作 NAND Flash 是可行的,但需实现坏块管理、磨损均衡、ECC 等核心功能。
  • 区别的核心:直接操作需要开发者承担所有底层复杂性,而 FTL 将其封装为透明服务。
  • 选择建议
    • 若追求开发效率 → 使用 FTL(如 SD卡、LittleFS)。
    • 若需极致控制或资源受限 → 直接操作 + 自定义管理逻辑。

直接操作 NAND Flash 是嵌入式开发中的高级课题,适合对存储性能、成本和可靠性有严格要求的场景,但需充分评估开发成本和风险。

8. 示例项目:STM32 + NAND Flash 数据记录仪

代码部分建议观看正点原子的nand flash部分的源码

8.1 硬件配置

  • MCU:STM32F429(带 FMC 接口)。
  • NAND Flash:MT29F4G08ABADA(4Gb,8位总线)。

8.2 NAND FLASH基本驱动步骤


8. 3常见问题与调试

1. 初始化失败
  • 检查时序参数:时序过短可能导致通信失败。
  • 确认电压电平:NAND Flash 是否为 3.3V 供电。
2. 读写错误
  • ECC 配置:确保硬件或软件 ECC 正确启用。
  • 坏块处理:检查是否未跳过已标记的坏块。
3. 文件系统挂载失败
  • 格式化 Flash :首次使用需调用 lfs_format
  • 电源干扰:确保复位期间 Flash 未断电。

总结

  • NAND Flash + STM32 是实现大容量存储的经典方案,需重点关注 接口驱动、坏块管理、ECC 和文件系统
  • 对于复杂应用,建议使用成熟的嵌入式文件系统(如 LittleFS)以减少开发难度。
  • STM32CubeMX 可快速生成 FSMC/FMC 初始化代码,结合 HAL 库加速开发。
相关推荐
Hz12138259 分钟前
STM32_USB
stm32·单片机·嵌入式硬件
阿波c麻了7 小时前
第十五届单片机模拟考试II
单片机·嵌入式硬件
charlie1145141917 小时前
STM32F103C8T6单片机的起始点:使用GPIO输出点亮我们的第一个小灯(HAL库版本)
stm32·单片机·嵌入式硬件·学习·教程·hal库·gpio
niuTaylor10 小时前
大学生机器人比赛实战(三)经验篇
单片机·嵌入式硬件·机器人
promising-w13 小时前
【TI MSPM0】UART学习
嵌入式硬件·学习·ti 单片机
damo王14 小时前
单片机实现多线程的方法汇总
单片机·嵌入式硬件
月阳羊15 小时前
【无人机】PX4 飞控系统架构
嵌入式硬件·系统架构·无人机
基极向上的三极管15 小时前
【51单片机】3-3【定时器/计数器/中断】超声波测距模块测距
单片机·嵌入式硬件·51单片机
LXL_2415 小时前
一、STM32简介
笔记·stm32·嵌入式硬件