ESP32 分开烧录和合并烧录地址简要说明
- 📍ESP32 引导加载程序 (Bootloader)介绍:
https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-guides/bootloader.html
ESP32 工程项目编译成功后,默认会生成最终的三个烧录文件:
bootloader.bin
、partition-table.bin
、APP.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
:0x1000partition-table.bin
:0x8000hello_world.bin
:0x10000
- 通过 flash_download_tool,分开烧录,地址分配界面:
- 合并烧录
合并烧录是指,将项目工程编译生成的最终的三个烧录文件:
bootloader.bin
、partition-table.bin
、APP.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
)