@@ -160,6 +160,18 @@ def __fetch_fs_size(target, source, env):
160
160
return (target , source )
161
161
162
162
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
+
163
175
env = DefaultEnvironment ()
164
176
platform = env .PioPlatform ()
165
177
board = env .BoardConfig ()
@@ -169,6 +181,21 @@ def __fetch_fs_size(target, source, env):
169
181
if mcu == "esp32c3" :
170
182
toolchain_arch = "riscv32-esp"
171
183
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
+
172
199
if "INTEGRATION_EXTRA_DATA" not in env :
173
200
env ["INTEGRATION_EXTRA_DATA" ] = {}
174
201
@@ -264,6 +291,10 @@ def __fetch_fs_size(target, source, env):
264
291
source_factory = env .Dir ,
265
292
suffix = ".bin" ,
266
293
),
294
+ MergeBin = Builder (
295
+ generator = merge_binaries ,
296
+ suffix = ".bin" ,
297
+ ),
267
298
)
268
299
)
269
300
@@ -275,6 +306,7 @@ def __fetch_fs_size(target, source, env):
275
306
#
276
307
277
308
target_elf = None
309
+ target_firm_merged = None
278
310
if "nobuild" in COMMAND_LINE_TARGETS :
279
311
target_elf = join ("$BUILD_DIR" , "${PROGNAME}.elf" )
280
312
if set (["uploadfs" , "uploadfsota" ]) & set (COMMAND_LINE_TARGETS ):
@@ -293,6 +325,14 @@ def __fetch_fs_size(target, source, env):
293
325
else :
294
326
target_firm = env .ElfToBin (
295
327
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 )
296
336
env .Depends (target_firm , "checkprogsize" )
297
337
298
338
env .AddPlatformTarget ("buildfs" , target_firm , target_firm , "Build Filesystem Image" )
@@ -430,6 +470,10 @@ def __fetch_fs_size(target, source, env):
430
470
431
471
432
472
elif 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
433
477
openocd_args = ["-d%d" % (2 if int (ARGUMENTS .get ("PIOVERBOSE" , 0 )) else 1 )]
434
478
openocd_args .extend (
435
479
debug_tools .get (upload_protocol ).get ("server" ).get ("arguments" , []))
@@ -442,11 +486,14 @@ def __fetch_fs_size(target, source, env):
442
486
% (
443
487
"$FS_START"
444
488
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
+ )
446
493
),
447
494
]
448
495
)
449
- if "uploadfs" not in COMMAND_LINE_TARGETS :
496
+ if "uploadfs" not in COMMAND_LINE_TARGETS and not firmware_merge_required :
450
497
for image in env .get ("FLASH_EXTRA_IMAGES" , []):
451
498
openocd_args .extend (
452
499
[
0 commit comments