Skip to content

Commit 382df0d

Browse files
authored
Merge branch 'espressif:master' into master
2 parents 1a9c389 + 074f315 commit 382df0d

File tree

1 file changed

+147
-50
lines changed

1 file changed

+147
-50
lines changed

Diff for: tools/platformio-build.py

+147-50
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,17 @@
2424

2525
# Extends: https://github.com/platformio/platform-espressif32/blob/develop/builder/main.py
2626

27-
from os.path import abspath, isdir, isfile, join
27+
from os.path import abspath, basename, isdir, isfile, join
2828

2929
from SCons.Script import DefaultEnvironment, SConscript
3030

3131
env = DefaultEnvironment()
3232
platform = env.PioPlatform()
3333
board_config = env.BoardConfig()
3434
build_mcu = board_config.get("build.mcu", "").lower()
35+
partitions_name = board_config.get(
36+
"build.partitions", board_config.get("build.arduino.partitions", "")
37+
)
3538

3639
FRAMEWORK_DIR = platform.get_package_dir("framework-arduinoespressif32")
3740
assert isdir(FRAMEWORK_DIR)
@@ -41,25 +44,23 @@
4144
# Helpers
4245
#
4346

47+
4448
def get_partition_table_csv(variants_dir):
4549
fwpartitions_dir = join(FRAMEWORK_DIR, "tools", "partitions")
50+
variant_partitions_dir = join(variants_dir, board_config.get("build.variant", ""))
4651

47-
custom_partition = board_config.get(
48-
"build.partitions", board_config.get("build.arduino.partitions", "")
49-
)
52+
if partitions_name:
53+
# A custom partitions file is selected
54+
if isfile(join(variant_partitions_dir, partitions_name)):
55+
return join(variant_partitions_dir, partitions_name)
5056

51-
if custom_partition:
52-
partitions_csv = board_config.get("build.partitions", board_config.get(
53-
"build.arduino.partitions", "default.csv"))
5457
return abspath(
55-
join(fwpartitions_dir, partitions_csv)
56-
if isfile(join(fwpartitions_dir, partitions_csv))
57-
else partitions_csv
58+
join(fwpartitions_dir, partitions_name)
59+
if isfile(join(fwpartitions_dir, partitions_name))
60+
else partitions_name
5861
)
5962

60-
variant_partitions = join(
61-
variants_dir, board_config.get("build.variant", ""), "partitions.csv"
62-
)
63+
variant_partitions = join(variant_partitions_dir, "partitions.csv")
6364
return (
6465
variant_partitions
6566
if isfile(variant_partitions)
@@ -68,9 +69,16 @@ def get_partition_table_csv(variants_dir):
6869

6970

7071
def get_bootloader_image(variants_dir):
72+
bootloader_image_file = "bootloader.bin"
73+
if partitions_name.endswith("tinyuf2.csv"):
74+
bootloader_image_file = "bootloader-tinyuf2.bin"
75+
7176
variant_bootloader = join(
72-
variants_dir, board_config.get("build.variant", ""), "bootloader.bin"
77+
variants_dir,
78+
board_config.get("build.variant", ""),
79+
board_config.get("build.arduino.custom_bootloader", bootloader_image_file),
7380
)
81+
7482
return (
7583
variant_bootloader
7684
if isfile(variant_bootloader)
@@ -85,6 +93,76 @@ def get_bootloader_image(variants_dir):
8593
)
8694

8795

96+
def get_patched_bootloader_image(original_bootloader_image, bootloader_offset):
97+
patched_bootloader_image = join(env.subst("$BUILD_DIR"), "patched_bootloader.bin")
98+
bootloader_cmd = env.Command(
99+
patched_bootloader_image,
100+
original_bootloader_image,
101+
env.VerboseAction(
102+
" ".join(
103+
[
104+
'"$PYTHONEXE"',
105+
join(
106+
platform.get_package_dir("tool-esptoolpy") or "", "esptool.py"
107+
),
108+
"--chip",
109+
build_mcu,
110+
"merge_bin",
111+
"-o",
112+
"$TARGET",
113+
"--flash_mode",
114+
"${__get_board_flash_mode(__env__)}",
115+
"--flash_size",
116+
board_config.get("upload.flash_size", "4MB"),
117+
"--target-offset",
118+
bootloader_offset,
119+
bootloader_offset,
120+
"$SOURCE",
121+
]
122+
),
123+
"Updating bootloader headers",
124+
),
125+
)
126+
env.Depends("$BUILD_DIR/$PROGNAME$PROGSUFFIX", bootloader_cmd)
127+
128+
return patched_bootloader_image
129+
130+
131+
def add_tinyuf2_extra_image():
132+
tinuf2_image = board_config.get(
133+
"upload.arduino.tinyuf2_image",
134+
join(variants_dir, board_config.get("build.variant", ""), "tinyuf2.bin"),
135+
)
136+
137+
# Add the UF2 image only if it exists and it's not already added
138+
if not isfile(tinuf2_image):
139+
print("Warning! The `%s` UF2 bootloader image doesn't exist" % tinuf2_image)
140+
return
141+
142+
if any(
143+
"tinyuf2.bin" == basename(extra_image[1])
144+
for extra_image in env.get("FLASH_EXTRA_IMAGES", [])
145+
):
146+
print("Warning! An extra UF2 bootloader image is already added!")
147+
return
148+
149+
env.Append(
150+
FLASH_EXTRA_IMAGES=[
151+
(
152+
board_config.get(
153+
"upload.arduino.uf2_bootloader_offset",
154+
(
155+
"0x2d0000"
156+
if env.subst("$BOARD").startswith("adafruit")
157+
else "0x410000"
158+
),
159+
),
160+
tinuf2_image,
161+
),
162+
]
163+
)
164+
165+
88166
#
89167
# Run target-specific script to populate the environment with proper build flags
90168
#
@@ -99,32 +177,6 @@ def get_bootloader_image(variants_dir):
99177
)
100178
)
101179

102-
#
103-
# Process framework extra images
104-
#
105-
106-
env.Append(
107-
LIBSOURCE_DIRS=[
108-
join(FRAMEWORK_DIR, "libraries")
109-
],
110-
111-
FLASH_EXTRA_IMAGES=[
112-
(
113-
"0x1000" if build_mcu in ("esp32", "esp32s2") else "0x0000",
114-
get_bootloader_image(board_config.get(
115-
"build.variants_dir", join(FRAMEWORK_DIR, "variants")))
116-
),
117-
("0x8000", join(env.subst("$BUILD_DIR"), "partitions.bin")),
118-
("0xe000", join(FRAMEWORK_DIR, "tools", "partitions", "boot_app0.bin"))
119-
]
120-
+ [
121-
(offset, join(FRAMEWORK_DIR, img))
122-
for offset, img in board_config.get(
123-
"upload.arduino.flash_extra_images", []
124-
)
125-
],
126-
)
127-
128180
#
129181
# Target: Build Core Library
130182
#
@@ -137,23 +189,68 @@ def get_bootloader_image(variants_dir):
137189
variants_dir = join("$PROJECT_DIR", board_config.get("build.variants_dir"))
138190

139191
if "build.variant" in board_config:
140-
env.Append(
141-
CPPPATH=[
142-
join(variants_dir, board_config.get("build.variant"))
143-
]
144-
)
192+
env.Append(CPPPATH=[join(variants_dir, board_config.get("build.variant"))])
145193
env.BuildSources(
146194
join("$BUILD_DIR", "FrameworkArduinoVariant"),
147-
join(variants_dir, board_config.get("build.variant"))
195+
join(variants_dir, board_config.get("build.variant")),
148196
)
149197

150-
libs.append(env.BuildLibrary(
151-
join("$BUILD_DIR", "FrameworkArduino"),
152-
join(FRAMEWORK_DIR, "cores", board_config.get("build.core"))
153-
))
198+
libs.append(
199+
env.BuildLibrary(
200+
join("$BUILD_DIR", "FrameworkArduino"),
201+
join(FRAMEWORK_DIR, "cores", board_config.get("build.core")),
202+
)
203+
)
154204

155205
env.Prepend(LIBS=libs)
156206

207+
#
208+
# Process framework extra images
209+
#
210+
211+
# Starting with v2.0.4 the Arduino core contains updated bootloader images that have
212+
# innacurate default headers. This results in bootloops if firmware is flashed via
213+
# OpenOCD (e.g. debugging or uploading via debug tools). For this reason, before
214+
# uploading or debugging we need to adjust the bootloader binary according to
215+
# the values of the --flash-size and --flash-mode arguments.
216+
# Note: This behavior doesn't occur if uploading is done via esptoolpy, as esptoolpy
217+
# overrides the binary image headers before flashing.
218+
219+
bootloader_patch_required = bool(
220+
env.get("PIOFRAMEWORK", []) == ["arduino"]
221+
and (
222+
"debug" in env.GetBuildType()
223+
or env.subst("$UPLOAD_PROTOCOL") in board_config.get("debug.tools", {})
224+
or env.IsIntegrationDump()
225+
)
226+
)
227+
228+
bootloader_image_path = get_bootloader_image(variants_dir)
229+
bootloader_offset = "0x1000" if build_mcu in ("esp32", "esp32s2") else "0x0000"
230+
if bootloader_patch_required:
231+
bootloader_image_path = get_patched_bootloader_image(
232+
bootloader_image_path, bootloader_offset
233+
)
234+
235+
env.Append(
236+
LIBSOURCE_DIRS=[join(FRAMEWORK_DIR, "libraries")],
237+
FLASH_EXTRA_IMAGES=[
238+
(bootloader_offset, bootloader_image_path),
239+
("0x8000", join(env.subst("$BUILD_DIR"), "partitions.bin")),
240+
("0xe000", join(FRAMEWORK_DIR, "tools", "partitions", "boot_app0.bin")),
241+
]
242+
+ [
243+
(offset, join(FRAMEWORK_DIR, img))
244+
for offset, img in board_config.get("upload.arduino.flash_extra_images", [])
245+
],
246+
)
247+
248+
# Add an extra UF2 image if the 'TinyUF2' partition is selected
249+
if partitions_name.endswith("tinyuf2.csv") or board_config.get(
250+
"upload.arduino.tinyuf2_image", ""
251+
):
252+
add_tinyuf2_extra_image()
253+
157254
#
158255
# Generate partition table
159256
#

0 commit comments

Comments
 (0)