Skip to content

Commit 049baaa

Browse files
peterdragunradimkarnis
authored andcommitted
feat(esptool): add option to dump whole flash based on detected size
Closes #461
1 parent f558f22 commit 049baaa

File tree

3 files changed

+41
-3
lines changed

3 files changed

+41
-3
lines changed

docs/en/esptool/basic-commands.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,14 @@ The read_flash command allows reading back the contents of flash. The arguments
105105

106106
esptool.py -p PORT -b 460800 read_flash 0 0x200000 flash_contents.bin
107107

108+
109+
It is also possible to autodetect flash size by using ``ALL`` as size. The above example with autodetection would look like this:
110+
111+
::
112+
113+
esptool.py -p PORT -b 460800 read_flash 0 ALL flash_contents.bin
114+
115+
108116
.. note::
109117

110118
If ``write_flash`` updated the boot image's :ref:`flash mode and flash size <flash-modes>` during flashing then these bytes may be different when read back.

esptool/__init__.py

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import traceback
4040

4141
from esptool.cmds import (
42+
DETECTED_FLASH_SIZES,
4243
chip_id,
4344
detect_chip,
4445
detect_flash_size,
@@ -526,7 +527,9 @@ def add_spi_flash_subparsers(parent, allow_keep, auto_detect):
526527
add_spi_connection_arg(parser_read_flash)
527528
parser_read_flash.add_argument("address", help="Start address", type=arg_auto_int)
528529
parser_read_flash.add_argument(
529-
"size", help="Size of region to dump", type=arg_auto_int
530+
"size",
531+
help="Size of region to dump. Use `ALL` to read to the end of flash.",
532+
type=arg_auto_size,
530533
)
531534
parser_read_flash.add_argument("filename", help="Name of binary dump")
532535
parser_read_flash.add_argument(
@@ -570,8 +573,9 @@ def add_spi_flash_subparsers(parent, allow_keep, auto_detect):
570573
)
571574
parser_erase_region.add_argument(
572575
"size",
573-
help="Size of region to erase (must be multiple of 4096)",
574-
type=arg_auto_int,
576+
help="Size of region to erase (must be multiple of 4096). "
577+
"Use `ALL` to erase to the end of flash.",
578+
type=arg_auto_size,
575579
)
576580

577581
parser_merge_bin = subparsers.add_parser(
@@ -827,6 +831,23 @@ def flash_xmc_startup():
827831
"than 16MB, in case of failure use --no-stub."
828832
)
829833

834+
if getattr(args, "size", "") == "all":
835+
if esp.secure_download_mode:
836+
raise FatalError(
837+
"Detecting flash size is not supported in secure download mode. "
838+
"Set an exact size value."
839+
)
840+
# detect flash size
841+
flash_id = esp.flash_id()
842+
size_id = flash_id >> 16
843+
size_str = DETECTED_FLASH_SIZES.get(size_id)
844+
if size_str is None:
845+
raise FatalError(
846+
"Detecting flash size failed. Set an exact size value."
847+
)
848+
print(f"Detected flash size: {size_str}")
849+
args.size = flash_size_bytes(size_str)
850+
830851
if esp.IS_STUB and hasattr(args, "address") and hasattr(args, "size"):
831852
if args.address + args.size > 0x1000000:
832853
print(
@@ -871,6 +892,11 @@ def arg_auto_int(x):
871892
return int(x, 0)
872893

873894

895+
def arg_auto_size(x):
896+
x = x.lower()
897+
return x if x == "all" else arg_auto_int(x)
898+
899+
874900
def get_port_list():
875901
if list_ports is None:
876902
raise FatalError(

test/test_esptool.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,10 @@ def test_region_erase(self):
776776
empty = self.readback(0x10000, 0x1000)
777777
assert empty == b"\xFF" * 0x1000
778778

779+
def test_region_erase_all(self):
780+
res = self.run_esptool("erase_region 0x0 ALL")
781+
assert re.search(r"Detected flash size: \d+[KM]B", res) is not None
782+
779783
def test_large_region_erase(self):
780784
# verifies that erasing a large region doesn't time out
781785
self.run_esptool("erase_region 0x0 0x100000")

0 commit comments

Comments
 (0)