分区表
本教程的核心逻辑适用于所有 ESP32 开发板,但所有操作步骤均以 微雪 ESP32-S3-Zero 迷你开发板 为例进行讲解。如果您使用其他型号的开发板,请根据实际情况修改相应设置。
1. 分区表是什么
ESP32 的外部 Flash 通常包含多个用途不同的区块:引导加载程序 (bootloader)、应用程序代码 (app)、Wi-Fi 校准数据 (phy_init)、键值存储 (nvs)、(可选的)OTA 升级备份等。这些区块的位置和大小由一张叫做分区表 (partition table) 的数据结构描述。
分区表占用 Flash 中一个 4 KB 扇区,在 ESP32-S3 上默认烧录于偏移地址 0x8000 处。系统启动时,bootloader 会先读取分区表,得到各分区的位置,然后跳转到 app 分区执行代码。
每个分区由以下字段描述:
| 字段 | 含义 |
|---|---|
| Name | 分区名(最长 16 字节,便于识别) |
| Type | 分区类型:app(程序)、data(数据) |
| SubType | 子类型:如 factory / ota_0 / nvs / phy 等 |
| Offset | 在 Flash 中的偏移地址 |
| Size | 分区大小(字节,支持 K、M 后缀) |
| Flags | 可选标志,如 encrypted |
2. 默认分区表
ESP-IDF 自带几张预定义分区表,新建项目默认使用最简单的一张 "Single factory app, no OTA":
# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x6000,
phy_init, data, phy, 0xf000, 0x1000,
factory, app, factory, 0x10000, 1M,
含义:
nvs(24 KB,0x9000 起):键值存储,Wi-Fi 配置、用户参数等都放在这里。phy_init(4 KB,0xf000 起):射频校准数据。factory(1 MB,0x10000 起):你的应用程序代码。bootloader 默认会执行这个分区里的程序。
这张表适合 2 MB 及以上 Flash、不需要 OTA 的入门场景,覆盖绝大多数学习项目。
另一张常用的预定义表是 "Factory app, two OTA definitions":
# Name, Type, SubType, Offset, Size,
nvs, data, nvs, 0x9000, 0x4000,
otadata, data, ota, 0xd000, 0x2000,
phy_init, data, phy, 0xf000, 0x1000,
factory, app, factory, 0x10000, 1M,
ota_0, app, ota_0, 0x110000, 1M,
ota_1, app, ota_1, 0x210000, 1M,
比上一张多出了:
otadata(8 KB):记录"当前在跑哪个 OTA 分区"。ota_0和ota_1(各 1 MB):两个 OTA 应用程序备份。升级时新固件写入空闲的那个,下次启动从新分区运行;失败可回滚到另一个。
这张表共需 ≈ 3.2 MB,Flash 至少 4 MB。
3. 切换分区表
-
点击
打开 SDK 配置编辑器,左侧列表选择 Partition Table:

-
右侧 Partition Table 下拉菜单中包含:

Single factory app, no OTA(默认)Single factory app (large), no OTA(app 区扩到 1.5 MB)Factory app, two OTA definitions(启用 OTA)Two large size OTA partitions(无 factory,仅两个 1700 KB OTA 区)Custom partition table CSV(自定义,见下节)
-
选择好后点击 "保存" 按钮。下次构建时会按新分区表重新生成 binary,烧录时一并写入。
备注切换分区表后,相关的 Flash 区段可能需要全部擦除一次(
idf.py erase-flash然后idf.py flash)。否则旧分区表残留可能让 bootloader 找不到新分区。
4. 自定义分区表
当预定义表都不够用时(例如:应用程序 > 1.5 MB、需要在 Flash 上挂载 SPIFFS / LittleFS 文件系统、要保留一段自定义数据区等),可以自己写一份 CSV。
操作步骤:
-
在工程根目录下新建一份
partitions.csv,仿照预定义表写自己的分区。例如把 app 区扩到 2 MB、再留 1 MB 给 SPIFFS:# Name, Type, SubType, Offset, Size, Flagsnvs, data, nvs, 0x9000, 0x6000,phy_init, data, phy, 0xf000, 0x1000,factory, app, factory, 0x10000, 2M,storage, data, spiffs, , 1M,Offset留空时由工具自动计算并对齐。 -
在 SDK 配置编辑器中打开 Partition Table,将 Partition Table 下拉菜单切到
Custom partition table CSV,下方 Custom partition CSV file 路径填partitions.csv(相对工程根目录)。
-
检查 Flash 大小:在 SDK 配置编辑器左侧选 Serial flasher config,把 Flash size 设为不小于所有分区总和的容量,且不得超过开发板实际的 Flash 容量(ESP32-S3-Zero 板载 Flash 为 4 MB,即选
4 MB)。最后点击 "保存" 按钮。
-
构建烧录。打开 ESP-IDF 终端,输入
idf.py partition-table命令打印当前生效的分区表,确认无误。*******************************************# ESP-IDF Partition Table# Name, Type, SubType, Offset, Size, Flagsnvs,data,nvs,0x9000,24K,phy_init,data,phy,0xf000,4K,factory,app,factory,0x10000,2M,storage,data,spiffs,0x210000,1M,*******************************************
5. 常见场景
| 场景 | 处理方式 |
|---|---|
| 应用程序烧不进默认 1 MB 分区 | 改用 "Single factory app (large)" 或自定义表把 factory 扩大 |
| 需要在线 OTA 升级 | 改用 "Factory app, two OTA definitions",把 Flash 配置改成 ≥ 4 MB Flash |
| 想在 Flash 上挂文件系统 | 自定义 CSV,加一行 spiffs 或 fat 子类型的 data 分区 |
| 启动后偶现 "partition not found" | 切换分区表后忘记 idf.py erase-flash;擦除一次重新烧录 |
6. 参考链接
- ESP-IDF 编程指南 - 分区表 — 字段语义、所有预定义表的对照、加密 NVS 变体
- ESP-IDF 编程指南 - OTA — 配合 OTA 分区使用的 API
esp_partitionAPI — 代码中按名称/类型查找分区、读写 Flash 区段