mirror of
https://github.com/espressif/esptool.git
synced 2025-10-20 04:54:31 +08:00
fix(read_flash): add flash size arg to enable reading past 2MB without stub
This commit is contained in:

committed by
Radim Karniš

parent
8ce5ed3c2b
commit
f1eb65f885
@@ -113,6 +113,11 @@ It is also possible to autodetect flash size by using ``ALL`` as size. The above
|
|||||||
esptool.py -p PORT -b 460800 read_flash 0 ALL flash_contents.bin
|
esptool.py -p PORT -b 460800 read_flash 0 ALL flash_contents.bin
|
||||||
|
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
When using the ``read_flash`` command in combination with the ``--no-stub`` argument, it may be necessary to also set the ``--flash_size`` argument to ensure proper reading of the flash contents by the ROM.
|
||||||
|
|
||||||
|
|
||||||
.. 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.
|
||||||
|
@@ -217,7 +217,12 @@ def main(argv=None, esp=None):
|
|||||||
default="0xFFFFFFFF",
|
default="0xFFFFFFFF",
|
||||||
)
|
)
|
||||||
|
|
||||||
def add_spi_flash_subparsers(parent, allow_keep, auto_detect):
|
def add_spi_flash_subparsers(
|
||||||
|
parent: argparse.ArgumentParser,
|
||||||
|
allow_keep: bool,
|
||||||
|
auto_detect: bool,
|
||||||
|
size_only: bool = False,
|
||||||
|
):
|
||||||
"""Add common parser arguments for SPI flash properties"""
|
"""Add common parser arguments for SPI flash properties"""
|
||||||
extra_keep_args = ["keep"] if allow_keep else []
|
extra_keep_args = ["keep"] if allow_keep else []
|
||||||
|
|
||||||
@@ -234,33 +239,35 @@ def main(argv=None, esp=None):
|
|||||||
extra_fs_message = ""
|
extra_fs_message = ""
|
||||||
flash_sizes = []
|
flash_sizes = []
|
||||||
|
|
||||||
parent.add_argument(
|
if not size_only:
|
||||||
"--flash_freq",
|
parent.add_argument(
|
||||||
"-ff",
|
"--flash_freq",
|
||||||
help="SPI Flash frequency",
|
"-ff",
|
||||||
choices=extra_keep_args
|
help="SPI Flash frequency",
|
||||||
+ [
|
choices=extra_keep_args
|
||||||
"80m",
|
+ [
|
||||||
"60m",
|
"80m",
|
||||||
"48m",
|
"60m",
|
||||||
"40m",
|
"48m",
|
||||||
"30m",
|
"40m",
|
||||||
"26m",
|
"30m",
|
||||||
"24m",
|
"26m",
|
||||||
"20m",
|
"24m",
|
||||||
"16m",
|
"20m",
|
||||||
"15m",
|
"16m",
|
||||||
"12m",
|
"15m",
|
||||||
],
|
"12m",
|
||||||
default=os.environ.get("ESPTOOL_FF", "keep" if allow_keep else None),
|
],
|
||||||
)
|
default=os.environ.get("ESPTOOL_FF", "keep" if allow_keep else None),
|
||||||
parent.add_argument(
|
)
|
||||||
"--flash_mode",
|
parent.add_argument(
|
||||||
"-fm",
|
"--flash_mode",
|
||||||
help="SPI Flash mode",
|
"-fm",
|
||||||
choices=extra_keep_args + ["qio", "qout", "dio", "dout"],
|
help="SPI Flash mode",
|
||||||
default=os.environ.get("ESPTOOL_FM", "keep" if allow_keep else "qio"),
|
choices=extra_keep_args + ["qio", "qout", "dio", "dout"],
|
||||||
)
|
default=os.environ.get("ESPTOOL_FM", "keep" if allow_keep else "qio"),
|
||||||
|
)
|
||||||
|
|
||||||
parent.add_argument(
|
parent.add_argument(
|
||||||
"--flash_size",
|
"--flash_size",
|
||||||
"-fs",
|
"-fs",
|
||||||
@@ -540,7 +547,9 @@ def main(argv=None, esp=None):
|
|||||||
parser_read_flash = subparsers.add_parser(
|
parser_read_flash = subparsers.add_parser(
|
||||||
"read_flash", help="Read SPI flash content"
|
"read_flash", help="Read SPI flash content"
|
||||||
)
|
)
|
||||||
add_spi_connection_arg(parser_read_flash)
|
add_spi_flash_subparsers(
|
||||||
|
parser_read_flash, allow_keep=True, auto_detect=True, size_only=True
|
||||||
|
)
|
||||||
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",
|
"size",
|
||||||
|
@@ -329,11 +329,17 @@ class ESP32ROM(ESPLoader):
|
|||||||
data = b""
|
data = b""
|
||||||
while len(data) < length:
|
while len(data) < length:
|
||||||
block_len = min(BLOCK_LEN, length - len(data))
|
block_len = min(BLOCK_LEN, length - len(data))
|
||||||
r = self.check_command(
|
try:
|
||||||
"read flash block",
|
r = self.check_command(
|
||||||
self.ESP_READ_FLASH_SLOW,
|
"read flash block",
|
||||||
struct.pack("<II", offset + len(data), block_len),
|
self.ESP_READ_FLASH_SLOW,
|
||||||
)
|
struct.pack("<II", offset + len(data), block_len),
|
||||||
|
)
|
||||||
|
except FatalError:
|
||||||
|
print(
|
||||||
|
"Hint: Consider specifying flash size using '--flash_size' argument"
|
||||||
|
)
|
||||||
|
raise
|
||||||
if len(r) < block_len:
|
if len(r) < block_len:
|
||||||
raise FatalError(
|
raise FatalError(
|
||||||
"Expected %d byte block, got %d bytes. Serial errors?"
|
"Expected %d byte block, got %d bytes. Serial errors?"
|
||||||
|
@@ -251,6 +251,12 @@ class EsptoolTestCase:
|
|||||||
dump_file.close()
|
dump_file.close()
|
||||||
os.unlink(dump_file.name)
|
os.unlink(dump_file.name)
|
||||||
|
|
||||||
|
def diff(self, readback, compare_to):
|
||||||
|
for rb_b, ct_b, offs in zip(readback, compare_to, range(len(readback))):
|
||||||
|
assert (
|
||||||
|
rb_b == ct_b
|
||||||
|
), f"First difference at offset {offs:#x} Expected {ct_b} got {rb_b}"
|
||||||
|
|
||||||
def verify_readback(
|
def verify_readback(
|
||||||
self, offset, length, compare_to, is_bootloader=False, spi_connection=None
|
self, offset, length, compare_to, is_bootloader=False, spi_connection=None
|
||||||
):
|
):
|
||||||
@@ -268,10 +274,7 @@ class EsptoolTestCase:
|
|||||||
assert ct[0] == rb[0], "First bytes should be identical"
|
assert ct[0] == rb[0], "First bytes should be identical"
|
||||||
rb = rb[8:]
|
rb = rb[8:]
|
||||||
ct = ct[8:]
|
ct = ct[8:]
|
||||||
for rb_b, ct_b, offs in zip(rb, ct, range(len(rb))):
|
self.diff(rb, ct)
|
||||||
assert (
|
|
||||||
rb_b == ct_b
|
|
||||||
), f"First difference at offset {offs:#x} Expected {ct_b} got {rb_b}"
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(arg_chip != "esp32", reason="ESP32 only")
|
@pytest.mark.skipif(arg_chip != "esp32", reason="ESP32 only")
|
||||||
@@ -735,6 +738,32 @@ class TestFlashSizes(EsptoolTestCase):
|
|||||||
# header should be the same as in the .bin file
|
# header should be the same as in the .bin file
|
||||||
self.verify_readback(offset, image_len, image)
|
self.verify_readback(offset, image_len, image)
|
||||||
|
|
||||||
|
@pytest.mark.skipif(
|
||||||
|
arg_chip == "esp8266", reason="ESP8266 does not support read_flash_slow"
|
||||||
|
)
|
||||||
|
def test_read_nostub_high_offset(self):
|
||||||
|
offset = 0x300000
|
||||||
|
length = 1024
|
||||||
|
self.run_esptool(f"write_flash -fs detect {offset} images/one_kb.bin")
|
||||||
|
dump_file = tempfile.NamedTemporaryFile(delete=False)
|
||||||
|
# readback with no-stub and flash-size set
|
||||||
|
try:
|
||||||
|
self.run_esptool(
|
||||||
|
f"--no-stub read_flash -fs detect {offset} 1024 {dump_file.name}"
|
||||||
|
)
|
||||||
|
with open(dump_file.name, "rb") as f:
|
||||||
|
rb = f.read()
|
||||||
|
assert length == len(
|
||||||
|
rb
|
||||||
|
), f"read_flash length {length} offset {offset:#x} yielded {len(rb)} bytes!"
|
||||||
|
finally:
|
||||||
|
dump_file.close()
|
||||||
|
os.unlink(dump_file.name)
|
||||||
|
# compare files
|
||||||
|
with open("images/one_kb.bin", "rb") as f:
|
||||||
|
ct = f.read()
|
||||||
|
self.diff(rb, ct)
|
||||||
|
|
||||||
|
|
||||||
class TestFlashDetection(EsptoolTestCase):
|
class TestFlashDetection(EsptoolTestCase):
|
||||||
@pytest.mark.quick_test
|
@pytest.mark.quick_test
|
||||||
@@ -1337,10 +1366,7 @@ class TestMakeImage(EsptoolTestCase):
|
|||||||
f"WARNING: Expected length {len(ct)} doesn't match comparison {len(rb)}"
|
f"WARNING: Expected length {len(ct)} doesn't match comparison {len(rb)}"
|
||||||
)
|
)
|
||||||
print(f"Readback {len(rb)} bytes")
|
print(f"Readback {len(rb)} bytes")
|
||||||
for rb_b, ct_b, offs in zip(rb, ct, range(len(rb))):
|
self.diff(rb, ct)
|
||||||
assert (
|
|
||||||
rb_b == ct_b
|
|
||||||
), f"First difference at offset {offs:#x} Expected {ct_b} got {rb_b}"
|
|
||||||
|
|
||||||
def test_make_image(self):
|
def test_make_image(self):
|
||||||
output = self.run_esptool(
|
output = self.run_esptool(
|
||||||
|
Reference in New Issue
Block a user