mirror of
https://github.com/espressif/esptool.git
synced 2025-10-19 20:13:00 +08:00
feat(espefuse): Adds efuse dump formats: separated(default) and united(new)
Added features: - read cmds can be run after burn cmds - the dump cmd can be used to create a united efuse file in --virt mode - the dump cmd can be used a few times without changing original data - updated the doc
This commit is contained in:

committed by
Radim Karniš

parent
c2448436fc
commit
fc2856ae5f
@@ -10,7 +10,11 @@ The ``espefuse.py dump`` command allows:
|
||||
|
||||
Optional arguments:
|
||||
|
||||
- ``--file_name`` - Saves dump for each block into separate file. Provide the common path name like /path/blk.bin, it will create: blk0.bin, blk1.bin ... blkN.bin. Then using ``burn_block_data`` command these dump files can be written to another chip.
|
||||
- ``--format`` - Selects the dump format:
|
||||
- ``default`` - Usual console eFuse dump;
|
||||
- ``united`` - All eFuse blocks are stored in one file;
|
||||
- ``separated`` - Each eFuse block is placed in a separate file. The tool will create multiple files based on the given the ``--file_name`` argument. Example: "--file_name /path/blk.bin", blk0.bin, blk1.bin ... blkN.bin. Use the ``burn_block_data`` cmd to write it back to another chip.
|
||||
- ``--file_name`` - The path to the file in which to save the dump, if not specified, output to the console.
|
||||
|
||||
Raw Values Of Efuse Registers
|
||||
-----------------------------
|
||||
@@ -89,7 +93,7 @@ This command saves dump for each block into a separate file. You need to provide
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
> espefuse.py dump --file_name backup/chip1/blk.bin
|
||||
> espefuse.py dump --format separated --file_name backup/chip1/blk.bin
|
||||
|
||||
=== Run "dump" command ===
|
||||
backup/chip1/blk0.bin
|
||||
@@ -111,3 +115,12 @@ These dump files can be written to another chip:
|
||||
> espefuse.py burn_block_data BLOCK0 backup/chip1/blk0.bin \
|
||||
BLOCK1 backup/chip1/blk1.bin \
|
||||
BLOCK2 backup/chip1/blk2.bin
|
||||
|
||||
To save all eFuse blocks in one file, use the following command:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
> espefuse.py dump --format united --file_name backup/chip1/efuses.bin
|
||||
|
||||
=== Run "dump" command ===
|
||||
backup/chip1/efuses.bin
|
||||
|
@@ -39,13 +39,15 @@ SUPPORTED_BURN_COMMANDS = [
|
||||
"execute_scripts",
|
||||
]
|
||||
|
||||
SUPPORTED_COMMANDS = [
|
||||
SUPPORTED_READ_COMMANDS = [
|
||||
"summary",
|
||||
"dump",
|
||||
"get_custom_mac",
|
||||
"adc_info",
|
||||
"check_error",
|
||||
] + SUPPORTED_BURN_COMMANDS
|
||||
]
|
||||
|
||||
SUPPORTED_COMMANDS = SUPPORTED_READ_COMMANDS + SUPPORTED_BURN_COMMANDS
|
||||
|
||||
SUPPORTED_CHIPS = {
|
||||
"esp32": DefChip("ESP32", esp32_efuse, esptool.targets.ESP32ROM),
|
||||
@@ -228,7 +230,7 @@ def main(custom_commandline=None, esp=None):
|
||||
)
|
||||
|
||||
common_args, remaining_args = init_parser.parse_known_args(custom_commandline)
|
||||
debug_mode = common_args.debug or ("dump" in remaining_args)
|
||||
debug_mode = common_args.debug
|
||||
just_print_help = [
|
||||
True for arg in remaining_args if arg in ["--help", "-h"]
|
||||
] or remaining_args == []
|
||||
@@ -304,6 +306,22 @@ def main(custom_commandline=None, esp=None):
|
||||
if not efuses.burn_all(check_batch_mode=True):
|
||||
raise esptool.FatalError("BURN was not done")
|
||||
print("Successful")
|
||||
|
||||
if (
|
||||
sum(cmd in SUPPORTED_BURN_COMMANDS for cmd in used_cmds) > 0
|
||||
and sum(cmd in SUPPORTED_READ_COMMANDS for cmd in used_cmds) > 0
|
||||
):
|
||||
# [burn_cmd1] [burn_cmd2] [read_cmd1] [burn_cmd3] [read_cmd2]
|
||||
print("\n=== Run read commands after burn commands ===")
|
||||
for rem_args in grouped_remaining_args:
|
||||
args, unused_args = parser.parse_known_args(
|
||||
rem_args, namespace=common_args
|
||||
)
|
||||
current_cmd = args.operation
|
||||
if current_cmd in SUPPORTED_READ_COMMANDS:
|
||||
print(f"\n=== Run {args.operation} command ===")
|
||||
operation_func = vars(efuse_operations)[current_cmd]
|
||||
operation_func(esp, efuses, args)
|
||||
finally:
|
||||
if not external_esp and not common_args.virt and esp._port:
|
||||
esp._port.close()
|
||||
|
@@ -5,6 +5,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import json
|
||||
import sys
|
||||
|
||||
@@ -173,12 +174,22 @@ def add_common_commands(subparsers, efuses):
|
||||
help="Display information about ADC calibration data stored in efuse.",
|
||||
)
|
||||
|
||||
dump_cmd = subparsers.add_parser("dump", help="Dump raw hex values of all efuses")
|
||||
dump_cmd = subparsers.add_parser("dump", help="Dump raw hex values of all eFuses")
|
||||
dump_cmd.add_argument(
|
||||
"--format",
|
||||
help="Select the dump format: "
|
||||
"default - usual console eFuse dump; "
|
||||
"united - all eFuse blocks are stored in one file; "
|
||||
"separated - each eFuse block is placed in a separate file. Tool will create multiple files based on "
|
||||
"the given --file_name (/path/blk.bin): blk0.bin, blk1.bin ... blkN.bin. Use the burn_block_data cmd "
|
||||
"to write it back to another chip.",
|
||||
choices=["default", "separated", "united"],
|
||||
default="default",
|
||||
)
|
||||
dump_cmd.add_argument(
|
||||
"--file_name",
|
||||
help="Saves dump for each block into separate file. Provide the common "
|
||||
"path name /path/blk.bin, it will create: blk0.bin, blk1.bin ... blkN.bin. "
|
||||
"Use burn_block_data to write it back to another chip.",
|
||||
help="The path to the file in which to save the dump, if not specified, output to the console.",
|
||||
default=sys.stdout,
|
||||
)
|
||||
|
||||
summary_cmd = subparsers.add_parser(
|
||||
@@ -379,23 +390,48 @@ def summary(esp, efuses, args):
|
||||
|
||||
def dump(esp, efuses, args):
|
||||
"""Dump raw efuse data registers"""
|
||||
# Using --debug option allows to print dump.
|
||||
# Nothing to do here. The log will be printed
|
||||
# during EspEfuses.__init__() in self.read_blocks()
|
||||
if args.file_name:
|
||||
# save dump to the file
|
||||
dump_file = args.file_name
|
||||
to_console = args.file_name == sys.stdout
|
||||
|
||||
def output_block_to_file(block, f, to_console):
|
||||
block_dump = BitStream(block.get_bitstring())
|
||||
block_dump.byteswap()
|
||||
if to_console:
|
||||
f.write(block_dump.hex + "\n")
|
||||
else:
|
||||
block_dump.tofile(f)
|
||||
|
||||
if args.format == "default":
|
||||
if to_console:
|
||||
# for "espefuse.py dump" cmd
|
||||
for block in efuses.blocks:
|
||||
block.print_block(block.get_bitstring(), "dump", debug=True)
|
||||
return
|
||||
else:
|
||||
# for back compatibility to support "espefuse.py dump --file_name dump.bin"
|
||||
args.format = "separated"
|
||||
|
||||
if args.format == "separated":
|
||||
# each efuse block is placed in a separate file
|
||||
for block in efuses.blocks:
|
||||
file_dump_name = args.file_name
|
||||
place_for_index = file_dump_name.find(".bin")
|
||||
file_dump_name = (
|
||||
file_dump_name[:place_for_index]
|
||||
+ str(block.id)
|
||||
+ file_dump_name[place_for_index:]
|
||||
)
|
||||
print(file_dump_name)
|
||||
with open(file_dump_name, "wb") as f:
|
||||
block.get_bitstring().byteswap()
|
||||
block.get_bitstring().tofile(f)
|
||||
if not to_console:
|
||||
file_dump_name = args.file_name
|
||||
fname, fextension = os.path.splitext(file_dump_name)
|
||||
file_dump_name = f"{fname}{block.id}{fextension}"
|
||||
print(f"Dump efuse block{block.id} -> {file_dump_name}")
|
||||
dump_file = open(file_dump_name, "wb")
|
||||
output_block_to_file(block, dump_file, to_console)
|
||||
if not to_console:
|
||||
dump_file.close()
|
||||
elif args.format == "united":
|
||||
# all efuse blocks are stored in one file
|
||||
if not to_console:
|
||||
print(f"Dump efuse blocks -> {args.file_name}")
|
||||
dump_file = open(args.file_name, "wb")
|
||||
for block in efuses.blocks:
|
||||
output_block_to_file(block, dump_file, to_console)
|
||||
if not to_console:
|
||||
dump_file.close()
|
||||
|
||||
|
||||
def burn_efuse(esp, efuses, args):
|
||||
|
@@ -38,12 +38,7 @@ class EmulateEfuseController(EmulateEfuseControllerBase):
|
||||
if addr == self.REGS.APB_CTL_DATE_ADDR:
|
||||
return self.REGS.APB_CTL_DATE_V << self.REGS.APB_CTL_DATE_S
|
||||
else:
|
||||
val = 0
|
||||
if addr == self.REGS.EFUSE_BLK0_RDATA3_REG:
|
||||
val = self.REGS.EFUSE_RD_CHIP_VER_REV1
|
||||
if addr == self.REGS.EFUSE_BLK0_RDATA5_REG:
|
||||
val = self.REGS.EFUSE_RD_CHIP_VER_REV2
|
||||
return val | super(EmulateEfuseController, self).read_reg(addr)
|
||||
return super(EmulateEfuseController, self).read_reg(addr)
|
||||
|
||||
""" << esptool method end """
|
||||
|
||||
|
@@ -73,6 +73,7 @@ class EfuseTestCase:
|
||||
f"{sys.executable} -m espefuse --chip {arg_chip} "
|
||||
f"--virt --path-efuse-file {self.efuse_file.name} -d"
|
||||
)
|
||||
self._set_target_wafer_version()
|
||||
else:
|
||||
self.base_cmd = (
|
||||
f"{sys.executable} -m espefuse --chip {arg_chip} "
|
||||
@@ -117,6 +118,11 @@ class EfuseTestCase:
|
||||
def _set_none_recovery_coding_scheme(self):
|
||||
self.espefuse_py("burn_efuse CODING_SCHEME 3")
|
||||
|
||||
def _set_target_wafer_version(self):
|
||||
# ESP32 has to be ECO3 (v3.0) for tests
|
||||
if arg_chip == "esp32":
|
||||
self.espefuse_py("burn_efuse CHIP_VER_REV1 1 CHIP_VER_REV2 1")
|
||||
|
||||
def check_data_block_in_log(
|
||||
self, log, file_path, repeat=1, reverse_order=False, offset=0
|
||||
):
|
||||
@@ -177,6 +183,18 @@ class TestReadCommands(EfuseTestCase):
|
||||
self.espefuse_py("dump -h")
|
||||
self.espefuse_py("dump")
|
||||
|
||||
def test_dump_format_united(self):
|
||||
tmp_file = tempfile.NamedTemporaryFile(delete=False)
|
||||
self.espefuse_py(f"dump --format united --file_name {tmp_file.name}")
|
||||
|
||||
def test_dump_separated_default(self):
|
||||
tmp_file = tempfile.NamedTemporaryFile(delete=False)
|
||||
self.espefuse_py(f"dump --file_name {tmp_file.name}")
|
||||
|
||||
def test_dump_separated(self):
|
||||
tmp_file = tempfile.NamedTemporaryFile(delete=False)
|
||||
self.espefuse_py(f"dump --format separated --file_name {tmp_file.name}")
|
||||
|
||||
def test_summary(self):
|
||||
self.espefuse_py("summary -h")
|
||||
self.espefuse_py("summary")
|
||||
|
Reference in New Issue
Block a user