mirror of
https://github.com/espressif/esptool.git
synced 2025-10-19 20:13:00 +08:00
feat(cmds): Polish the public API, unify arg names, pack some args
BREAKING CHANGE
This commit is contained in:
@@ -303,7 +303,7 @@ The output of the command will be in ``raw`` format and gaps between individual
|
||||
|
||||
**RAW options:**
|
||||
|
||||
* The ``--fill-flash-size SIZE`` option will pad the merged binary with `0xFF` bytes to the full flash specified size, for example ``--fill-flash-size 4MB`` will create a 4MB binary file.
|
||||
* The ``--pad-to-size SIZE`` option will pad the merged binary with `0xFF` bytes to the full flash specified size, for example ``--pad-to-size 4MB`` will create a 4MB binary file.
|
||||
* The ``--target-offset 0xNNN`` option will create a merged binary that should be flashed at the specified offset, instead of at offset 0x0.
|
||||
|
||||
|
||||
|
@@ -153,3 +153,21 @@ The esptool ``v5`` has switched to using `Click <https://click.palletsprojects.c
|
||||
|
||||
1. Remove the old shell completion code from your scripts and shell configuration files like ``.bashrc``, ``.zshrc``, ``.config/fish/config.fish``, etc.
|
||||
2. Follow the new shell completion setup instructions in the :ref:`shell-completion` section of the :ref:`installation <installation>` guide.
|
||||
|
||||
``merge_bin`` ``--fill-flash-size`` Argument
|
||||
********************************************
|
||||
|
||||
The ``--fill-flash-size`` option of the :ref:`merge_bin <merge-bin>` command has been renamed to ``--pad-to-size``. This change provides a more intuitive and descriptive name for the argument and is consistent with the naming scheme in other esptool image manipulation commands.
|
||||
|
||||
**Migration Steps:**
|
||||
|
||||
1. Rename the ``--fill-flash-size`` to ``--pad-to-size`` in any existing ``merge_bin`` commands in scripts/CI pipelines.
|
||||
|
||||
``write_flash`` ``--ignore-flash-encryption-efuse-setting`` Argument
|
||||
********************************************************************
|
||||
|
||||
The ``--ignore-flash-encryption-efuse-setting`` option of the :ref:`write_flash <write-flash>` command has been renamed to ``--ignore-flash-enc-efuse``. This change shortens the argument name to improve readability and consistency with other esptool options.
|
||||
|
||||
**Migration Steps:**
|
||||
|
||||
1. Rename the ``--ignore-flash-encryption-efuse-setting`` to ``--ignore-flash-enc-efuse`` in any existing ``write_flash`` commands in scripts/CI pipelines.
|
||||
|
@@ -123,7 +123,7 @@ click.rich_click.OPTION_GROUPS = {
|
||||
"name": "RAW options",
|
||||
"options": [
|
||||
"--target-offset",
|
||||
"--fill-flash-size",
|
||||
"--pad-to-size",
|
||||
],
|
||||
},
|
||||
],
|
||||
@@ -570,9 +570,9 @@ def write_mem_cli(ctx, address, value, mask):
|
||||
"filename, separated by space.",
|
||||
)
|
||||
@click.option(
|
||||
"--ignore-flash-encryption-efuse-setting",
|
||||
"--ignore-flash-enc-efuse",
|
||||
is_flag=True,
|
||||
help="Ignore flash encryption efuse settings",
|
||||
help="Ignore flash encryption eFuse settings",
|
||||
)
|
||||
@click.option(
|
||||
"--force",
|
||||
@@ -926,12 +926,12 @@ def read_flash_sfdp_cli(ctx, address, bytes, **kwargs):
|
||||
help="Target offset where the output file will be flashed",
|
||||
)
|
||||
@click.option( # RAW only
|
||||
"--fill-flash-size",
|
||||
"--pad-to-size",
|
||||
type=click.Choice(
|
||||
["256KB", "512KB", "1MB", "2MB", "4MB", "8MB", "16MB", "32MB", "64MB", "128MB"]
|
||||
),
|
||||
help="If set, the final binary file will be padded with FF bytes up to this flash "
|
||||
"size.",
|
||||
help="If set, the final binary file will be padded with 0xFF bytes up to this flash"
|
||||
" size.",
|
||||
)
|
||||
@add_spi_flash_options(allow_keep=True, auto_detect=False)
|
||||
@click.pass_context
|
||||
|
131
esptool/cmds.py
131
esptool/cmds.py
@@ -102,7 +102,7 @@ def detect_chip(
|
||||
connect_attempts: Number of connection attempts before failing.
|
||||
|
||||
Returns:
|
||||
An instance of the detected chip class, initialized and ready for use.
|
||||
An initialized instance of the detected chip class ready for use.
|
||||
"""
|
||||
inst = None
|
||||
detect_port = ESPLoader(port, baud, trace_enabled=trace_enabled)
|
||||
@@ -257,7 +257,7 @@ def dump_mem(
|
||||
output: Path to output file for binary data. If None, returns the data.
|
||||
|
||||
Returns:
|
||||
bytes | None: Memory dump as bytes if filename is None;
|
||||
Memory dump as bytes if filename is None;
|
||||
otherwise, returns None after writing to file.
|
||||
"""
|
||||
log.print(
|
||||
@@ -429,14 +429,7 @@ def write_flash(
|
||||
flash_freq: str = "keep",
|
||||
flash_mode: str = "keep",
|
||||
flash_size: str = "keep",
|
||||
erase_all: bool = False,
|
||||
encrypt: bool = False,
|
||||
encrypt_files: list[tuple[int, BinaryIO]] | None = None,
|
||||
compress: bool = False,
|
||||
no_compress: bool = False,
|
||||
force: bool = False,
|
||||
ignore_flash_encryption_efuse_setting: bool = False,
|
||||
no_progress: bool = False,
|
||||
**kwargs,
|
||||
) -> None:
|
||||
"""
|
||||
Write firmware or data to the SPI flash memory of an ESP device.
|
||||
@@ -451,15 +444,29 @@ def write_flash(
|
||||
(``"keep"`` to retain current).
|
||||
flash_size: Flash size to set in the bootloader image header
|
||||
(``"keep"`` to retain current).
|
||||
erase_all: Erase the entire flash before writing.
|
||||
encrypt: Encrypt all files during flashing.
|
||||
encrypt_files: List of (address, file) tuples for files to encrypt individually.
|
||||
compress: Compress data before flashing.
|
||||
no_compress: Don't compress data before flashing.
|
||||
force: Ignore safety checks (e.g., secure boot, flash size).
|
||||
ignore_flash_encryption_efuse_setting: Ignore flash encryption efuse settings.
|
||||
no_progress: Disable progress updates.
|
||||
|
||||
Keyword Args:
|
||||
erase_all (bool): Erase the entire flash before writing.
|
||||
encrypt (bool): Encrypt all files during flashing.
|
||||
encrypt_files (list[tuple[int, BinaryIO]] | None): List of (address, file)
|
||||
tuples for files to encrypt individually.
|
||||
compress (bool): Compress data before flashing.
|
||||
no_compress (bool): Don't compress data before flashing.
|
||||
force (bool): Ignore safety checks (e.g., overwriting bootloader, flash size).
|
||||
ignore_flash_enc_efuse (bool): Ignore flash encryption eFuse settings.
|
||||
no_progress (bool): Disable progress updates.
|
||||
"""
|
||||
|
||||
# Set default values of optional arguments
|
||||
erase_all: bool = kwargs.get("erase_all", False)
|
||||
encrypt: bool = kwargs.get("encrypt", False)
|
||||
encrypt_files: list[tuple[int, BinaryIO]] | None = kwargs.get("encrypt_files", None)
|
||||
compress: bool = kwargs.get("compress", False)
|
||||
no_compress: bool = kwargs.get("no_compress", False)
|
||||
force: bool = kwargs.get("force", False)
|
||||
ignore_flash_enc_efuse: bool = kwargs.get("ignore_flash_enc_efuse", False)
|
||||
no_progress: bool = kwargs.get("no_progress", False)
|
||||
|
||||
# set compress based on default behaviour:
|
||||
# -> if either "compress" or "no_compress" is set, honour that
|
||||
# -> otherwise, set "compress" unless the stub flasher is disabled
|
||||
@@ -575,7 +582,7 @@ def write_flash(
|
||||
|
||||
do_write = False
|
||||
|
||||
if not do_write and not ignore_flash_encryption_efuse_setting:
|
||||
if not do_write and not ignore_flash_enc_efuse:
|
||||
raise FatalError(
|
||||
"Can't perform encrypted flash write, "
|
||||
"consult Flash Encryption documentation for more information"
|
||||
@@ -1231,7 +1238,7 @@ def read_flash_sfdp(esp: ESPLoader, address: int, bytes: int = 1) -> None:
|
||||
Args:
|
||||
esp: Initiated esp object connected to a real device.
|
||||
address: Starting address in the SFDP region to read from.
|
||||
bytes: Number of bytes to read (1-4, default: 1).
|
||||
bytes: Number of bytes to read (1-4).
|
||||
"""
|
||||
if not (1 <= bytes <= 4):
|
||||
raise FatalError("Invalid number of bytes to read from SFDP (1-4).")
|
||||
@@ -1270,7 +1277,7 @@ def read_flash(
|
||||
no_progress: Disable printing progress.
|
||||
|
||||
Returns:
|
||||
bytes | None: The read flash data as bytes if output is None; otherwise,
|
||||
The read flash data as bytes if output is None; otherwise,
|
||||
returns None after writing to file.
|
||||
"""
|
||||
_set_flash_parameters(esp, flash_size)
|
||||
@@ -1557,7 +1564,7 @@ def run_stub(esp: ESPLoader) -> ESPLoader:
|
||||
esp: Initiated esp object connected to a real device.
|
||||
|
||||
Returns:
|
||||
ESPLoader: The esp instance, either as a stub child class in a state
|
||||
The esp instance, either as a stub child class in a state
|
||||
where the stub has been executed, or in its original state
|
||||
if the stub loader is disabled or unsupported.
|
||||
"""
|
||||
@@ -1938,10 +1945,7 @@ def merge_bin(
|
||||
flash_mode: str = "keep",
|
||||
flash_size: str = "keep",
|
||||
format: str = "raw",
|
||||
target_offset: int = 0,
|
||||
fill_flash_size: str | None = None,
|
||||
chunk_size: int | None = None,
|
||||
md5_disable: bool = False,
|
||||
**kwargs,
|
||||
) -> None:
|
||||
"""
|
||||
Merge multiple binary files into a single output file for flashing to an ESP device.
|
||||
@@ -1962,11 +1966,20 @@ def merge_bin(
|
||||
flash_size: Flash size to set in the image header
|
||||
(``"keep"`` to retain current).
|
||||
format: Output format (``"raw"``, ``"uf2"``, or ``"hex"``).
|
||||
target_offset: Starting offset for the merged output.
|
||||
fill_flash_size: If specified, pad the output he given flash size.
|
||||
chunk_size: Chunk size for UF2 format.
|
||||
md5_disable: If True, disable MD5 checks in UF2 format.
|
||||
|
||||
Keyword Args:
|
||||
target_offset (int): Starting offset for the merged output.
|
||||
pad_to_size (str | None): If specified, pad the output to a specific flash size.
|
||||
chunk_size (int | None): Chunk size for UF2 format.
|
||||
md5_disable (bool): If True, disable MD5 checks in UF2 format.
|
||||
"""
|
||||
|
||||
# Set default values of optional arguments
|
||||
target_offset: int = kwargs.get("target_offset", 0)
|
||||
pad_to_size: str | None = kwargs.get("pad_to_size", None)
|
||||
chunk_size: int | None = kwargs.get("chunk_size", None)
|
||||
md5_disable: bool = kwargs.get("md5_disable", False)
|
||||
|
||||
try:
|
||||
chip_class = CHIP_DEFS[chip]
|
||||
except KeyError:
|
||||
@@ -2023,8 +2036,8 @@ def merge_bin(
|
||||
chip_class, addr, flash_freq, flash_mode, flash_size, image
|
||||
)
|
||||
of.write(image)
|
||||
if fill_flash_size:
|
||||
pad_to(flash_size_bytes(fill_flash_size))
|
||||
if pad_to_size:
|
||||
pad_to(flash_size_bytes(pad_to_size))
|
||||
log.print(
|
||||
f"Wrote {of.tell():#x} bytes to file {output}, "
|
||||
f"ready to flash to offset {target_offset:#x}"
|
||||
@@ -2061,18 +2074,7 @@ def elf2image(
|
||||
flash_freq: str | None = None,
|
||||
flash_mode: str = "qio",
|
||||
flash_size: str = "1MB",
|
||||
version: int = 1,
|
||||
min_rev: int = 0,
|
||||
min_rev_full: int = 0,
|
||||
max_rev_full: int = 65535,
|
||||
secure_pad: bool = False,
|
||||
secure_pad_v2: bool = False,
|
||||
elf_sha256_offset: int | None = None,
|
||||
append_digest: bool = True,
|
||||
use_segments: bool = False,
|
||||
flash_mmu_page_size: str | None = None,
|
||||
pad_to_size: str | None = None,
|
||||
ram_only_header: bool = False,
|
||||
**kwargs,
|
||||
) -> None:
|
||||
"""
|
||||
Convert an ELF file into a firmware image suitable for flashing onto an ESP device.
|
||||
@@ -2084,19 +2086,36 @@ def elf2image(
|
||||
flash_freq: Flash frequency to set in the image header.
|
||||
flash_mode: Flash mode to set in the image header.
|
||||
flash_size: Flash size to set in the image header.
|
||||
version: ESP8266 only, firmware image version.
|
||||
min_rev: Minimum chip revision required.
|
||||
min_rev_full: Minimum full revision required.
|
||||
max_rev_full: Maximum full revision allowed.
|
||||
secure_pad: Enable secure padding, ESP32-only.
|
||||
secure_pad_v2: Enable version 2 secure padding.
|
||||
elf_sha256_offset: Offset for storing the ELF file's SHA-256 hash.
|
||||
append_digest: Whether to append a digest to the firmware image.
|
||||
use_segments: Use ELF segments instead of sections.
|
||||
flash_mmu_page_size: MMU page size for flash mapping.
|
||||
pad_to_size: Pad the final image to a specific flash size.
|
||||
ram_only_header: Image will only contain RAM segments and no SHA-256 digest.
|
||||
|
||||
Keyword Args:
|
||||
version (int): ESP8266-only, firmware image version.
|
||||
min_rev (int): Minimum chip revision required in legacy format.
|
||||
min_rev_full (int): Minimum chip revision required in extended format.
|
||||
max_rev_full (int): Maximum chip revision allowed in extended format.
|
||||
secure_pad (bool): ESP32-only, enable secure padding.
|
||||
secure_pad_v2 (bool): Enable version 2 secure padding.
|
||||
elf_sha256_offset (int): Offset for storing the ELF file's SHA-256 hash.
|
||||
append_digest (bool): Whether to append a digest to the firmware image.
|
||||
use_segments (bool): Use ELF segments instead of sections.
|
||||
flash_mmu_page_size (str): MMU page size for flash mapping.
|
||||
pad_to_size (str): Pad the final image to a specific flash size.
|
||||
ram_only_header (bool): Include only RAM segments and no SHA-256 hash.
|
||||
"""
|
||||
|
||||
# Set default values of optional arguments
|
||||
version: int = kwargs.get("version", 1)
|
||||
min_rev: int = kwargs.get("min_rev", 0)
|
||||
min_rev_full: int = kwargs.get("min_rev_full", 0)
|
||||
max_rev_full: int = kwargs.get("max_rev_full", 65535)
|
||||
secure_pad: bool = kwargs.get("secure_pad", False)
|
||||
secure_pad_v2: bool = kwargs.get("secure_pad_v2", False)
|
||||
elf_sha256_offset: int | None = kwargs.get("elf_sha256_offset", None)
|
||||
append_digest: bool = kwargs.get("append_digest", True)
|
||||
use_segments: bool = kwargs.get("use_segments", False)
|
||||
flash_mmu_page_size: str | None = kwargs.get("flash_mmu_page_size", None)
|
||||
pad_to_size: str | None = kwargs.get("pad_to_size", None)
|
||||
ram_only_header: bool = kwargs.get("ram_only_header", False)
|
||||
|
||||
e = ELFFile(input)
|
||||
if chip == "auto": # Default to ESP8266 for backwards compatibility
|
||||
chip = "esp8266"
|
||||
|
@@ -369,7 +369,7 @@ class TestFlashEncryption(EsptoolTestCase):
|
||||
pytest.skip("Valid encryption key already programmed, aborting the test")
|
||||
|
||||
self.run_esptool(
|
||||
"write_flash --encrypt --ignore-flash-encryption-efuse-setting "
|
||||
"write_flash --encrypt --ignore-flash-enc-efuse "
|
||||
"0x10000 images/ram_helloworld/helloworld-esp32.bin"
|
||||
)
|
||||
self.run_esptool("read_flash 0x10000 192 images/read_encrypted_flash.bin")
|
||||
@@ -408,7 +408,7 @@ class TestFlashEncryption(EsptoolTestCase):
|
||||
pytest.skip("Valid encryption key already programmed, aborting the test")
|
||||
|
||||
self.run_esptool(
|
||||
"write_flash --encrypt --ignore-flash-encryption-efuse-setting "
|
||||
"write_flash --encrypt --ignore-flash-enc-efuse "
|
||||
"0x10000 images/ram_helloworld/helloworld-esp32_edit.bin"
|
||||
)
|
||||
self.run_esptool("read_flash 0x10000 192 images/read_encrypted_flash.bin")
|
||||
|
@@ -169,9 +169,9 @@ class TestMergeBin:
|
||||
assert helloworld == merged[0xF000 : 0xF000 + len(helloworld)]
|
||||
self.assertAllFF(merged[0x1000 + len(bootloader) : 0xF000])
|
||||
|
||||
def test_fill_flash_size(self):
|
||||
def test_pad_to_size(self):
|
||||
merged = self.run_merge_bin(
|
||||
"esp32c3", [(0x0, "bootloader_esp32c3.bin")], ["--fill-flash-size", "4MB"]
|
||||
"esp32c3", [(0x0, "bootloader_esp32c3.bin")], ["--pad-to-size", "4MB"]
|
||||
)
|
||||
bootloader = read_image("bootloader_esp32c3.bin")
|
||||
|
||||
@@ -179,14 +179,14 @@ class TestMergeBin:
|
||||
assert bootloader == merged[: len(bootloader)]
|
||||
self.assertAllFF(merged[len(bootloader) :])
|
||||
|
||||
def test_fill_flash_size_w_target_offset(self):
|
||||
def test_pad_to_size_w_target_offset(self):
|
||||
merged = self.run_merge_bin(
|
||||
"esp32",
|
||||
[
|
||||
(0x1000, "bootloader_esp32.bin"),
|
||||
(0x10000, "ram_helloworld/helloworld-esp32.bin"),
|
||||
],
|
||||
["--target-offset", "0x1000", "--fill-flash-size", "2MB"],
|
||||
["--target-offset", "0x1000", "--pad-to-size", "2MB"],
|
||||
)
|
||||
|
||||
# full length is without target-offset arg
|
||||
@@ -215,7 +215,7 @@ class TestMergeBin:
|
||||
merged = self.run_merge_bin(
|
||||
"esp32",
|
||||
[(0x1000, f.name), (0x10000, "ram_helloworld/helloworld-esp32.bin")],
|
||||
["--target-offset", "0x1000", "--fill-flash-size", "2MB"],
|
||||
["--target-offset", "0x1000", "--pad-to-size", "2MB"],
|
||||
)
|
||||
finally:
|
||||
os.unlink(f.name)
|
||||
|
Reference in New Issue
Block a user