24
24
25
25
# Extends: https://github.com/platformio/platform-espressif32/blob/develop/builder/main.py
26
26
27
- from os .path import abspath , isdir , isfile , join
27
+ from os .path import abspath , basename , isdir , isfile , join
28
28
29
29
from SCons .Script import DefaultEnvironment , SConscript
30
30
31
31
env = DefaultEnvironment ()
32
32
platform = env .PioPlatform ()
33
33
board_config = env .BoardConfig ()
34
34
build_mcu = board_config .get ("build.mcu" , "" ).lower ()
35
+ partitions_name = board_config .get (
36
+ "build.partitions" , board_config .get ("build.arduino.partitions" , "" )
37
+ )
35
38
36
39
FRAMEWORK_DIR = platform .get_package_dir ("framework-arduinoespressif32" )
37
40
assert isdir (FRAMEWORK_DIR )
41
44
# Helpers
42
45
#
43
46
47
+
44
48
def get_partition_table_csv (variants_dir ):
45
49
fwpartitions_dir = join (FRAMEWORK_DIR , "tools" , "partitions" )
50
+ variant_partitions_dir = join (variants_dir , board_config .get ("build.variant" , "" ))
46
51
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 )
50
56
51
- if custom_partition :
52
- partitions_csv = board_config .get ("build.partitions" , board_config .get (
53
- "build.arduino.partitions" , "default.csv" ))
54
57
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
58
61
)
59
62
60
- variant_partitions = join (
61
- variants_dir , board_config .get ("build.variant" , "" ), "partitions.csv"
62
- )
63
+ variant_partitions = join (variant_partitions_dir , "partitions.csv" )
63
64
return (
64
65
variant_partitions
65
66
if isfile (variant_partitions )
@@ -68,9 +69,16 @@ def get_partition_table_csv(variants_dir):
68
69
69
70
70
71
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
+
71
76
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 ),
73
80
)
81
+
74
82
return (
75
83
variant_bootloader
76
84
if isfile (variant_bootloader )
@@ -85,6 +93,76 @@ def get_bootloader_image(variants_dir):
85
93
)
86
94
87
95
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
+
88
166
#
89
167
# Run target-specific script to populate the environment with proper build flags
90
168
#
@@ -99,32 +177,6 @@ def get_bootloader_image(variants_dir):
99
177
)
100
178
)
101
179
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
-
128
180
#
129
181
# Target: Build Core Library
130
182
#
@@ -137,23 +189,68 @@ def get_bootloader_image(variants_dir):
137
189
variants_dir = join ("$PROJECT_DIR" , board_config .get ("build.variants_dir" ))
138
190
139
191
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" ))])
145
193
env .BuildSources (
146
194
join ("$BUILD_DIR" , "FrameworkArduinoVariant" ),
147
- join (variants_dir , board_config .get ("build.variant" ))
195
+ join (variants_dir , board_config .get ("build.variant" )),
148
196
)
149
197
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
+ )
154
204
155
205
env .Prepend (LIBS = libs )
156
206
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
+
157
254
#
158
255
# Generate partition table
159
256
#
0 commit comments