30
30
import zlib
31
31
import shlex
32
32
33
- __version__ = "2.0-beta1 "
33
+ __version__ = "2.0-beta2 "
34
34
35
35
MAX_UINT32 = 0xffffffff
36
36
MAX_UINT24 = 0xffffff
@@ -281,6 +281,62 @@ def sync(self):
281
281
for i in range (7 ):
282
282
self .command ()
283
283
284
+ def _connect_attempt (self , mode = 'default_reset' , esp32r0_delay = False ):
285
+ """ A single connection attempt, with esp32r0 workaround options """
286
+ # esp32r0_delay is a workaround for bugs with the most common auto reset
287
+ # circuit and Windows, if the EN pin on the dev board does not have
288
+ # enough capacitance.
289
+ #
290
+ # Newer dev boards shouldn't have this problem (higher value capacitor
291
+ # on the EN pin), and ESP32 revision 1 can't use this workaround as it
292
+ # relies on a silicon bug.
293
+ #
294
+ # Details: https://github.com/espressif/esptool/issues/136
295
+ last_error = None
296
+
297
+ # issue reset-to-bootloader:
298
+ # RTS = either CH_PD/EN or nRESET (both active low = chip in reset
299
+ # DTR = GPIO0 (active low = boot to flasher)
300
+ #
301
+ # DTR & RTS are active low signals,
302
+ # ie True = pin @ 0V, False = pin @ VCC.
303
+ if mode != 'no_reset' :
304
+ self ._port .setDTR (False ) # IO0=HIGH
305
+ self ._port .setRTS (True ) # EN=LOW, chip in reset
306
+ time .sleep (0.1 )
307
+ if esp32r0_delay :
308
+ # Some chips are more likely to trigger the esp32r0
309
+ # watchdog reset silicon bug if they're held with EN=LOW
310
+ # for a longer period
311
+ time .sleep (1.2 )
312
+ self ._port .setDTR (True ) # IO0=LOW
313
+ self ._port .setRTS (False ) # EN=HIGH, chip out of reset
314
+ if esp32r0_delay :
315
+ # Sleep longer after reset.
316
+ # This workaround only works on revision 0 ESP32 chips,
317
+ # it exploits a silicon bug spurious watchdog reset.
318
+ time .sleep (0.4 ) # allow watchdog reset to occur
319
+ time .sleep (0.05 )
320
+ self ._port .setDTR (False ) # IO0=HIGH, done
321
+
322
+ self ._port .timeout = 0.1
323
+ for _ in range (5 ):
324
+ try :
325
+ self .flush_input ()
326
+ self ._port .flushOutput ()
327
+ self .sync ()
328
+ self ._port .timeout = 5
329
+ return None
330
+ except FatalError as e :
331
+ if esp32r0_delay :
332
+ print ('_' , end = '' )
333
+ else :
334
+ print ('.' , end = '' )
335
+ sys .stdout .flush ()
336
+ time .sleep (0.05 )
337
+ last_error = e
338
+ return last_error
339
+
284
340
def connect (self , mode = 'default_reset' ):
285
341
""" Try connecting repeatedly until successful, or giving up """
286
342
print ('Connecting...' , end = '' )
@@ -289,44 +345,12 @@ def connect(self, mode='default_reset'):
289
345
290
346
try :
291
347
for _ in range (10 ):
292
- # issue reset-to-bootloader:
293
- # RTS = either CH_PD/EN or nRESET (both active low = chip in reset
294
- # DTR = GPIO0 (active low = boot to flasher)
295
- #
296
- # DTR & RTS are active low signals,
297
- # ie True = pin @ 0V, False = pin @ VCC.
298
- if mode != 'no_reset' :
299
- self ._port .setDTR (False ) # IO0=HIGH
300
- self ._port .setRTS (True ) # EN=LOW, chip in reset
301
- time .sleep (0.05 )
302
- self ._port .setDTR (True ) # IO0=LOW
303
- self ._port .setRTS (False ) # EN=HIGH, chip out of reset
304
- if mode == 'esp32r0' :
305
- # this is a workaround for a bug with the most
306
- # common auto reset circuit and Windows, if the EN
307
- # pin on the dev board does not have enough
308
- # capacitance. This workaround only works on
309
- # revision 0 ESP32 chips, it exploits a silicon
310
- # bug spurious watchdog reset.
311
- #
312
- # Details: https://github.com/espressif/esptool/issues/136
313
- time .sleep (0.4 ) # allow watchdog reset to occur
314
- time .sleep (0.05 )
315
- self ._port .setDTR (False ) # IO0=HIGH, done
316
-
317
- self ._port .timeout = 0.1
318
- for _ in range (4 ):
319
- try :
320
- self .flush_input ()
321
- self ._port .flushOutput ()
322
- self .sync ()
323
- self ._port .timeout = 5
324
- return
325
- except FatalError as e :
326
- print ('.' , end = '' )
327
- sys .stdout .flush ()
328
- time .sleep (0.05 )
329
- last_error = e
348
+ last_error = self ._connect_attempt (mode = mode , esp32r0_delay = False )
349
+ if last_error is None :
350
+ return
351
+ last_error = self ._connect_attempt (mode = mode , esp32r0_delay = True )
352
+ if last_error is None :
353
+ return
330
354
finally :
331
355
print ('' ) # end 'Connecting...' line
332
356
raise FatalError ('Failed to connect to %s: %s' % (self .CHIP_NAME , last_error ))
@@ -653,8 +677,7 @@ def set_data_lengths(mosi_bits, miso_bits):
653
677
if data_bits == 0 :
654
678
self .write_reg (SPI_W0_REG , 0 ) # clear data register before we read it
655
679
else :
656
- if len (data ) % 4 != 0 : # pad to 32-bit multiple
657
- data += b'\0 ' * (4 - (len (data ) % 4 ))
680
+ data = pad_to (data , 4 , b'\00 ' ) # pad to 32-bit multiple
658
681
words = struct .unpack ("I" * (len (data ) // 4 ), data )
659
682
next_reg = SPI_W0_REG
660
683
for word in words :
@@ -901,11 +924,11 @@ def chip_id(self):
901
924
902
925
def read_mac (self ):
903
926
""" Read MAC from EFUSE region """
904
- words = [self .read_efuse (1 ), self .read_efuse (2 )]
927
+ words = [self .read_efuse (2 ), self .read_efuse (1 )]
905
928
bitstring = struct .pack (">II" , * words )
906
- bitstring = bitstring [: 6 ] # trim 2 byte CRC
929
+ bitstring = bitstring [2 : 8 ] # trim the 2 byte CRC
907
930
try :
908
- return tuple (ord (b ) for b in bitstring ) # trim 2 byte CRC
931
+ return tuple (ord (b ) for b in bitstring )
909
932
except TypeError : # Python 3, bitstring elements are already bytes
910
933
return tuple (bitstring )
911
934
@@ -964,10 +987,7 @@ class ImageSegment(object):
964
987
def __init__ (self , addr , data , file_offs = None ):
965
988
self .addr = addr
966
989
# pad all ImageSegments to at least 4 bytes length
967
- pad_mod = len (data ) % 4
968
- if pad_mod != 0 :
969
- data += b"\x00 " * (4 - pad_mod )
970
- self .data = data
990
+ self .data = pad_to (data , 4 , b'\x00 ' )
971
991
self .file_offs = file_offs
972
992
self .include_in_checksum = True
973
993
@@ -1210,15 +1230,13 @@ def __init__(self, load_file=None):
1210
1230
self .flash_mode = 0
1211
1231
self .flash_size_freq = 0
1212
1232
self .version = 1
1213
- self .encrypt_flag = False
1214
1233
1215
1234
if load_file is not None :
1216
1235
segments = self .load_common_header (load_file , ESPLoader .ESP_IMAGE_MAGIC )
1217
1236
additional_header = list (struct .unpack ("B" * 16 , load_file .read (16 )))
1218
- self .encrypt_flag = (additional_header [0 ] == 0x01 )
1219
1237
1220
- # check remaining 14 bytes are unused
1221
- if additional_header [ 2 :] != [0 ] * 14 :
1238
+ # check these bytes are unused
1239
+ if additional_header != [0 ] * 16 :
1222
1240
print ("WARNING: ESP32 image header contains unknown flags. Possibly this image is from a newer version of esptool.py" )
1223
1241
1224
1242
for _ in range (segments ):
@@ -1241,9 +1259,9 @@ def save(self, filename):
1241
1259
with open (filename , 'wb' ) as f :
1242
1260
self .write_common_header (f , self .segments )
1243
1261
1244
- f . write ( b' \x01 ' if self . encrypt_flag else b' \x00 ' )
1245
- # remaining 15 bytes of header are unused
1246
- f .write (b'\x00 ' * 15 )
1262
+ # first 4 bytes of header are read by ROM bootloader for SPI
1263
+ # config, but currently unused
1264
+ f .write (b'\x00 ' * 16 )
1247
1265
1248
1266
checksum = ESPLoader .ESP_CHECKSUM_MAGIC
1249
1267
last_addr = None
@@ -1464,6 +1482,14 @@ def unhexify(hs):
1464
1482
return s
1465
1483
1466
1484
1485
+ def pad_to (data , alignment , pad_character = b'\xFF ' ):
1486
+ """ Pad to the next alignment boundary """
1487
+ pad_mod = len (data ) % alignment
1488
+ if pad_mod != 0 :
1489
+ data += pad_character * (alignment - pad_mod )
1490
+ return data
1491
+
1492
+
1467
1493
class FatalError (RuntimeError ):
1468
1494
"""
1469
1495
Wrapper class for runtime errors that aren't caused by internal bugs, but by
@@ -1590,7 +1616,7 @@ def write_flash(esp, args):
1590
1616
for address , argfile in args .addr_filename :
1591
1617
if args .no_stub :
1592
1618
print ('Erasing flash...' )
1593
- image = argfile .read ()
1619
+ image = pad_to ( argfile .read (), 4 )
1594
1620
image = _update_image_flash_params (esp , address , flash_params , image )
1595
1621
calcmd5 = hashlib .md5 (image ).hexdigest ()
1596
1622
uncsize = len (image )
@@ -1689,10 +1715,6 @@ def elf2image(args):
1689
1715
print ("Creating image for ESP8266..." )
1690
1716
args .chip == 'esp8266'
1691
1717
1692
- if args .chip != 'esp32' :
1693
- if args .set_encrypt_flag :
1694
- raise FatalError ("--encrypt-flag only applies to ESP32 images" )
1695
-
1696
1718
if args .chip == 'esp32' :
1697
1719
image = ESP32FirmwareImage ()
1698
1720
elif args .version == '1' : # ESP8266
@@ -1704,7 +1726,6 @@ def elf2image(args):
1704
1726
image .flash_mode = {'qio' :0 , 'qout' :1 , 'dio' :2 , 'dout' : 3 }[args .flash_mode ]
1705
1727
image .flash_size_freq = image .ROM_LOADER .FLASH_SIZES [args .flash_size ]
1706
1728
image .flash_size_freq += {'40m' :0 , '26m' :1 , '20m' :2 , '80m' : 0xf }[args .flash_freq ]
1707
- image .encrypt_flag = args .set_encrypt_flag
1708
1729
1709
1730
if args .output is None :
1710
1731
args .output = image .default_output_name (args .input )
@@ -1776,7 +1797,7 @@ def _verify_flash(esp, args):
1776
1797
flash_params = _get_flash_params (esp , args )
1777
1798
1778
1799
for address , argfile in args .addr_filename :
1779
- image = argfile .read ()
1800
+ image = pad_to ( argfile .read (), 4 )
1780
1801
argfile .seek (0 ) # rewind in case we need it again
1781
1802
1782
1803
image = _update_image_flash_params (esp , address , flash_params , image )
@@ -1853,7 +1874,7 @@ def main():
1853
1874
parser .add_argument (
1854
1875
'--before' ,
1855
1876
help = 'What to do before connecting to the chip' ,
1856
- choices = ['default_reset' , 'no_reset' , 'esp32r0' ],
1877
+ choices = ['default_reset' , 'no_reset' ],
1857
1878
default = os .environ .get ('ESPTOOL_BEFORE' , 'default_reset' ))
1858
1879
1859
1880
parser .add_argument (
@@ -1946,7 +1967,6 @@ def add_spi_flash_subparsers(parent, auto_detect=False):
1946
1967
parser_elf2image .add_argument ('input' , help = 'Input ELF file' )
1947
1968
parser_elf2image .add_argument ('--output' , '-o' , help = 'Output filename prefix (for version 1 image), or filename (for version 2 single image)' , type = str )
1948
1969
parser_elf2image .add_argument ('--version' , '-e' , help = 'Output image version' , choices = ['1' ,'2' ], default = '1' )
1949
- parser_elf2image .add_argument ('--set-encrypt-flag' , help = 'Flag image to be encrypted by bootloader after flashing.' , action = "store_true" )
1950
1970
1951
1971
add_spi_flash_subparsers (parser_elf2image )
1952
1972
@@ -2152,6 +2172,19 @@ def __call__(self, parser, namespace, values, option_string=None):
2152
2172
except IndexError :
2153
2173
raise argparse .ArgumentError (self ,'Must be pairs of an address and the binary filename to write there' )
2154
2174
pairs .append ((address , argfile ))
2175
+
2176
+ # Sort the addresses and check for overlapping
2177
+ end = 0
2178
+ for address , argfile in sorted (pairs ):
2179
+ argfile .seek (0 ,2 ) # seek to end
2180
+ size = argfile .tell ()
2181
+ argfile .seek (0 )
2182
+ sector_start = address & ~ (ESPLoader .FLASH_SECTOR_SIZE - 1 )
2183
+ sector_end = ((address + size + ESPLoader .FLASH_SECTOR_SIZE - 1 ) & ~ (ESPLoader .FLASH_SECTOR_SIZE - 1 )) - 1
2184
+ if sector_start < end :
2185
+ message = 'Detected overlap at address: 0x%x for file: %s' % (address , argfile .name )
2186
+ raise argparse .ArgumentError (self , message )
2187
+ end = sector_end
2155
2188
setattr (namespace , self .dest , pairs )
2156
2189
2157
2190
0 commit comments