mirror of
https://github.com/espressif/esptool.git
synced 2025-10-16 14:28:54 +08:00
feat(espefuse): Allow filtering efuses based on command line arguments
This commit is contained in:
@@ -3,12 +3,16 @@
|
||||
Summary
|
||||
=======
|
||||
|
||||
The ``espefuse.py summary`` command reads all eFuses from the chip and outputs them in text or json format. It is also possible to save it to a file.
|
||||
The ``espefuse.py summary`` command reads the eFuses from the chip and outputs them in text or json format. It is also possible to save it to a file. The command also supports eFuse filtering by name.
|
||||
|
||||
Optional arguments:
|
||||
|
||||
- ``--format`` - Select the summary format: ``summary`` - text format (default option), ``json`` - json format. Usage ``--format json``.
|
||||
- ``--format`` - Select the summary format:
|
||||
- ``summary`` - text format (default option).
|
||||
- ``json`` - json format. Usage ``--format json``.
|
||||
- ``value_only`` - only the value of the eFuse specified as an argument will be displayed. For more information, refer to the :ref:`Filtering eFuses <filtering-eFuses>` section.
|
||||
- ``--file`` - File to save the efuse summary. Usage ``--file efuses.json``.
|
||||
- List of eFuses to filter. For more information, refer to the :ref:`Filtering eFuses <filtering-eFuses>` section.
|
||||
|
||||
Text Format Summary
|
||||
-------------------
|
||||
@@ -112,3 +116,31 @@ Save Json Format Summary To File
|
||||
|
||||
=== Run "summary" command ===
|
||||
Saving efuse values to efuses.json
|
||||
|
||||
.. _filtering-eFuses:
|
||||
|
||||
Filtering Efuses and Displaying Only the Value
|
||||
----------------------------------------------
|
||||
|
||||
The ``espefuse.py summary`` command supports filtering eFuses by name. The eFuses to filter needs to be specified as positional arguments. If no eFuses are specified, complete summary will be displayed. Example:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
> espefuse.py summary ABS_DONE_0 BLOCK1
|
||||
|
||||
=== Run "summary" command ===
|
||||
EFUSE_NAME (Block) Description = [Meaningful Value] [Readable/Writeable] (Hex Value)
|
||||
----------------------------------------------------------------------------------------
|
||||
Security fuses:
|
||||
ABS_DONE_0 (BLOCK0) Secure boot V1 is enabled for bootloader image = False R/W (0b0)
|
||||
BLOCK1 (BLOCK1) Flash encryption key
|
||||
= 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W
|
||||
|
||||
If ``--format value_only`` is specified, only the value of the eFuse specified as an argument will be displayed. Only one eFuse can be specified as an argument for this format. Example:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
> espefuse.py summary --format value_only MAC
|
||||
|
||||
=== Run "summary" command ===
|
||||
00:00:00:00:00:00 (CRC 0x00 OK)
|
||||
|
@@ -182,7 +182,7 @@ def add_common_commands(subparsers, efuses):
|
||||
summary_cmd.add_argument(
|
||||
"--format",
|
||||
help="Select the summary format",
|
||||
choices=["summary", "json"],
|
||||
choices=["summary", "json", "value_only"],
|
||||
default="summary",
|
||||
)
|
||||
summary_cmd.add_argument(
|
||||
@@ -191,6 +191,11 @@ def add_common_commands(subparsers, efuses):
|
||||
type=argparse.FileType("w"),
|
||||
default=sys.stdout,
|
||||
)
|
||||
summary_cmd.add_argument(
|
||||
"efuses_to_show",
|
||||
help="The efuses to show. If not provided, all efuses will be shown.",
|
||||
nargs="*",
|
||||
)
|
||||
|
||||
execute_scripts = subparsers.add_parser(
|
||||
"execute_scripts", help="Executes scripts to burn at one time."
|
||||
@@ -245,14 +250,21 @@ def add_show_sensitive_info_option(p):
|
||||
|
||||
|
||||
def summary(esp, efuses, args):
|
||||
"""Print a human-readable summary of efuse contents"""
|
||||
"""Print a human-readable or json summary of efuse contents"""
|
||||
ROW_FORMAT = "%-50s %-50s%s = %s %s %s"
|
||||
human_output = args.format == "summary"
|
||||
human_output = args.format in ["summary", "value_only"]
|
||||
value_only = args.format == "value_only"
|
||||
if value_only and len(args.efuses_to_show) != 1:
|
||||
raise esptool.FatalError(
|
||||
"The 'value_only' format can be used exactly for one efuse."
|
||||
)
|
||||
do_filtering = bool(args.efuses_to_show)
|
||||
json_efuse = {}
|
||||
summary_efuse = []
|
||||
if args.file != sys.stdout:
|
||||
print("Saving efuse values to " + args.file.name)
|
||||
if human_output:
|
||||
print(
|
||||
if human_output and not value_only:
|
||||
summary_efuse.append(
|
||||
ROW_FORMAT.replace("-50", "-12")
|
||||
% (
|
||||
"EFUSE_NAME (Block)",
|
||||
@@ -261,13 +273,12 @@ def summary(esp, efuses, args):
|
||||
"[Meaningful Value]",
|
||||
"[Readable/Writeable]",
|
||||
"(Hex Value)",
|
||||
),
|
||||
file=args.file,
|
||||
)
|
||||
)
|
||||
print("-" * 88, file=args.file)
|
||||
summary_efuse.append("-" * 88)
|
||||
for category in sorted(set(e.category for e in efuses), key=lambda c: c.title()):
|
||||
if human_output:
|
||||
print("%s fuses:" % category.title(), file=args.file)
|
||||
if human_output and not value_only:
|
||||
summary_efuse.append(f"{category.title()} fuses:")
|
||||
for e in (e for e in efuses if e.category == category):
|
||||
if e.efuse_type.startswith("bytes"):
|
||||
raw = ""
|
||||
@@ -296,8 +307,12 @@ def summary(esp, efuses, args):
|
||||
value = "".join(v)
|
||||
else:
|
||||
value = value.replace("0", "?")
|
||||
if human_output:
|
||||
print(
|
||||
if (
|
||||
human_output
|
||||
and (not do_filtering or e.name in args.efuses_to_show)
|
||||
and not value_only
|
||||
):
|
||||
summary_efuse.append(
|
||||
ROW_FORMAT
|
||||
% (
|
||||
e.get_info(),
|
||||
@@ -306,18 +321,20 @@ def summary(esp, efuses, args):
|
||||
value,
|
||||
perms,
|
||||
raw,
|
||||
),
|
||||
file=args.file,
|
||||
)
|
||||
)
|
||||
desc_len = len(e.description[50:])
|
||||
if desc_len:
|
||||
desc_len += 50
|
||||
for i in range(50, desc_len, 50):
|
||||
print(
|
||||
"%-50s %-50s" % ("", e.description[i : (50 + i)]),
|
||||
file=args.file,
|
||||
summary_efuse.append(
|
||||
f"{'':<50} {e.description[i : (50 + i)]:<50}"
|
||||
)
|
||||
if args.format == "json":
|
||||
elif human_output and value_only and e.name in args.efuses_to_show:
|
||||
summary_efuse.append(f"{value}")
|
||||
elif args.format == "json" and (
|
||||
not do_filtering or e.name in args.efuses_to_show
|
||||
):
|
||||
json_efuse[e.name] = {
|
||||
"name": e.name,
|
||||
"value": base_value if readable else value,
|
||||
@@ -331,19 +348,26 @@ def summary(esp, efuses, args):
|
||||
"efuse_type": e.efuse_type,
|
||||
"bit_len": e.bit_len,
|
||||
}
|
||||
if human_output:
|
||||
print("", file=args.file)
|
||||
if human_output:
|
||||
print(efuses.summary(), file=args.file)
|
||||
if human_output and not value_only:
|
||||
# Remove empty category if efuses are filtered and there are none to show
|
||||
if do_filtering and summary_efuse[-1] == f"{category.title()} fuses:":
|
||||
summary_efuse.pop()
|
||||
else:
|
||||
summary_efuse.append("")
|
||||
if human_output and not value_only:
|
||||
summary_efuse.append(efuses.summary())
|
||||
warnings = efuses.get_coding_scheme_warnings()
|
||||
if warnings:
|
||||
print(
|
||||
"WARNING: Coding scheme has encoding bit error warnings", file=args.file
|
||||
summary_efuse.append(
|
||||
"WARNING: Coding scheme has encoding bit error warnings"
|
||||
)
|
||||
if human_output:
|
||||
for line in summary_efuse:
|
||||
print(line, file=args.file)
|
||||
if args.file != sys.stdout:
|
||||
args.file.close()
|
||||
print("Done")
|
||||
if args.format == "json":
|
||||
elif args.format == "json":
|
||||
json.dump(json_efuse, args.file, sort_keys=True, indent=4)
|
||||
print("")
|
||||
|
||||
|
@@ -184,6 +184,15 @@ class TestReadCommands(EfuseTestCase):
|
||||
def test_summary_json(self):
|
||||
self.espefuse_py("summary --format json")
|
||||
|
||||
def test_summary_filter(self):
|
||||
self.espefuse_py("summary MAC")
|
||||
self.espefuse_py("summary --format value_only MAC")
|
||||
self.espefuse_py(
|
||||
"summary --format value_only MAC WR_DIS",
|
||||
check_msg="The 'value_only' format can be used exactly for one efuse.",
|
||||
ret_code=2,
|
||||
)
|
||||
|
||||
@pytest.mark.skipif(
|
||||
arg_chip == "esp32p4", reason="No Custom MAC Address defined yet"
|
||||
)
|
||||
|
Reference in New Issue
Block a user