开始前适用开发板:ESP32 系列 · 开发框架:ESP-IDF
文档类型:ESP-IDF 通用 API 教程,不绑定单一开发板。
板级例程见 热门例程详解。
学习时长:约 20 分钟 · 难度:★★☆☆☆
延伸:工程结构 · NVS 教程
学习目标
完成本节后,你将能够:
- 理解 Flash 分区表的作用——为什么需要把 Flash 切成多块
- 读懂
partitions.csv文件中每一列的含义 - 根据项目需求自定义分区表(OTA、文件系统、大 app 等)
- 排查常见的"空间不足"编译错误
分区表简介
一句话理解:分区表就是 Flash 的"地图"——告诉系统这块 Flash(比如 4MB/8MB/16MB)的每一段分别存什么东西。
生活类比:把 Flash 想象成一块硬盘,分区表就是你装系统时做的"磁盘分区"——C 盘装系统(app),D 盘存文件(SPIFFS),E 盘做备份(OTA)。
Flash 物理存储(示例 4MB):
┌────────────┬──────┬────────┬──────────┬──────────┬──────────┐
│ Bootloader │ 分区 │ NVS │ PHY │ App │ SPIFFS │
│ (二级引导) │ 表 │ 键值存储│ 校准数据 │ 你的程序 │ 文件系统 │
│ 0x0000 │ 0x8000│ 0x9000│ 0xF000 │ 0x10000 │ │
└────────────┴──────┴────────┴──────────┴──────────┴──────────┘
分区表定义了 ESP32 系列芯片 Flash 存储器的使用方式,指定了不同区域的大小、起始位置和用途。默认的分区表位于项目的 partitions.csv 文件中。
分区表格式
分区表使用 CSV 格式,每行定义一个分区。基本格式如下:
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x4000,
otadata, data, ota, 0xd000, 0x2000,
phy_init, data, phy, 0xf000, 0x1000,
factory, app, factory, 0x10000, 1M,
各字段含义:
- Name: 分区名称,最长 16 字节
- Type: 分区类型(app 或 data)
- SubType: 分区子类型
- Offset: 分区起始地址(可选)
- Size: 分区大小
- Flags: 分区标志(可选)
常见分区类型
1. app 类型分区
- factory: 出厂应用程序
- ota_0/ota_1: OTA 更新分区
- test: 测试程序分区
2. data 类型分区
- nvs: 非易失性存储,用于保存键值对
- phy_init: PHY 初始化数据
- coredump: 存储崩溃转储数据
- spiffs/fat: 文件系统分区
修改分区表
1. 创建自定义分区表
在项目根目录创建 partitions.csv 文件:
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x6000,
phy_init, data, phy, 0xf000, 0x1000,
factory, app, factory, 0x10000, 1M,
storage, data, spiffs, , 0x200000,
2. 常见分区配置示例
基本配置(单 app 无 OTA)
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x4000,
phy_init, data, phy, 0xf000, 0x1000,
factory, app, factory, 0x10000, 1M,
双 OTA 配置
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x4000,
otadata, data, ota, 0xd000, 0x2000,
phy_init, data, phy, 0xf000, 0x1000,
ota_0, app, ota_0, 0x10000, 1M,
ota_1, app, ota_1, 0x110000, 1M,
带文件系统配置
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x4000,
phy_init, data, phy, 0xf000, 0x1000,
factory, app, factory, 0x10000, 1M,
storage, data, spiffs, , 0x200000,
通过 menuconfig 配置
- 打开 menuconfig:
idf.py menuconfig
-
进入分区表配置:
- 选择
Partition Table菜单 - 可以配置以下选项:
- 分区表文件位置
- 分区表格式(CSV 或二进制)
- 分区表偏移地址
- 选择
-
常见配置选项:
Factory app partition size: 出厂应用程序分区大小OTA app partition size: OTA 应用程序分区大小Flash size: Flash 大小设置
常见问题与解决方案
1. 分区大小不足
症状:编译时提示 "partition table does not fit flash size"
解决方法:
- 减小应用程序大小
- 优化分区配置
- 使用更大容量的 Flash
2. OTA 更新失败
症状:OTA 更新时提示空间不足
解决方法:
- 增加 OTA 分区大小
- 检查分区表配置是否正确
- 确保有足够的备份分区
3. NVS 写入失败
症状:NVS 写入操作返回错误
解决方法:
- 增加 NVS 分区大小
- 清理不必要的 NVS 数据
- 检查 NVS 分区配置
分区大小计算
1. 最小分区要求
- nvs: 至少 0x3000 字节
- phy_init: 固定 0x1000 字节
- factory/ota: 根据应用大小,通常至少 1M
2. 常见分区大小
- 4MB Flash 典型分配:
- nvs: 16KB (0x4000)
- phy_init: 4KB (0x1000)
- factory: 1MB (0x100000)
- storage: 剩余空间
3. 对齐要求
- 所有分区必须 4KB 对齐
- Offset 可以设为空,系统会自动计算
最佳实践
-
备份分区表:
- 保存一份当前工作的分区表配置
- 记录修改历史
-
预留空间:
- 为将来的功能预留足够空间
- 考虑 OTA 更新需求
-
定期检查:
- 监控分区使用情况
- 及时调整分区大小
-
文档记录:
- 记录分区用途
- 记录特殊配置要求
动手练习
- 查看当前分区表:在任意工程执行
idf.py partition-table,对照 CSV 文件理解输出 - 扩大 SPIFFS:修改
partitions.csv,把 SPIFFS 从 1MB 增大到 2MB,观察编译结果 - 添加 OTA:将单 app 分区表改为双 OTA,理解为什么需要
otadata分区 - 空间计算:计算你的 Flash 容量(
menuconfig→ Flash size),验证所有分区大小之和不超过总容量
例程中的典型分区表
| 例程 | 分区特点 | 说明 |
|---|---|---|
| hello_world | 单 factory | 最简单 |
| mp3_player | factory + SPIFFS | SPIFFS 存 MP3 文件 |
| ota | 双 OTA(ota_0 + ota_1) | 空中升级需要两个 app 分区 |
| face_recognition | factory + SPIFFS(大) | SPIFFS 存人脸特征库 |
参考资料
酷世DIY · Kevincoooool