@@ -160,6 +160,18 @@ def __fetch_fs_size(target, source, env):
160160 return (target , source )
161161
162162
163+ def merge_binaries (source , target , env , for_signature ):
164+ return " " .join ([
165+ '"$PYTHONEXE"' ,
166+ join (platform .get_package_dir ("tool-esptoolpy" ) or "" , "esptool.py" ),
167+ "--chip" , mcu , "merge_bin" ,
168+ "-o" , "$TARGET" ,
169+ "--flash_mode" , "$BOARD_FLASH_MODE" ,
170+ "--flash_size" , board .get ("upload.flash_size" , "detect" ),
171+ "$ESP32_APP_OFFSET" , "$SOURCES"
172+ ] + ['"%s"' % itm for img in env .get ("FLASH_EXTRA_IMAGES" , []) for itm in img ])
173+
174+
163175env = DefaultEnvironment ()
164176platform = env .PioPlatform ()
165177board = env .BoardConfig ()
@@ -169,6 +181,21 @@ def __fetch_fs_size(target, source, env):
169181if mcu == "esp32c3" :
170182 toolchain_arch = "riscv32-esp"
171183
184+ # Arduino core v2.0.4 contains updated bootloader images that have innacurate default
185+ # headers. This results in bootloops if firmware is flashed via OpenOCD (e.g. debugging
186+ # or uploading via debug tools). For this reason, before uploading or debugging we need
187+ # to merge binaries via esptoolpy so that the image headers will be adjusted according to
188+ # --flash-size and --flash-mode arguments.
189+ # Note: This behavior doesn't occur if uploading is done via esptoolpy, as esptoolpy
190+ # overrides the binary image headers before flashing.
191+ firmware_merge_required = bool (
192+ env .get ("PIOFRAMEWORK" , []) == ["arduino" ]
193+ and (
194+ "debug" in env .GetBuildType ()
195+ or env .subst ("$UPLOAD_PROTOCOL" ) in board .get ("debug.tools" , {})
196+ )
197+ )
198+
172199if "INTEGRATION_EXTRA_DATA" not in env :
173200 env ["INTEGRATION_EXTRA_DATA" ] = {}
174201
@@ -264,6 +291,10 @@ def __fetch_fs_size(target, source, env):
264291 source_factory = env .Dir ,
265292 suffix = ".bin" ,
266293 ),
294+ MergeBin = Builder (
295+ generator = merge_binaries ,
296+ suffix = ".bin" ,
297+ ),
267298 )
268299)
269300
@@ -275,6 +306,7 @@ def __fetch_fs_size(target, source, env):
275306#
276307
277308target_elf = None
309+ target_firm_merged = None
278310if "nobuild" in COMMAND_LINE_TARGETS :
279311 target_elf = join ("$BUILD_DIR" , "${PROGNAME}.elf" )
280312 if set (["uploadfs" , "uploadfsota" ]) & set (COMMAND_LINE_TARGETS ):
@@ -293,6 +325,14 @@ def __fetch_fs_size(target, source, env):
293325 else :
294326 target_firm = env .ElfToBin (
295327 join ("$BUILD_DIR" , "${PROGNAME}" ), target_elf )
328+ if firmware_merge_required :
329+ # Note: Default offset address must be set to 0x0 because debugging
330+ # relies on OpenOCD that requires merged firmware
331+ env ["INTEGRATION_EXTRA_DATA" ].update (
332+ {"application_offset" : "0x0" , "merged_firmware" : True }
333+ )
334+ target_firm_merged = env .MergeBin (join (
335+ "$BUILD_DIR" , "${PROGNAME}_merged" ), target_firm )
296336 env .Depends (target_firm , "checkprogsize" )
297337
298338env .AddPlatformTarget ("buildfs" , target_firm , target_firm , "Build Filesystem Image" )
@@ -430,6 +470,10 @@ def __fetch_fs_size(target, source, env):
430470
431471
432472elif upload_protocol in debug_tools :
473+ if firmware_merge_required :
474+ # Only merged firmware with proper headers will work when uploading is done via
475+ # debug probes. The firmware offset address must be adjusted to 0x0 accordingly.
476+ target_firm = target_firm_merged
433477 openocd_args = ["-d%d" % (2 if int (ARGUMENTS .get ("PIOVERBOSE" , 0 )) else 1 )]
434478 openocd_args .extend (
435479 debug_tools .get (upload_protocol ).get ("server" ).get ("arguments" , []))
@@ -442,11 +486,14 @@ def __fetch_fs_size(target, source, env):
442486 % (
443487 "$FS_START"
444488 if "uploadfs" in COMMAND_LINE_TARGETS
445- else "$ESP32_APP_OFFSET"
489+ else board .get (
490+ "upload.offset_address" ,
491+ "0x0" if firmware_merge_required else "$ESP32_APP_OFFSET"
492+ )
446493 ),
447494 ]
448495 )
449- if "uploadfs" not in COMMAND_LINE_TARGETS :
496+ if "uploadfs" not in COMMAND_LINE_TARGETS and not firmware_merge_required :
450497 for image in env .get ("FLASH_EXTRA_IMAGES" , []):
451498 openocd_args .extend (
452499 [
0 commit comments