ESP32 分开烧录和合并烧录地址简要说明

发布于:2025-07-06 ⋅ 阅读:(27) ⋅ 点赞:(0)

ESP32 分开烧录和合并烧录地址简要说明


  • 📍ESP32 引导加载程序 (Bootloader)介绍:https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-guides/bootloader.html

ESP32 工程项目编译成功后,默认会生成最终的三个烧录文件:bootloader.binpartition-table.binAPP.bin,前2个二进制bin文件,会在项目编译开始时,最先生成,后者则是在编译完成100%,成功后生成最终的二进制文件。

  • ESP32的二级引导加载程序位于 flash 的 0x1000 偏移地址处。
  • 基于使用espidf默认bootloader和的自带分区表:esp-idf-v5.4\components\partition_table,如果使用自定义的bootloader程序,比自带的容量大,那分区表的偏移地址可能就不一样了。

📑分开烧录和合并烧录的地址逻辑

1. 分开烧录时的地址逻辑

当分开烧录(逐个烧录bootloader.bin、partition_table.bin、app.bin)时:

  • 每个文件独立烧录到指定地址:
  • bootloader.bin → 0x1000
  • partition_table.bin → 0x8000
  • app.bin → 0x10000
  • 工具行为:
    esptool.py会直接将每个文件的内容写入Flash的物理偏移地址,无需关心文件内部是否包含地址信息。
d:\ESP32\tools\python_env\idf5.4_py3.11_env\Scripts\python.exe d:\ESP32\ESPidf\v5.4\esp-idf\components\esptool_py\esptool\esptool.py -p COM30 -b 460800 --before default_reset --after hard_reset --chip esp32 write_flash --flash_mode dio --flash_freq 80m --flash_size 16MB 0x1000 bootloader/bootloader.bin 0x10000 hello_world.bin 0x8000 partition_table/partition-table.bin
2. 合并后的bin文件烧录逻辑

当将多个文件合并为单个merged.bin时:

  • 文件内部隐含地址信息:
    合并后的文件是一个连续的二进制流,但每个组件的原始偏移量(如bootloader在0x1000)会被记录在文件内部(通过填充空白数据实现对齐)。
  • 例如:merged.bin的结构如下:
0x0000 ~ 0x0FFF: 空白(全0xFF或填充数据)  
0x1000 ~ 0x7FFF: bootloader.bin  
0x8000 ~ 0xFFFF: partition_table.bin  
0x10000 ~ ... : app.bin  
  • 烧录地址从0x0开始的原因:
    • esptool.py在烧录合并文件时,会解析文件内部的偏移量,自动将内容写入对应的Flash地址。
    • 如果从0x1000开始烧录合并文件,会导致bootloader被错误地写入0x2000(0x1000 + 0x1000),破坏地址对齐。
  • 合并时在0x0~0x1000之间填充空白(或未使用数据),确保bootloader.bin在文件内的偏移量为0x1000,从而烧录后能对齐到Flash的0x1000地址。

场景 文件类型 烧录地址 工具行为
分开烧录 独立文件(如bootloader.bin 指定地址(如0x1000 直接写入指定地址,工具不解析文件内部结构,按用户输入的地址精确写入。
合并烧录 包含填充的连续二进制文件(如merged.bin 0x0 工具自动解析文件内的隐含偏移量(如0x1000处为bootloader),按原始组件地址分发到对应Flash位置。
  • 分开烧录命令:
d:\ESP32\tools\python_env\idf5.4_py3.11_env\Scripts\python.exe d:\ESP32\ESPidf\v5.4\esp-idf\components\esptool_py\esptool\esptool.py -p COM30 -b 460800 --before default_reset --after hard_reset --chip esp32 write_flash --flash_mode dio --flash_freq 80m --flash_size 16MB 0x1000 bootloader/bootloader.bin 0x10000 hello_world.bin 0x8000 partition_table/partition-table.bin
  • bootloader.bin:0x1000
  • partition-table.bin:0x8000
  • hello_world.bin:0x10000
  • 通过 flash_download_tool,分开烧录,地址分配界面:
    在这里插入图片描述
  • 合并烧录

合并烧录是指,将项目工程编译生成的最终的三个烧录文件:bootloader.binpartition-table.binAPP.bin,通过esptool打包生成为一个bin文件。

# 合并烧录示例
esptool.py write_flash 0x0 merged.bin
  • 通过 flash_download_tool,合并bin文件烧录,地址0x0000界面:
    在这里插入图片描述

验证合并后bin文件数据

验证bootloader.bin合并后的文件数据,是在合并文件merged.bin地址的0x1000位置,使用 hexdump命令查看两者二进制文件:
在这里插入图片描述

C:\Users\Administrator\Desktop\flash_download_tool_3.9.5>hexdump -C -n 32 bootloader.bin
00000000  e9 04 02 4f 58 06 08 40  ee 00 00 00 00 00 00 00  |...OX..@........|
00000010  00 8f 01 00 00 00 00 01  30 00 ff 3f c0 19 00 00  |........0..?....|
00000020

C:\Users\Administrator\Desktop\flash_download_tool_3.9.5>hexdump -C -s 0x1000 -n 32 target.bin
00001000  e9 04 02 4f 58 06 08 40  ee 00 00 00 00 00 00 00  |...OX..@........|
00001010  00 8f 01 00 00 00 00 01  30 00 ff 3f c0 19 00 00  |........0..?....|
00001020

📄默认烧录地址(基于ESP-IDF标准分区表)

分区表(如partitions.csv)定义了外部Flash的逻辑划分,每个分区的偏移量和大小决定了其在Flash中的物理地址。

组件 烧录地址(Flash物理偏移量) 大小(示例) 说明
Bootloader 0x1000 ~28KB 二级引导程序,由芯片的BootROM(Internal ROM)加载。
Partition Table 0x8000 3KB 分区表本身,描述所有分区的布局(必须与代码中的分区表定义一致)。
APP(Factory) 0x10000 1MB+ 主应用程序固件(如factory分区),具体大小由分区表定义。

📗合并文件方法

  • 🛠通过 flash_download_tool,合并bin文件:(输出的合并文件在flash_download_tool_3.9.5\combine文件夹内)
    在这里插入图片描述
  • CombineBin 按钮:可将 Download Path Config 中选中的多个固件打包成一
    个固件。若使能 DoNotChgBin,则按原始固件打包。若不使能DoNotChgBin,则按界面 SPI SPEED、SPI MODE 配置打包固件。固件之间非数据区,会以 0xff 进行填充。打包的固件将保存为 ./combine/target.bin
    每次点击覆盖前次。
  • 🔧🔨使用 esptool.py 工具的 merge_bin 功能进行手动合并。
  • 📍esptool.cmds.merge_bin介绍: https://docs.espressif.com/projects/esptool/en/latest/esp32/esptool/scripting.html?highlight=merge_bin#esptool.cmds.merge_bin

merge_bin 命令将会合并多个bin文件为一个bin文件,多个bin文件中间间隔的部分将会使用0xFF进行填充。命令如下:

esptool.py --chip ESP32 merge_bin -o merged.bin --flash_mode dio --flash_size 16MB 0x1000 bootloader.bin 0x8000 partition-table.bin 0x10000 app.bin
  • 🔧手动使用esptool命令合并bin文件操作:
C:\Users\Administrator\Desktop\flash_download_tool_3.9.5>esptool --chip ESP32 merge_bin -o merged.bin --flash_mode dio --flash_size 16MB 0x1000 bootloader.bin 0x8000 partition-table.bin 0x10000 hello_world.bin
esptool.py v4.8.1
SHA digest in image updated
Wrote 0x3c380 bytes to file merged.bin, ready to flash to offset 0x0

在这里插入图片描述

所生成的合并文件merged.bin在当前命令提示符窗口定位文件夹位置C:\Users\Administrator\Desktop\flash_download_tool_3.9.5>目录下。

  • 🌿在espidf 项目中添加自动合并文件,编译成功后自动生成合并文件:(在项目的 main/CMakeLists.txt)中添加以下代码:)

# 定义合并后的输出文件名
set(MERGED_BIN "${CMAKE_BINARY_DIR}/merged.bin")
set(BOOTLOADER_BIN "${CMAKE_BINARY_DIR}/bootloader/bootloader.bin")  
set(PARTITION_TABLE_BIN "${CMAKE_BINARY_DIR}/partition_table/partition-table.bin")
set(APP_BIN "${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.bin")  # 通常是 build/hello_world.bin

# 添加自定义目标,在编译完成后自动合并
add_custom_target(
    merge_bin ALL
    DEPENDS ${APP_BIN} ${BOOTLOADER_BIN} ${PARTITION_TABLE_BIN}
    COMMAND ${Python3_EXECUTABLE} ${IDF_PATH}/components/esptool_py/esptool/esptool.py
        --chip ${IDF_TARGET}
        merge_bin
        --output ${MERGED_BIN}
        --flash_mode ${CONFIG_ESPTOOLPY_FLASHMODE}
        --flash_size ${CONFIG_ESPTOOLPY_FLASHSIZE}
        0x1000 ${BOOTLOADER_BIN}
        0x8000 ${PARTITION_TABLE_BIN}
        0x10000 ${APP_BIN}
    COMMENT "Merging binaries into ${MERGED_BIN}"
)

📜espressif各芯片型号二级引导加载程序 flash 地址差异

  • esp32 存放在 flash 的 0x1000 偏移地址处的二进制镜像就是二级引导加载程序。(https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-guides/startup.html)
  • ESP32C3引导加载程序位于 flash 的 0x0 偏移地址处。(详细介绍见:https://docs.espressif.com/projects/esp-idf/zh_CN/v4.4.2/esp32c3/api-guides/bootloader.html#id9)
  • ESP32S3 二级引导加载程序位于 flash 的 0x0 偏移地址处。(https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32s3/api-guides/bootloader.html)
  • esp32s2 二级引导加载程序位于 flash 的 0x1000 偏移地址处。(https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32s2/api-guides/bootloader.html)
  • esp32c6 二级引导加载程序位于 flash 的 0x0 偏移地址处。
  • esp32H2 二级引导加载程序位于 flash 的 0x0 偏移地址处。
  • esp32p4存放在 flash 的 0x2000 偏移地址处的二进制镜像就是二级引导加载程序。(https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32p4/api-guides/startup.html