Skip to content

Commit e0deeac

Browse files
committed
feat(erase_region): Enable erasing in ROM bootloader and SDM
1 parent 8298cdc commit e0deeac

File tree

3 files changed

+36
-9
lines changed

3 files changed

+36
-9
lines changed

esptool/cmds.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,12 +1151,27 @@ def erase_flash(esp, args):
11511151
"please use with caution, otherwise it may brick your device!"
11521152
)
11531153
print("Erasing flash (this may take a while)...")
1154+
if esp.CHIP_NAME != "ESP8266" and not esp.IS_STUB:
1155+
print(
1156+
"Note: You can use the erase_region command in ROM bootloader "
1157+
"mode to erase a specific region."
1158+
)
11541159
t = time.time()
11551160
esp.erase_flash()
1156-
print("Chip erase completed successfully in %.1fs" % (time.time() - t))
1161+
print(f"Chip erase completed successfully in {time.time() - t:.1f} seconds.")
11571162

11581163

11591164
def erase_region(esp, args):
1165+
if args.address % ESPLoader.FLASH_SECTOR_SIZE != 0:
1166+
raise FatalError(
1167+
"Offset to erase from must be a multiple "
1168+
f"of {ESPLoader.FLASH_SECTOR_SIZE}"
1169+
)
1170+
if args.size % ESPLoader.FLASH_SECTOR_SIZE != 0:
1171+
raise FatalError(
1172+
"Size of data to erase must be a multiple "
1173+
f"of {ESPLoader.FLASH_SECTOR_SIZE}"
1174+
)
11601175
if not args.force and esp.CHIP_NAME != "ESP8266" and not esp.secure_download_mode:
11611176
if esp.get_flash_encryption_enabled() or esp.get_secure_boot_enabled():
11621177
raise FatalError(
@@ -1167,8 +1182,12 @@ def erase_region(esp, args):
11671182
)
11681183
print("Erasing region (may be slow depending on size)...")
11691184
t = time.time()
1170-
esp.erase_region(args.address, args.size)
1171-
print("Erase completed successfully in %.1f seconds." % (time.time() - t))
1185+
if esp.CHIP_NAME != "ESP8266" and not esp.IS_STUB:
1186+
# flash_begin triggers a flash erase, enabling erasing in ROM and SDM
1187+
esp.flash_begin(args.size, args.address, logging=False)
1188+
else:
1189+
esp.erase_region(args.address, args.size)
1190+
print(f"Erase completed successfully in {time.time() - t:.1f} seconds.")
11721191

11731192

11741193
def run(esp, args):

esptool/loader.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -891,7 +891,7 @@ def mem_finish(self, entrypoint=0):
891891
raise
892892
pass
893893

894-
def flash_begin(self, size, offset, begin_rom_encrypted=False):
894+
def flash_begin(self, size, offset, begin_rom_encrypted=False, logging=True):
895895
"""
896896
Start downloading to Flash (performs an erase)
897897
@@ -916,7 +916,7 @@ def flash_begin(self, size, offset, begin_rom_encrypted=False):
916916
self.check_command(
917917
"enter Flash download mode", self.ESP_FLASH_BEGIN, params, timeout=timeout
918918
)
919-
if size != 0 and not self.IS_STUB:
919+
if size != 0 and not self.IS_STUB and logging:
920920
print("Took %.2fs to erase flash block" % (time.time() - t))
921921
return num_blocks
922922

@@ -1196,10 +1196,6 @@ def erase_flash(self):
11961196

11971197
@stub_function_only
11981198
def erase_region(self, offset, size):
1199-
if offset % self.FLASH_SECTOR_SIZE != 0:
1200-
raise FatalError("Offset to erase from must be a multiple of 4096")
1201-
if size % self.FLASH_SECTOR_SIZE != 0:
1202-
raise FatalError("Size of data to erase must be a multiple of 4096")
12031199
timeout = timeout_per_mb(ERASE_REGION_TIMEOUT_PER_MB, size)
12041200
self.check_command(
12051201
"erase region",

test/test_esptool.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,6 +1067,18 @@ def test_large_region_erase(self):
10671067
# verifies that erasing a large region doesn't time out
10681068
self.run_esptool("erase_region 0x0 0x100000")
10691069

1070+
@pytest.mark.skipif(arg_chip == "esp8266", reason="Not supported on ESP8266")
1071+
def test_region_erase_no_stub(self):
1072+
self.run_esptool("write_flash 0x10000 images/one_kb.bin")
1073+
self.run_esptool("write_flash 0x11000 images/sector.bin")
1074+
self.verify_readback(0x10000, 0x400, "images/one_kb.bin")
1075+
self.verify_readback(0x11000, 0x1000, "images/sector.bin")
1076+
# erase only the flash sector containing one_kb.bin
1077+
self.run_esptool("--no-stub erase_region 0x10000 0x1000")
1078+
self.verify_readback(0x11000, 0x1000, "images/sector.bin")
1079+
empty = self.readback(0x10000, 0x1000)
1080+
assert empty == b"\xFF" * 0x1000
1081+
10701082

10711083
class TestSectorBoundaries(EsptoolTestCase):
10721084
def test_end_sector(self):

0 commit comments

Comments
 (0)