Skip to content

Commit

Permalink
Merge branch 'espressif:master' into main_work
Browse files Browse the repository at this point in the history
  • Loading branch information
Jason2866 authored May 3, 2024
2 parents b103dcc + 1deb1c6 commit 7f9b1ec
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 30 deletions.
4 changes: 3 additions & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,10 @@ host_tests_hsm:
PYTEST_ADDOPTS: "-sv --junitxml=test/report.xml --color=yes"
before_script:
- apt-get update
- apt-get install -y python3 python3-pip softhsm2
- apt-get install -y python3 python3-pip python3-venv softhsm2
- ./ci/setup_softhsm2.sh || exit 1
- python3 -m venv esptoolenv
- source esptoolenv/bin/activate
- pip3 install -e .[dev,hsm] --prefer-binary
script:
- coverage run --parallel-mode -m pytest ${CI_PROJECT_DIR}/test/test_espsecure_hsm.py
Expand Down
36 changes: 34 additions & 2 deletions docs/en/espefuse/summary-cmd.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
-------------------
Expand Down Expand Up @@ -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)
2 changes: 1 addition & 1 deletion docs/en/esptool/flashing-firmware.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Flashing Firmware
Esptool is used under the hood of many development frameworks for Espressif SoCs, such as `ESP-IDF <https://docs.espressif.com/projects/esp-idf/>`_, `Arduino <https://docs.espressif.com/projects/arduino-esp32/>`_, or `PlatformIO <https://docs.platformio.org/en/latest/platforms/espressif32.html>`_.
After the resulting firmware binary files are compiled, esptool is used to flash these into the device.

Sometimes there might be a need to comfortably flash a bigger amount of decives with the same binaries or to share flashing instructions with a third party.
Sometimes there might be a need to comfortably flash a bigger amount of devices with the same binaries or to share flashing instructions with a third party.
It is possible to compile the firmware just once and then repeatedly use esptool (manually or :ref:`in a custom script <scripting>`) to flash the files.

Sharing these instructions and below mentioned assets with a third party (for example a manufacturer) should suffice to allow reproducible and quick flashing of your application into an Espressif chip.
Expand Down
74 changes: 49 additions & 25 deletions espefuse/efuse/base_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def check_efuse_name(efuse_name, efuse_list):
summary_cmd.add_argument(
"--format",
help="Select the summary format",
choices=["summary", "json"],
choices=["summary", "json", "value_only"],
default="summary",
)
summary_cmd.add_argument(
Expand All @@ -191,6 +191,11 @@ def check_efuse_name(efuse_name, efuse_list):
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."
Expand Down Expand Up @@ -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)",
Expand All @@ -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 = ""
Expand Down Expand Up @@ -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(),
Expand All @@ -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,
Expand All @@ -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("")

Expand Down
2 changes: 1 addition & 1 deletion esptool/cmds.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def detect_chip(
else:
err_msg = f"Unexpected chip ID value {chip_id}."
except (UnsupportedCommandError, struct.error, FatalError) as e:
# UnsupportedCommmanddError: ESP8266/ESP32 ROM
# UnsupportedCommandError: ESP8266/ESP32 ROM
# struct.error: ESP32-S2
# FatalError: ESP8266/ESP32 STUB
print(" Unsupported detection protocol, switching and trying again...")
Expand Down
9 changes: 9 additions & 0 deletions test/test_espefuse.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,15 @@ def test_summary(self):
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"
)
Expand Down

0 comments on commit 7f9b1ec

Please sign in to comment.