Skip to content

Commit fc2856a

Browse files
KonstantinKondrashovradimkarnis
authored andcommitted
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
1 parent c244843 commit fc2856a

File tree

5 files changed

+111
-31
lines changed

5 files changed

+111
-31
lines changed

docs/en/espefuse/dump-cmd.rst

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ The ``espefuse.py dump`` command allows:
1010

1111
Optional arguments:
1212

13-
- ``--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.
13+
- ``--format`` - Selects the dump format:
14+
- ``default`` - Usual console eFuse dump;
15+
- ``united`` - All eFuse blocks are stored in one file;
16+
- ``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.
17+
- ``--file_name`` - The path to the file in which to save the dump, if not specified, output to the console.
1418

1519
Raw Values Of Efuse Registers
1620
-----------------------------
@@ -89,7 +93,7 @@ This command saves dump for each block into a separate file. You need to provide
8993

9094
.. code-block:: none
9195
92-
> espefuse.py dump --file_name backup/chip1/blk.bin
96+
> espefuse.py dump --format separated --file_name backup/chip1/blk.bin
9397
9498
=== Run "dump" command ===
9599
backup/chip1/blk0.bin
@@ -111,3 +115,12 @@ These dump files can be written to another chip:
111115
> espefuse.py burn_block_data BLOCK0 backup/chip1/blk0.bin \
112116
BLOCK1 backup/chip1/blk1.bin \
113117
BLOCK2 backup/chip1/blk2.bin
118+
119+
To save all eFuse blocks in one file, use the following command:
120+
121+
.. code-block:: none
122+
123+
> espefuse.py dump --format united --file_name backup/chip1/efuses.bin
124+
125+
=== Run "dump" command ===
126+
backup/chip1/efuses.bin

espefuse/__init__.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,15 @@
3939
"execute_scripts",
4040
]
4141

42-
SUPPORTED_COMMANDS = [
42+
SUPPORTED_READ_COMMANDS = [
4343
"summary",
4444
"dump",
4545
"get_custom_mac",
4646
"adc_info",
4747
"check_error",
48-
] + SUPPORTED_BURN_COMMANDS
48+
]
49+
50+
SUPPORTED_COMMANDS = SUPPORTED_READ_COMMANDS + SUPPORTED_BURN_COMMANDS
4951

5052
SUPPORTED_CHIPS = {
5153
"esp32": DefChip("ESP32", esp32_efuse, esptool.targets.ESP32ROM),
@@ -228,7 +230,7 @@ def main(custom_commandline=None, esp=None):
228230
)
229231

230232
common_args, remaining_args = init_parser.parse_known_args(custom_commandline)
231-
debug_mode = common_args.debug or ("dump" in remaining_args)
233+
debug_mode = common_args.debug
232234
just_print_help = [
233235
True for arg in remaining_args if arg in ["--help", "-h"]
234236
] or remaining_args == []
@@ -304,6 +306,22 @@ def main(custom_commandline=None, esp=None):
304306
if not efuses.burn_all(check_batch_mode=True):
305307
raise esptool.FatalError("BURN was not done")
306308
print("Successful")
309+
310+
if (
311+
sum(cmd in SUPPORTED_BURN_COMMANDS for cmd in used_cmds) > 0
312+
and sum(cmd in SUPPORTED_READ_COMMANDS for cmd in used_cmds) > 0
313+
):
314+
# [burn_cmd1] [burn_cmd2] [read_cmd1] [burn_cmd3] [read_cmd2]
315+
print("\n=== Run read commands after burn commands ===")
316+
for rem_args in grouped_remaining_args:
317+
args, unused_args = parser.parse_known_args(
318+
rem_args, namespace=common_args
319+
)
320+
current_cmd = args.operation
321+
if current_cmd in SUPPORTED_READ_COMMANDS:
322+
print(f"\n=== Run {args.operation} command ===")
323+
operation_func = vars(efuse_operations)[current_cmd]
324+
operation_func(esp, efuses, args)
307325
finally:
308326
if not external_esp and not common_args.virt and esp._port:
309327
esp._port.close()

espefuse/efuse/base_operations.py

Lines changed: 56 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
# SPDX-License-Identifier: GPL-2.0-or-later
66

77
import argparse
8+
import os
89
import json
910
import sys
1011

@@ -173,12 +174,22 @@ def check_efuse_name(efuse_name, efuse_list):
173174
help="Display information about ADC calibration data stored in efuse.",
174175
)
175176

176-
dump_cmd = subparsers.add_parser("dump", help="Dump raw hex values of all efuses")
177+
dump_cmd = subparsers.add_parser("dump", help="Dump raw hex values of all eFuses")
178+
dump_cmd.add_argument(
179+
"--format",
180+
help="Select the dump format: "
181+
"default - usual console eFuse dump; "
182+
"united - all eFuse blocks are stored in one file; "
183+
"separated - each eFuse block is placed in a separate file. Tool will create multiple files based on "
184+
"the given --file_name (/path/blk.bin): blk0.bin, blk1.bin ... blkN.bin. Use the burn_block_data cmd "
185+
"to write it back to another chip.",
186+
choices=["default", "separated", "united"],
187+
default="default",
188+
)
177189
dump_cmd.add_argument(
178190
"--file_name",
179-
help="Saves dump for each block into separate file. Provide the common "
180-
"path name /path/blk.bin, it will create: blk0.bin, blk1.bin ... blkN.bin. "
181-
"Use burn_block_data to write it back to another chip.",
191+
help="The path to the file in which to save the dump, if not specified, output to the console.",
192+
default=sys.stdout,
182193
)
183194

184195
summary_cmd = subparsers.add_parser(
@@ -379,23 +390,48 @@ def summary(esp, efuses, args):
379390

380391
def dump(esp, efuses, args):
381392
"""Dump raw efuse data registers"""
382-
# Using --debug option allows to print dump.
383-
# Nothing to do here. The log will be printed
384-
# during EspEfuses.__init__() in self.read_blocks()
385-
if args.file_name:
386-
# save dump to the file
393+
dump_file = args.file_name
394+
to_console = args.file_name == sys.stdout
395+
396+
def output_block_to_file(block, f, to_console):
397+
block_dump = BitStream(block.get_bitstring())
398+
block_dump.byteswap()
399+
if to_console:
400+
f.write(block_dump.hex + "\n")
401+
else:
402+
block_dump.tofile(f)
403+
404+
if args.format == "default":
405+
if to_console:
406+
# for "espefuse.py dump" cmd
407+
for block in efuses.blocks:
408+
block.print_block(block.get_bitstring(), "dump", debug=True)
409+
return
410+
else:
411+
# for back compatibility to support "espefuse.py dump --file_name dump.bin"
412+
args.format = "separated"
413+
414+
if args.format == "separated":
415+
# each efuse block is placed in a separate file
387416
for block in efuses.blocks:
388-
file_dump_name = args.file_name
389-
place_for_index = file_dump_name.find(".bin")
390-
file_dump_name = (
391-
file_dump_name[:place_for_index]
392-
+ str(block.id)
393-
+ file_dump_name[place_for_index:]
394-
)
395-
print(file_dump_name)
396-
with open(file_dump_name, "wb") as f:
397-
block.get_bitstring().byteswap()
398-
block.get_bitstring().tofile(f)
417+
if not to_console:
418+
file_dump_name = args.file_name
419+
fname, fextension = os.path.splitext(file_dump_name)
420+
file_dump_name = f"{fname}{block.id}{fextension}"
421+
print(f"Dump efuse block{block.id} -> {file_dump_name}")
422+
dump_file = open(file_dump_name, "wb")
423+
output_block_to_file(block, dump_file, to_console)
424+
if not to_console:
425+
dump_file.close()
426+
elif args.format == "united":
427+
# all efuse blocks are stored in one file
428+
if not to_console:
429+
print(f"Dump efuse blocks -> {args.file_name}")
430+
dump_file = open(args.file_name, "wb")
431+
for block in efuses.blocks:
432+
output_block_to_file(block, dump_file, to_console)
433+
if not to_console:
434+
dump_file.close()
399435

400436

401437
def burn_efuse(esp, efuses, args):

espefuse/efuse/esp32/emulate_efuse_controller.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,7 @@ def read_reg(self, addr):
3838
if addr == self.REGS.APB_CTL_DATE_ADDR:
3939
return self.REGS.APB_CTL_DATE_V << self.REGS.APB_CTL_DATE_S
4040
else:
41-
val = 0
42-
if addr == self.REGS.EFUSE_BLK0_RDATA3_REG:
43-
val = self.REGS.EFUSE_RD_CHIP_VER_REV1
44-
if addr == self.REGS.EFUSE_BLK0_RDATA5_REG:
45-
val = self.REGS.EFUSE_RD_CHIP_VER_REV2
46-
return val | super(EmulateEfuseController, self).read_reg(addr)
41+
return super(EmulateEfuseController, self).read_reg(addr)
4742

4843
""" << esptool method end """
4944

test/test_espefuse.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ def setup_method(self):
7373
f"{sys.executable} -m espefuse --chip {arg_chip} "
7474
f"--virt --path-efuse-file {self.efuse_file.name} -d"
7575
)
76+
self._set_target_wafer_version()
7677
else:
7778
self.base_cmd = (
7879
f"{sys.executable} -m espefuse --chip {arg_chip} "
@@ -117,6 +118,11 @@ def _set_34_coding_scheme(self):
117118
def _set_none_recovery_coding_scheme(self):
118119
self.espefuse_py("burn_efuse CODING_SCHEME 3")
119120

121+
def _set_target_wafer_version(self):
122+
# ESP32 has to be ECO3 (v3.0) for tests
123+
if arg_chip == "esp32":
124+
self.espefuse_py("burn_efuse CHIP_VER_REV1 1 CHIP_VER_REV2 1")
125+
120126
def check_data_block_in_log(
121127
self, log, file_path, repeat=1, reverse_order=False, offset=0
122128
):
@@ -177,6 +183,18 @@ def test_dump(self):
177183
self.espefuse_py("dump -h")
178184
self.espefuse_py("dump")
179185

186+
def test_dump_format_united(self):
187+
tmp_file = tempfile.NamedTemporaryFile(delete=False)
188+
self.espefuse_py(f"dump --format united --file_name {tmp_file.name}")
189+
190+
def test_dump_separated_default(self):
191+
tmp_file = tempfile.NamedTemporaryFile(delete=False)
192+
self.espefuse_py(f"dump --file_name {tmp_file.name}")
193+
194+
def test_dump_separated(self):
195+
tmp_file = tempfile.NamedTemporaryFile(delete=False)
196+
self.espefuse_py(f"dump --format separated --file_name {tmp_file.name}")
197+
180198
def test_summary(self):
181199
self.espefuse_py("summary -h")
182200
self.espefuse_py("summary")

0 commit comments

Comments
 (0)