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 7, 2024
2 parents 2356b18 + 1deb1c6 commit 7014093
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 33 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 espefuse/efuse/esp32c5/mem_definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class EfuseDefineRegisters(EfuseRegistersBase):
EFUSE_MEM_SIZE = 0x01FC + 4

# EFUSE registers & command/conf values
DR_REG_EFUSE_BASE = 0x600B0800
DR_REG_EFUSE_BASE = 0x600B4800
EFUSE_PGM_DATA0_REG = DR_REG_EFUSE_BASE
EFUSE_CHECK_VALUE0_REG = DR_REG_EFUSE_BASE + 0x020
EFUSE_CLK_REG = DR_REG_EFUSE_BASE + 0x1C8
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
12 changes: 10 additions & 2 deletions esptool/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,8 @@ class ESPLoader(object):
Don't instantiate this base class directly, either instantiate a subclass or
call cmds.detect_chip() which will interrogate the chip and return the
appropriate subclass instance.
appropriate subclass instance. You can also use a context manager as
"with detect_chip() as esp:" to ensure the serial port is closed when done.
"""

Expand Down Expand Up @@ -281,7 +282,8 @@ def __init__(self, port=DEFAULT_PORT, baud=ESP_ROM_BAUD, trace_enabled=False):
"""Base constructor for ESPLoader bootloader interaction
Don't call this constructor, either instantiate a specific
ROM class directly, or use cmds.detect_chip().
ROM class directly, or use cmds.detect_chip(). You can use the with
statement to ensure the serial port is closed when done.
This base class has all of the instance methods for bootloader
functionality supported across various chips & stub
Expand Down Expand Up @@ -365,6 +367,12 @@ def __init__(self, port=DEFAULT_PORT, baud=ESP_ROM_BAUD, trace_enabled=False):
# need to set the property back to None or it will continue to fail
self._port.write_timeout = None

def __enter__(self):
return self

def __exit__(self, exc_type, exc_value, traceback):
self._port.close()

@property
def serial_port(self):
return self._port.port
Expand Down
2 changes: 2 additions & 0 deletions esptool/targets/esp32c5.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ class ESP32C5ROM(ESP32C6ROM):
CHIP_NAME = "ESP32-C5"
IMAGE_CHIP_ID = 23

EFUSE_BASE = 0x600B4800

IROM_MAP_START = 0x42000000
IROM_MAP_END = 0x42800000
DROM_MAP_START = 0x42800000
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 7014093

Please sign in to comment.