17
17
import re
18
18
from os .path import join
19
19
20
+
20
21
from SCons .Script import (ARGUMENTS , COMMAND_LINE_TARGETS , AlwaysBuild ,
21
22
Builder , Default , DefaultEnvironment )
23
+ from platformio import util
22
24
23
-
24
- def _get_flash_size (env ):
25
- # use board's flash size by default
26
- board_max_size = int (env .BoardConfig ().get ("upload.maximum_size" , 0 ))
27
-
28
- # check if user overrides LD Script
29
- match = re .search (r"\.flash\.(\d+)(m|k).*\.ld" , env .GetActualLDScript ())
30
- if match :
31
- if match .group (2 ) == "k" :
32
- board_max_size = int (match .group (1 )) * 1024
33
- elif match .group (2 ) == "m" :
34
- board_max_size = int (match .group (1 )) * 1024 * 1024
35
-
36
- return ("%dK" % (board_max_size / 1024 ) if board_max_size < 1048576
37
- else "%dM" % (board_max_size / 1048576 ))
25
+ #
26
+ # Helpers
27
+ #
38
28
39
29
40
30
def _get_board_f_flash (env ):
@@ -43,6 +33,96 @@ def _get_board_f_flash(env):
43
33
return int (int (frequency ) / 1000000 )
44
34
45
35
36
+ def _parse_size (value ):
37
+ if isinstance (value , int ):
38
+ return value
39
+ elif value .isdigit ():
40
+ return int (value )
41
+ elif value .startswith ("0x" ):
42
+ return int (value , 16 )
43
+ elif value [- 1 ].upper () in ("K" , "M" ):
44
+ base = 1024 if value [- 1 ].upper () == "K" else 1024 * 1024
45
+ return int (value [:- 1 ]) * base
46
+ return value
47
+
48
+
49
+ @util .memoized ()
50
+ def _parse_ld_sizes (ldscript_path ):
51
+ assert ldscript_path
52
+ result = {}
53
+ # get flash size from board's manifest
54
+ result ['flash_size' ] = int (env .BoardConfig ().get ("upload.maximum_size" , 0 ))
55
+ # get flash size from LD script path
56
+ match = re .search (r"\.flash\.(\d+[mk]).*\.ld" , ldscript_path )
57
+ if match :
58
+ result ['flash_size' ] = _parse_size (match .group (1 ))
59
+
60
+ appsize_re = re .compile (
61
+ r"irom0_0_seg\s*:.+len\s*=\s*(0x[\da-f]+)" , flags = re .I )
62
+ spiffs_re = re .compile (
63
+ r"PROVIDE\s*\(\s*_SPIFFS_(\w+)\s*=\s*(0x[\da-f]+)\s*\)" , flags = re .I )
64
+ with open (ldscript_path ) as fp :
65
+ for line in fp .readlines ():
66
+ line = line .strip ()
67
+ if not line or line .startswith ("/*" ):
68
+ continue
69
+ match = appsize_re .search (line )
70
+ if match :
71
+ result ['app_size' ] = _parse_size (match .group (1 ))
72
+ continue
73
+ match = spiffs_re .search (line )
74
+ if match :
75
+ result ['spiffs_%s' % match .group (1 )] = _parse_size (
76
+ match .group (2 ))
77
+ return result
78
+
79
+
80
+ def _get_flash_size (env ):
81
+ ldsizes = _parse_ld_sizes (env .GetActualLDScript ())
82
+ if ldsizes ['flash_size' ] < 1048576 :
83
+ return "%dK" % (ldsizes ['flash_size' ] / 1024 )
84
+ return "%dM" % (ldsizes ['flash_size' ] / 1048576 )
85
+
86
+
87
+ def fetch_spiffs_size (env ):
88
+ ldsizes = _parse_ld_sizes (env .GetActualLDScript ())
89
+ for key in ldsizes :
90
+ if key .startswith ("spiffs_" ):
91
+ env [key .upper ()] = ldsizes [key ]
92
+
93
+ assert all ([
94
+ k in env
95
+ for k in ["SPIFFS_START" , "SPIFFS_END" , "SPIFFS_PAGE" , "SPIFFS_BLOCK" ]
96
+ ])
97
+
98
+ # esptool flash starts from 0
99
+ for k in ("SPIFFS_START" , "SPIFFS_END" ):
100
+ _value = 0
101
+ if env [k ] < 0x40300000 :
102
+ _value = env [k ] & 0xFFFFF
103
+ elif env [k ] < 0x411FB000 :
104
+ _value = env [k ] & 0xFFFFFF
105
+ _value -= 0x200000 # correction
106
+ else :
107
+ _value = env [k ] & 0xFFFFFF
108
+ _value += 0xE00000 # correction
109
+
110
+ env [k ] = _value
111
+
112
+
113
+ def __fetch_spiffs_size (target , source , env ):
114
+ fetch_spiffs_size (env )
115
+ return (target , source )
116
+
117
+
118
+ def _update_max_upload_size (env ):
119
+ ldsizes = _parse_ld_sizes (env .GetActualLDScript ())
120
+ if ldsizes and "app_size" in ldsizes :
121
+ env .BoardConfig ().update ("upload.maximum_size" , ldsizes ['app_size' ])
122
+
123
+
124
+ ########################################################
125
+
46
126
env = DefaultEnvironment ()
47
127
platform = env .PioPlatform ()
48
128
@@ -170,53 +250,15 @@ def _get_board_f_flash(env):
170
250
for f in env .get ("BUILD_FLAGS" , [])
171
251
])
172
252
173
- #
174
- # SPIFFS
175
- #
176
-
177
-
178
- def fetch_spiffs_size (env ):
179
- spiffs_re = re .compile (
180
- r"PROVIDE\s*\(\s*_SPIFFS_(\w+)\s*=\s*(0x[\dA-F]+)\s*\)" )
181
- with open (env .GetActualLDScript ()) as f :
182
- for line in f .readlines ():
183
- match = spiffs_re .search (line )
184
- if not match :
185
- continue
186
- env ["SPIFFS_%s" % match .group (1 ).upper ()] = match .group (2 )
187
-
188
- assert all ([k in env for k in ["SPIFFS_START" , "SPIFFS_END" , "SPIFFS_PAGE" ,
189
- "SPIFFS_BLOCK" ]])
190
-
191
- # esptool flash starts from 0
192
- for k in ("SPIFFS_START" , "SPIFFS_END" ):
193
- _value = 0
194
- if int (env [k ], 16 ) < 0x40300000 :
195
- _value = int (env [k ], 16 ) & 0xFFFFF
196
- elif int (env [k ], 16 ) < 0x411FB000 :
197
- _value = int (env [k ], 16 ) & 0xFFFFFF
198
- _value -= 0x200000 # correction
199
- else :
200
- _value = int (env [k ], 16 ) & 0xFFFFFF
201
- _value += 0xE00000 # correction
202
-
203
- env [k ] = hex (_value )
204
-
205
-
206
- def __fetch_spiffs_size (target , source , env ):
207
- fetch_spiffs_size (env )
208
- return (target , source )
209
-
210
-
211
253
env .Append (
212
254
BUILDERS = dict (
213
255
DataToBin = Builder (
214
256
action = env .VerboseAction (" " .join ([
215
257
'"$MKSPIFFSTOOL"' ,
216
258
"-c" , "$SOURCES" ,
217
- "-p" , "${int( SPIFFS_PAGE, 16)} " ,
218
- "-b" , "${int( SPIFFS_BLOCK, 16)} " ,
219
- "-s" , "${int( SPIFFS_END, 16) - int( SPIFFS_START, 16) }" ,
259
+ "-p" , "$SPIFFS_PAGE" ,
260
+ "-b" , "$SPIFFS_BLOCK" ,
261
+ "-s" , "${SPIFFS_END - SPIFFS_START}" ,
220
262
"$TARGET"
221
263
]), "Building SPIFFS image from '$SOURCES' directory to $TARGET" ),
222
264
emitter = __fetch_spiffs_size ,
@@ -388,6 +430,17 @@ def __fetch_spiffs_size(target, source, env):
388
430
AlwaysBuild (env .Alias ("nobuild" , target_firm ))
389
431
target_buildprog = env .Alias ("buildprog" , target_firm , target_firm )
390
432
433
+ # update max upload size based on CSV file
434
+ if env .get ("PIOMAINPROG" ):
435
+ env .AddPreAction (
436
+ "checkprogsize" ,
437
+ env .VerboseAction (
438
+ lambda source , target , env : _update_max_upload_size (env ),
439
+ "Retrieving maximum program size $SOURCE" ))
440
+ # remove after PIO Core 3.6 release
441
+ elif set (["checkprogsize" , "upload" ]) & set (COMMAND_LINE_TARGETS ):
442
+ _update_max_upload_size (env )
443
+
391
444
#
392
445
# Target: Print binary size
393
446
#
0 commit comments