mirror of
https://github.com/espressif/esptool.git
synced 2025-10-17 07:32:30 +08:00
feat(esptool): add option to dump whole flash based on detected size
Closes https://github.com/espressif/esptool/issues/461
This commit is contained in:

committed by
Radim Karniš

parent
f558f22974
commit
049baaa760
@@ -105,6 +105,14 @@ The read_flash command allows reading back the contents of flash. The arguments
|
|||||||
|
|
||||||
esptool.py -p PORT -b 460800 read_flash 0 0x200000 flash_contents.bin
|
esptool.py -p PORT -b 460800 read_flash 0 0x200000 flash_contents.bin
|
||||||
|
|
||||||
|
|
||||||
|
It is also possible to autodetect flash size by using ``ALL`` as size. The above example with autodetection would look like this:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
esptool.py -p PORT -b 460800 read_flash 0 ALL flash_contents.bin
|
||||||
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
@@ -39,6 +39,7 @@ import time
|
|||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from esptool.cmds import (
|
from esptool.cmds import (
|
||||||
|
DETECTED_FLASH_SIZES,
|
||||||
chip_id,
|
chip_id,
|
||||||
detect_chip,
|
detect_chip,
|
||||||
detect_flash_size,
|
detect_flash_size,
|
||||||
@@ -526,7 +527,9 @@ def main(argv=None, esp=None):
|
|||||||
add_spi_connection_arg(parser_read_flash)
|
add_spi_connection_arg(parser_read_flash)
|
||||||
parser_read_flash.add_argument("address", help="Start address", type=arg_auto_int)
|
parser_read_flash.add_argument("address", help="Start address", type=arg_auto_int)
|
||||||
parser_read_flash.add_argument(
|
parser_read_flash.add_argument(
|
||||||
"size", help="Size of region to dump", type=arg_auto_int
|
"size",
|
||||||
|
help="Size of region to dump. Use `ALL` to read to the end of flash.",
|
||||||
|
type=arg_auto_size,
|
||||||
)
|
)
|
||||||
parser_read_flash.add_argument("filename", help="Name of binary dump")
|
parser_read_flash.add_argument("filename", help="Name of binary dump")
|
||||||
parser_read_flash.add_argument(
|
parser_read_flash.add_argument(
|
||||||
@@ -570,8 +573,9 @@ def main(argv=None, esp=None):
|
|||||||
)
|
)
|
||||||
parser_erase_region.add_argument(
|
parser_erase_region.add_argument(
|
||||||
"size",
|
"size",
|
||||||
help="Size of region to erase (must be multiple of 4096)",
|
help="Size of region to erase (must be multiple of 4096). "
|
||||||
type=arg_auto_int,
|
"Use `ALL` to erase to the end of flash.",
|
||||||
|
type=arg_auto_size,
|
||||||
)
|
)
|
||||||
|
|
||||||
parser_merge_bin = subparsers.add_parser(
|
parser_merge_bin = subparsers.add_parser(
|
||||||
@@ -827,6 +831,23 @@ def main(argv=None, esp=None):
|
|||||||
"than 16MB, in case of failure use --no-stub."
|
"than 16MB, in case of failure use --no-stub."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if getattr(args, "size", "") == "all":
|
||||||
|
if esp.secure_download_mode:
|
||||||
|
raise FatalError(
|
||||||
|
"Detecting flash size is not supported in secure download mode. "
|
||||||
|
"Set an exact size value."
|
||||||
|
)
|
||||||
|
# detect flash size
|
||||||
|
flash_id = esp.flash_id()
|
||||||
|
size_id = flash_id >> 16
|
||||||
|
size_str = DETECTED_FLASH_SIZES.get(size_id)
|
||||||
|
if size_str is None:
|
||||||
|
raise FatalError(
|
||||||
|
"Detecting flash size failed. Set an exact size value."
|
||||||
|
)
|
||||||
|
print(f"Detected flash size: {size_str}")
|
||||||
|
args.size = flash_size_bytes(size_str)
|
||||||
|
|
||||||
if esp.IS_STUB and hasattr(args, "address") and hasattr(args, "size"):
|
if esp.IS_STUB and hasattr(args, "address") and hasattr(args, "size"):
|
||||||
if args.address + args.size > 0x1000000:
|
if args.address + args.size > 0x1000000:
|
||||||
print(
|
print(
|
||||||
@@ -871,6 +892,11 @@ def arg_auto_int(x):
|
|||||||
return int(x, 0)
|
return int(x, 0)
|
||||||
|
|
||||||
|
|
||||||
|
def arg_auto_size(x):
|
||||||
|
x = x.lower()
|
||||||
|
return x if x == "all" else arg_auto_int(x)
|
||||||
|
|
||||||
|
|
||||||
def get_port_list():
|
def get_port_list():
|
||||||
if list_ports is None:
|
if list_ports is None:
|
||||||
raise FatalError(
|
raise FatalError(
|
||||||
|
@@ -776,6 +776,10 @@ class TestErase(EsptoolTestCase):
|
|||||||
empty = self.readback(0x10000, 0x1000)
|
empty = self.readback(0x10000, 0x1000)
|
||||||
assert empty == b"\xFF" * 0x1000
|
assert empty == b"\xFF" * 0x1000
|
||||||
|
|
||||||
|
def test_region_erase_all(self):
|
||||||
|
res = self.run_esptool("erase_region 0x0 ALL")
|
||||||
|
assert re.search(r"Detected flash size: \d+[KM]B", res) is not None
|
||||||
|
|
||||||
def test_large_region_erase(self):
|
def test_large_region_erase(self):
|
||||||
# verifies that erasing a large region doesn't time out
|
# verifies that erasing a large region doesn't time out
|
||||||
self.run_esptool("erase_region 0x0 0x100000")
|
self.run_esptool("erase_region 0x0 0x100000")
|
||||||
|
Reference in New Issue
Block a user