跳到主要内容

分区表

重要提示:关于开发板的兼容性

本教程的核心逻辑适用于所有 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分区大小(字节,支持 KM 后缀)
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_0ota_1 (各 1 MB):两个 OTA 应用程序备份。升级时新固件写入空闲的那个,下次启动从新分区运行;失败可回滚到另一个。

这张表共需 ≈ 3.2 MB,Flash 至少 4 MB

3. 切换分区表

  1. 点击 VS Code SDK 配置编辑器图标 打开 SDK 配置编辑器,左侧列表选择 Partition Table

    找到 menuconfig 分区表选项

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

    选择 menuconfig 分区表选项

    • 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(自定义,见下节)
  3. 选择好后点击 "保存" 按钮。下次构建时会按新分区表重新生成 binary,烧录时一并写入。

    备注

    切换分区表后,相关的 Flash 区段可能需要全部擦除一次idf.py erase-flash 然后 idf.py flash)。否则旧分区表残留可能让 bootloader 找不到新分区。

4. 自定义分区表

当预定义表都不够用时(例如:应用程序 > 1.5 MB、需要在 Flash 上挂载 SPIFFS / LittleFS 文件系统、要保留一段自定义数据区等),可以自己写一份 CSV。

操作步骤:

  1. 在工程根目录下新建一份 partitions.csv,仿照预定义表写自己的分区。例如把 app 区扩到 2 MB、再留 1 MB 给 SPIFFS:

    # Name, Type, SubType, Offset, Size, Flags
    nvs, data, nvs, 0x9000, 0x6000,
    phy_init, data, phy, 0xf000, 0x1000,
    factory, app, factory, 0x10000, 2M,
    storage, data, spiffs, , 1M,

    Offset 留空时由工具自动计算并对齐。

  2. 在 SDK 配置编辑器中打开 Partition Table,将 Partition Table 下拉菜单切到 Custom partition table CSV,下方 Custom partition CSV file 路径填 partitions.csv(相对工程根目录)。

    自定义 CSV 路径配置

  3. 检查 Flash 大小:在 SDK 配置编辑器左侧选 Serial flasher config,把 Flash size 设为不小于所有分区总和的容量,且不得超过开发板实际的 Flash 容量(ESP32-S3-Zero 板载 Flash 为 4 MB,即选 4 MB)。最后点击 "保存" 按钮。

    Flash size 配置

  4. 构建烧录。打开 ESP-IDF 终端,输入 idf.py partition-table 命令打印当前生效的分区表,确认无误。

    *******************************************
    # ESP-IDF Partition Table
    # Name, Type, SubType, Offset, Size, Flags
    nvs,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,加一行 spiffsfat 子类型的 data 分区
启动后偶现 "partition not found"切换分区表后忘记 idf.py erase-flash;擦除一次重新烧录

6. 参考链接