From 950428c2f40c8122774fc38d68cd07f61e6ef301 Mon Sep 17 00:00:00 2001 From: Jan Beran Date: Fri, 7 Jun 2024 13:44:23 +0200 Subject: [PATCH] feat(tools): Add often used espefuse subcommands to idf.py --- docs/en/api-guides/flash_psram_config.rst | 4 +- .../jtag-debugging/configure-other-jtag.rst | 2 +- docs/en/api-reference/peripherals/ecdsa.rst | 6 +- docs/en/api-reference/peripherals/hmac.rst | 2 +- .../peripherals/sd_pullup_requirements.rst | 8 +- docs/en/api-reference/protocols/esp_tls.rst | 2 +- .../api-reference/storage/nvs_encryption.rst | 2 +- docs/en/api-reference/system/efuse.rst | 16 +- .../system/inc/espefuse_summary_ESP32-C2.rst | 14 +- .../system/inc/espefuse_summary_ESP32-C3.rst | 22 +- .../system/inc/espefuse_summary_ESP32-C6.rst | 14 +- .../system/inc/espefuse_summary_ESP32-H2.rst | 15 +- .../system/inc/espefuse_summary_ESP32-P4.rst | 15 +- .../system/inc/espefuse_summary_ESP32-S2.rst | 22 +- .../system/inc/espefuse_summary_ESP32-S3.rst | 30 +- .../system/inc/espefuse_summary_ESP32.rst | 22 +- docs/en/security/flash-encryption.rst | 40 +- docs/en/security/secure-boot-v1.rst | 4 +- examples/system/efuse/CMakeLists.txt | 2 +- tools/idf_py_actions/serial_ext.py | 374 +++++++++++++++--- tools/test_build_system/test_common.py | 2 +- 21 files changed, 436 insertions(+), 182 deletions(-) diff --git a/docs/en/api-guides/flash_psram_config.rst b/docs/en/api-guides/flash_psram_config.rst index 07fa5e28ed..01587b2062 100644 --- a/docs/en/api-guides/flash_psram_config.rst +++ b/docs/en/api-guides/flash_psram_config.rst @@ -237,7 +237,7 @@ Error Handling load:0x3fcd0108,len:0x171c ets_loader.c 78 - this may mean that the necessary efuses are not correctly burnt. Please check the eFuse bits of the chip using command ``espefuse.py summary``. + this may mean that the necessary eFuses are not correctly burnt. Please check the eFuse bits of the chip using ``idf.py efuse-summary``. The ROM bootloader relies on an eFuse bit ``FLASH_TYPE`` to reset the flash into the default mode (SPI mode). If this bit is not burnt and the flash is working in OPI mode, ROM bootloader may not be able to read from the flash and load the following images. @@ -257,7 +257,7 @@ Here is a method to burn the eFuse bit: .. code-block:: python - python3 ./espefuse.py -p /dev/ --do-not-confirm burn_efuse FLASH_TYPE 1 + idf.py -p PORT efuse-burn --do-not-confirm FLASH_TYPE 1 .. note:: diff --git a/docs/en/api-guides/jtag-debugging/configure-other-jtag.rst b/docs/en/api-guides/jtag-debugging/configure-other-jtag.rst index 69c951ae00..e3c95d1be5 100644 --- a/docs/en/api-guides/jtag-debugging/configure-other-jtag.rst +++ b/docs/en/api-guides/jtag-debugging/configure-other-jtag.rst @@ -12,7 +12,7 @@ For guidance about which JTAG interface to select when using OpenOCD with {IDF_T Configure eFuses ^^^^^^^^^^^^^^^^ - By default, {IDF_TARGET_NAME} JTAG interface is connected to the :doc:`built-in USB_SERIAL_JTAG peripheral `. To use an external JTAG adapter instead, you need to switch the JTAG interface to the GPIO pins. This can be done by burning eFuses using ``espefuse.py`` tool. + By default, {IDF_TARGET_NAME} JTAG interface is connected to the :doc:`built-in USB_SERIAL_JTAG peripheral `. To use an external JTAG adapter instead, you need to switch the JTAG interface to the GPIO pins. This can be done by burning eFuses using ``idf.py`` tool. .. only:: esp32c3 diff --git a/docs/en/api-reference/peripherals/ecdsa.rst b/docs/en/api-reference/peripherals/ecdsa.rst index 4b5f1da5b7..06f8a8a505 100644 --- a/docs/en/api-reference/peripherals/ecdsa.rst +++ b/docs/en/api-reference/peripherals/ecdsa.rst @@ -22,11 +22,11 @@ ECDSA on {IDF_TARGET_NAME} On {IDF_TARGET_NAME}, the ECDSA module works with a secret key burnt into an eFuse block. This eFuse key is made completely inaccessible (default mode) for any resources outside the cryptographic modules, thus avoiding key leakage. -ECDSA key can be programmed externally through ``espefuse.py`` script using: +ECDSA key can be programmed externally through ``idf.py`` script. Here is an example of how to program the ECDSA key: .. code:: bash - espefuse.py burn_key ECDSA_KEY + idf.py efuse-burn-key ECDSA_KEY .. only:: SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK @@ -63,7 +63,7 @@ Following code snippet uses :cpp:func:`esp_efuse_write_key` to set physical key .. only:: SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE - Determinisitic Signature Generation + Deterministic Signature Generation ----------------------------------- The ECDSA peripheral of {IDF_TARGET_NAME} also supports generation of deterministic signatures using deterministic derivation of the parameter K as specified in the `RFC 6979 `_ section 3.2. diff --git a/docs/en/api-reference/peripherals/hmac.rst b/docs/en/api-reference/peripherals/hmac.rst index 6a2e547231..b000899947 100644 --- a/docs/en/api-reference/peripherals/hmac.rst +++ b/docs/en/api-reference/peripherals/hmac.rst @@ -98,7 +98,7 @@ Following is the procedure to re-enable the JTAG: **Stage 1: Setup** 1. Generate a 256-bit HMAC secret key to use for JTAG re-enable. -2. Write the key to an eFuse block with key purpose HMAC_DOWN_ALL (5) or HMAC_DOWN_JTAG (6). This can be done using the ``esp_efuse_write_key()`` function in the firmware or using ``espefuse.py`` from the host. +2. Write the key to an eFuse block with key purpose HMAC_DOWN_ALL (5) or HMAC_DOWN_JTAG (6). This can be done using the ``esp_efuse_write_key()`` function in the firmware or using ``idf.py efuse-burn-key`` from the host. 3. Configure the eFuse key block to be read-protected using the ``esp_efuse_set_read_protect()``, so that software cannot read back the value. 4. Burn the ``soft JTAG disable`` bit/bits on {IDF_TARGET_NAME}. This will permanently disable JTAG unless the correct key value is provided by the software. diff --git a/docs/en/api-reference/peripherals/sd_pullup_requirements.rst b/docs/en/api-reference/peripherals/sd_pullup_requirements.rst index cefd8acf12..399d5f424a 100644 --- a/docs/en/api-reference/peripherals/sd_pullup_requirements.rst +++ b/docs/en/api-reference/peripherals/sd_pullup_requirements.rst @@ -199,7 +199,7 @@ If you use a development board without pull-ups, you can do the following: Burning eFuses is irreversible! The issue list above might be out of date, so please make sure that the module you are burning has a 3.3 V flash chip by checking the information on https://www.espressif.com/. If you burn the 3.3 V eFuses on a module with a 1.8 V flash chip, the module will stop functioning. - If you are sure that you need to irreversibly burn eFuses, go to your ESP-IDF directory and run the following command: + If you are sure that you need to irreversibly burn eFuses, go to your ESP-IDF directory and run the following command using ``espefuse.py`` tool: .. code-block:: bash @@ -221,9 +221,11 @@ If you use a development board without pull-ups, you can do the following: To check the status of the eFuses, run:: - ``components/esptool_py/esptool/espefuse.py summary`` + .. code-block:: - If running from an automated flashing script, ``espefuse.py`` has an option ``--do-not-confirm``. + idf.py efuse-summary + + If running from an automated flashing script, it is better to use standalone eFuse tool, ``espefuse.py``. This tool also has an option ``--do-not-confirm`` to burn eFuses without confirmation. For more details, see **{IDF_TARGET_NAME} Technical Reference Manual** [`PDF <{IDF_TARGET_TRM_EN_URL}#efuse>`__]. diff --git a/docs/en/api-reference/protocols/esp_tls.rst b/docs/en/api-reference/protocols/esp_tls.rst index a1ba508c2e..d4937a9619 100644 --- a/docs/en/api-reference/protocols/esp_tls.rst +++ b/docs/en/api-reference/protocols/esp_tls.rst @@ -208,7 +208,7 @@ The following table shows a typical comparison between WolfSSL and MbedTLS when ECDSA Peripheral with ESP-TLS ----------------------------- - ESP-TLS provides support for using the ECDSA peripheral with {IDF_TARGET_NAME}. The use of ECDSA peripheral is supported only when ESP-TLS is used with MbedTLS as its underlying SSL/TLS stack. The ECDSA private key should be present in the eFuse for using the ECDSA peripheral. Please refer to `espefuse.py `__ documentation for programming the ECDSA key in the efuse. + ESP-TLS provides support for using the ECDSA peripheral with {IDF_TARGET_NAME}. The use of ECDSA peripheral is supported only when ESP-TLS is used with MbedTLS as its underlying SSL/TLS stack. The ECDSA private key should be present in the eFuse for using the ECDSA peripheral. Please refer to :doc:`ECDSA Guide <../peripherals/ecdsa>` for programming the ECDSA key in the eFuse. To use ECDSA peripheral with ESP-TLS, set :cpp:member:`esp_tls_cfg_t::use_ecdsa_peripheral` to `true`, and set :cpp:member:`esp_tls_cfg_t::ecdsa_key_efuse_blk` to the eFuse block ID in which ECDSA private key is stored. This will enable the use of ECDSA peripheral for private key operations. As the client private key is already present in the eFuse, it needs not be supplied to the :cpp:type:`esp_tls_cfg_t` structure. diff --git a/docs/en/api-reference/storage/nvs_encryption.rst b/docs/en/api-reference/storage/nvs_encryption.rst index ad6f9cc474..e76a446f81 100644 --- a/docs/en/api-reference/storage/nvs_encryption.rst +++ b/docs/en/api-reference/storage/nvs_encryption.rst @@ -122,7 +122,7 @@ It is possible for an application to use different keys for different NVS partit .. note:: Users can program their own HMAC key in eFuse block beforehand by using the following command: :: - espefuse.py -p PORT burn_key HMAC_UP + idf.py -p PORT efuse-burn-key HMAC_UP Encrypted Read/Write -------------------- diff --git a/docs/en/api-reference/system/efuse.rst b/docs/en/api-reference/system/efuse.rst index d56b86d5f0..fe3ad95633 100644 --- a/docs/en/api-reference/system/efuse.rst +++ b/docs/en/api-reference/system/efuse.rst @@ -10,6 +10,11 @@ Introduction The eFuse Manager library is designed to structure access to eFuse bits and make using these easy. This library operates eFuse bits by a structure name which is assigned in eFuse table. This sections introduces some concepts used by eFuse Manager. +eFuse Manager vs idf.py +----------------------- + +idf.py provides a subset of the functionality of the eFuse Manager via the ``idf.py efuse-`` commands. In this documentation, mostly ``idf.py`` based commands will be used, although you can still see some ``espefuse.py`` based commands for advanced or rare cases. To see all available commands, run ``idf.py --help`` and search for those prefixed with ``efuse-``. + Hardware Description -------------------- @@ -226,7 +231,7 @@ Supported Coding Scheme You can find out the coding scheme of your chip: - * run a ``espefuse.py -p PORT summary`` command. + * run a ``idf.py efuse-summary`` command. * from ``esptool`` utility logs (during flashing). * calling the function in the code :cpp:func:`esp_efuse_get_coding_scheme` for the EFUSE_BLK3 block. @@ -351,7 +356,7 @@ The eFuses bit order is little endian (see the example below), it means that eFu .. code-block:: none - $ espefuse.py dump + $ idf.py efuse-dump USER_DATA (BLOCK3 ) [3 ] read_regs: 03020100 07060504 0B0A0908 0F0E0D0C 13121111 17161514 1B1A1918 1F1E1D1C BLOCK4 (BLOCK4 ) [4 ] read_regs: 03020100 07060504 0B0A0908 0F0E0D0C 13121111 17161514 1B1A1918 1F1E1D1C @@ -440,7 +445,7 @@ The json string has the following properties: }, } -These functions can be used from a top-level project ``CMakeLists.txt`` (:example_file:`get-started/hello_world/CMakeLists.txt`): +These functions can be used from a top-level project ``CMakeLists.txt`` (:example_file:`system/efuse/CMakeLists.txt`): .. code-block:: cmake @@ -451,13 +456,13 @@ These functions can be used from a top-level project ``CMakeLists.txt`` (:exampl espefuse_get_efuse(ret_data ${efuse_json} "MAC" "value") message("MAC:" ${ret_data}) -The format of the ``value`` property is the same as shown in ``espefuse.py summary``. +The format of the ``value`` property is the same as shown in ``espefuse.py summary`` or ``idf.py efuse-summary``. .. code-block:: none MAC:94:b9:7e:5a:6e:58 (CRC 0xe2 OK) -There is an example test :example_file:`system/efuse/CMakeLists.txt` which adds a custom target ``efuse-summary``. This allows you to run the ``idf.py efuse-summary`` command to read the required eFuses (specified in the ``efuse_names`` list) at any time, not just at project build time. +There is an example test :example_file:`system/efuse/CMakeLists.txt` which adds a custom target ``efuse-filter``. This allows you to run the ``idf.py efuse-filter`` command to read the required eFuses (specified in the ``efuse_names`` list) at any time, not just during the project build. Debug eFuse & Unit Tests ------------------------ @@ -482,6 +487,7 @@ Flash Encryption (FE) is a hardware feature that requires the physical burning o ^^^^^^^^^^^^^^^ esptool includes a useful tool for reading/writing {IDF_TARGET_NAME} eFuse bits - `espefuse.py `_. +Part of the functionality of this tool is also provided directly by ``idf.py`` commands. For example, the ``idf.py efuse-summary`` command is equivalent to ``espefuse.py summary``. .. include:: inc/espefuse_summary_{IDF_TARGET_NAME}.rst diff --git a/docs/en/api-reference/system/inc/espefuse_summary_ESP32-C2.rst b/docs/en/api-reference/system/inc/espefuse_summary_ESP32-C2.rst index e8ed1c0bbf..e2a2b5e8b7 100644 --- a/docs/en/api-reference/system/inc/espefuse_summary_ESP32-C2.rst +++ b/docs/en/api-reference/system/inc/espefuse_summary_ESP32-C2.rst @@ -1,12 +1,10 @@ .. code-block:: none - espefuse.py -p PORT summary + idf.py efuse-summary - espefuse.py v4.6-dev - Connecting.... - Detecting chip type... ESP32-C2 + Executing action: efuse-summary + (...) - === Run "summary" command === EFUSE_NAME (Block) Description = [Meaningful Value] [Readable/Writeable] (Hex Value) ---------------------------------------------------------------------------------------- Calibration fuses: @@ -90,11 +88,13 @@ To get a dump for all eFuse registers. .. code-block:: none - espefuse.py -p PORT dump + idf.py efuse-dump + Executing action: efuse-dump + Running espefuse.py in directory + Executing "espefuse.py dump --chip esp32c2"... espefuse.py v4.6-dev Connecting.... - Detecting chip type... ESP32-C2 BLOCK0 (BLOCK0 ) [0 ] read_regs: 00000000 00000000 BLOCK1 (BLOCK1 ) [1 ] read_regs: 00000000 00000000 00000000 BLOCK2 (BLOCK2 ) [2 ] read_regs: 8d5c4b94 8252083a 5c01e953 80d0a824 c0860b18 00006890 00000000 4b000000 diff --git a/docs/en/api-reference/system/inc/espefuse_summary_ESP32-C3.rst b/docs/en/api-reference/system/inc/espefuse_summary_ESP32-C3.rst index 9e6dfcbf17..e011f99177 100644 --- a/docs/en/api-reference/system/inc/espefuse_summary_ESP32-C3.rst +++ b/docs/en/api-reference/system/inc/espefuse_summary_ESP32-C3.rst @@ -1,12 +1,10 @@ .. code-block:: none - espefuse.py -p PORT summary + idf.py efuse-summary - espefuse.py v4.6-dev - Connecting.... - Detecting chip type... ESP32-C3 + Executing action: efuse-summary + (...) - === Run "summary" command === EFUSE_NAME (Block) Description = [Meaningful Value] [Readable/Writeable] (Hex Value) ---------------------------------------------------------------------------------------- Calibration fuses: @@ -80,8 +78,8 @@ oot_mode[3:0] is 0; 1; 2; 3; 6; 7) DIS_FORCE_DOWNLOAD (BLOCK0) Set this bit to disable the function that forces c = False R/W (0b0) hip into download mode - DIS_DOWNLOAD_MANUAL_ENCRYPT (BLOCK0) Set this bit to disable flash encryption when in d = False R/W (0b0) - ownload boot modes + DIS_DOWNLOAD_MANUAL_ENCRYPT (BLOCK0) Set this bit to disable flash encryption when in = False R/W (0b0) + download boot modes SPI_BOOT_CRYPT_CNT (BLOCK0) Enables flash encryption when 1 or 3 bits are set = Disable R/W (0b000) and disables otherwise SECURE_BOOT_KEY_REVOKE0 (BLOCK0) Revoke 1st secure boot key = False R/W (0b0) @@ -99,8 +97,8 @@ DIS_DOWNLOAD_MODE (BLOCK0) Set this bit to disable download mode (boot_mode[3 = False R/W (0b0) :0] = 0; 1; 2; 3; 6; 7) ENABLE_SECURITY_DOWNLOAD (BLOCK0) Set this bit to enable secure UART download mode = False R/W (0b0) - SECURE_VERSION (BLOCK0) Secure version (used by ESP-IDF anti-rollback feat = 0 R/W (0x0000) - ure) + SECURE_VERSION (BLOCK0) Secure version (used by ESP-IDF anti-rollback = 0 R/W (0x0000) + feature) BLOCK_KEY0 (BLOCK4) Purpose: USER Key0 or user data @@ -159,11 +157,13 @@ To get a dump for all eFuse registers. .. code-block:: none - espefuse.py -p PORT dump + idf.py efuse-dump + Executing action: efuse-dump + Running espefuse.py in directory + Executing "espefuse.py dump --chip esp32c3"... espefuse.py v4.6-dev Connecting.... - Detecting chip type... ESP32-C3 BLOCK0 ( ) [0 ] read_regs: 00000000 00000000 00000000 00000000 80000000 00000000 MAC_SPI_8M_0 (BLOCK1 ) [1 ] read_regs: 790f968c 000058cf 00000000 020c0000 715424e0 0047d2f2 BLOCK_SYS_DATA (BLOCK2 ) [2 ] read_regs: 96046025 6f41fdc3 512cedbe 217ee31d d864ea41 5aba3a86 1e260363 00000009 diff --git a/docs/en/api-reference/system/inc/espefuse_summary_ESP32-C6.rst b/docs/en/api-reference/system/inc/espefuse_summary_ESP32-C6.rst index 5fdfe6c753..3728f02469 100644 --- a/docs/en/api-reference/system/inc/espefuse_summary_ESP32-C6.rst +++ b/docs/en/api-reference/system/inc/espefuse_summary_ESP32-C6.rst @@ -1,12 +1,10 @@ .. code-block:: none - espefuse.py -p PORT summary + idf.py efuse-summary - espefuse.py v4.6-dev - Connecting.... - Detecting chip type... ESP32-C6 + Executing action: efuse-summary + (...) - === Run "summary" command === EFUSE_NAME (Block) Description = [Meaningful Value] [Readable/Writeable] (Hex Value) ---------------------------------------------------------------------------------------- Config fuses: @@ -160,11 +158,13 @@ To get a dump for all eFuse registers. .. code-block:: none - espefuse.py -p PORT dump + idf.py efuse-dump + Executing action: efuse-dump + Running espefuse.py in directory + Executing "espefuse.py dump --chip esp32c6"... espefuse.py v4.6-dev Connecting.... - Detecting chip type... ESP32-C6 BLOCK0 ( ) [0 ] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000 MAC_SPI_8M_0 (BLOCK1 ) [1 ] read_regs: f9f7529c 00006055 00000000 01040000 00000000 00000000 BLOCK_SYS_DATA (BLOCK2 ) [2 ] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 diff --git a/docs/en/api-reference/system/inc/espefuse_summary_ESP32-H2.rst b/docs/en/api-reference/system/inc/espefuse_summary_ESP32-H2.rst index ecc333b412..d5a5d90a7a 100644 --- a/docs/en/api-reference/system/inc/espefuse_summary_ESP32-H2.rst +++ b/docs/en/api-reference/system/inc/espefuse_summary_ESP32-H2.rst @@ -1,12 +1,10 @@ .. code-block:: none - espefuse.py -p PORT summary + idf.py efuse-summary - espefuse.py v4.6-dev - Connecting.... - Detecting chip type... ESP32-H2 + Executing action: efuse-summary + (...) - === Run "summary" command === EFUSE_NAME (Block) Description = [Meaningful Value] [Readable/Writeable] (Hex Value) ---------------------------------------------------------------------------------------- Config fuses: @@ -160,12 +158,13 @@ To get a dump for all eFuse registers. .. code-block:: none - espefuse.py -p PORT dump + idf.py efuse-dump - espefuse.py dump + Executing action: efuse-dump + Running espefuse.py in directory + Executing "espefuse.py dump --chip esp32h2"... espefuse.py v4.6-dev Connecting.... - Detecting chip type... ESP32-H2 BLOCK0 ( ) [0 ] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000 MAC_SPI_8M_0 (BLOCK1 ) [1 ] read_regs: f9f72ca2 fffe6055 00000000 00000000 00000000 00000000 BLOCK_SYS_DATA (BLOCK2 ) [2 ] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 diff --git a/docs/en/api-reference/system/inc/espefuse_summary_ESP32-P4.rst b/docs/en/api-reference/system/inc/espefuse_summary_ESP32-P4.rst index a730ceb3ca..564809477b 100644 --- a/docs/en/api-reference/system/inc/espefuse_summary_ESP32-P4.rst +++ b/docs/en/api-reference/system/inc/espefuse_summary_ESP32-P4.rst @@ -1,12 +1,10 @@ .. code-block:: none - espefuse.py -p PORT summary + idf.py efuse-summary - espefuse.py v4.7.0 - Connecting.... - Detecting chip type... ESP32-P4 + Executing action: efuse-summary + (...) - === Run "summary" command === EFUSE_NAME (Block) Description = [Meaningful Value] [Readable/Writeable] (Hex Value) ---------------------------------------------------------------------------------------- Config fuses: @@ -191,9 +189,13 @@ To get a dump for all eFuse registers. .. code-block:: none + idf.py efuse-dump + + Executing action: efuse-dump + Running espefuse.py in directory + Executing "espefuse.py dump --chip esp32p4"... espefuse.py v4.7.dev1 Connecting.... - Detecting chip type... ESP32-P4 BLOCK0 ( ) [0 ] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000 MAC_SPI_8M_0 (BLOCK1 ) [1 ] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000 BLOCK_SYS_DATA (BLOCK2 ) [2 ] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 @@ -208,4 +210,5 @@ To get a dump for all eFuse registers. BLOCK0 ( ) [0 ] err__regs: 00000000 00000000 00000000 00000000 00000000 00000000 EFUSE_RD_RS_ERR0_REG 0x00000000 EFUSE_RD_RS_ERR1_REG 0x00000000 + === Run "dump" command === diff --git a/docs/en/api-reference/system/inc/espefuse_summary_ESP32-S2.rst b/docs/en/api-reference/system/inc/espefuse_summary_ESP32-S2.rst index b0160d2222..5515841005 100644 --- a/docs/en/api-reference/system/inc/espefuse_summary_ESP32-S2.rst +++ b/docs/en/api-reference/system/inc/espefuse_summary_ESP32-S2.rst @@ -1,13 +1,12 @@ .. code-block:: none - espefuse.py -p PORT summary + idf.py efuse-summary - espefuse.py v4.6-dev - Connecting.... - Detecting chip type... Unsupported detection protocol, switching and trying again... - Detecting chip type... ESP32-S2 + Executing action: efuse-summary + "ninja efuse-summary"... + + (...) - === Run "summary" command === EFUSE_NAME (Block) Description = [Meaningful Value] [Readable/Writeable] (Hex Value) ---------------------------------------------------------------------------------------- Config fuses: @@ -90,8 +89,8 @@ DIS_DOWNLOAD_MODE (BLOCK0) Set this bit to disable all download boot modes = False R/W (0b0) ENABLE_SECURITY_DOWNLOAD (BLOCK0) Set this bit to enable secure UART download mode ( = False R/W (0b0) read/write flash only) - SECURE_VERSION (BLOCK0) Secure version (used by ESP-IDF anti-rollback feat = 0 R/W (0x0000) - ure) + SECURE_VERSION (BLOCK0) Secure version (used by ESP-IDF anti-rollback = 0 R/W (0x0000) + feature) BLOCK_KEY0 (BLOCK4) Purpose: USER Key0 or user data @@ -158,12 +157,13 @@ To get a dump for all eFuse registers. .. code-block:: none - espefuse.py -p PORT dump + idf.py efuse-dump + Executing action: efuse-dump + Running espefuse.py in directory + Executing "espefuse.py dump --chip esp32s2"... espefuse.py v4.6-dev Connecting.... - Detecting chip type... Unsupported detection protocol, switching and trying again... - Detecting chip type... ESP32-S2 BLOCK0 ( ) [0 ] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000 MAC_SPI_8M_0 (BLOCK1 ) [1 ] read_regs: 79b3b954 000058cf 00000000 10440000 00000000 00000000 BLOCK_SYS_DATA (BLOCK2 ) [2 ] read_regs: f1c60eea 8238f201 595b98e9 0200fe81 1c549f24 88491102 06461421 070c2083 diff --git a/docs/en/api-reference/system/inc/espefuse_summary_ESP32-S3.rst b/docs/en/api-reference/system/inc/espefuse_summary_ESP32-S3.rst index 70e274cc08..7936b84afd 100644 --- a/docs/en/api-reference/system/inc/espefuse_summary_ESP32-S3.rst +++ b/docs/en/api-reference/system/inc/espefuse_summary_ESP32-S3.rst @@ -1,12 +1,10 @@ .. code-block:: none - espefuse.py -p PORT summary + idf.py efuse-summary - espefuse.py v4.6-dev - Connecting.... - Detecting chip type... ESP32-S3 + Executing action: efuse-summary + (...) - === Run "summary" command === EFUSE_NAME (Block) Description = [Meaningful Value] [Readable/Writeable] (Hex Value) ---------------------------------------------------------------------------------------- Calibration fuses: @@ -94,14 +92,14 @@ = 00:00:00:00:00:00 (OK) R/W Security fuses: - DIS_DOWNLOAD_ICACHE (BLOCK0) Set this bit to disable Icache in download mode (b = False R/W (0b0) - oot_mode[3:0] is 0; 1; 2; 3; 6; 7) + DIS_DOWNLOAD_ICACHE (BLOCK0) Set this bit to disable Icache in download mode ( = False R/W (0b0) + boot_mode[3:0] is 0; 1; 2; 3; 6; 7) DIS_DOWNLOAD_DCACHE (BLOCK0) Set this bit to disable Dcache in download mode ( = False R/W (0b0) boot_mode[3:0] is 0; 1; 2; 3; 6; 7) - DIS_FORCE_DOWNLOAD (BLOCK0) Set this bit to disable the function that forces c = False R/W (0b0) - hip into download mode - DIS_DOWNLOAD_MANUAL_ENCRYPT (BLOCK0) Set this bit to disable flash encryption when in d = False R/W (0b0) - ownload boot modes + DIS_FORCE_DOWNLOAD (BLOCK0) Set this bit to disable the function that forces = False R/W (0b0) + chip into download mode + DIS_DOWNLOAD_MANUAL_ENCRYPT (BLOCK0) Set this bit to disable flash encryption when in = False R/W (0b0) + download boot modes SPI_BOOT_CRYPT_CNT (BLOCK0) Enables flash encryption when 1 or 3 bits are set = Disable R/W (0b000) and disabled otherwise SECURE_BOOT_KEY_REVOKE0 (BLOCK0) Revoke 1st secure boot key = False R/W (0b0) @@ -119,8 +117,8 @@ DIS_DOWNLOAD_MODE (BLOCK0) Set this bit to disable download mode (boot_mode[3 = False R/W (0b0) :0] = 0; 1; 2; 3; 6; 7) ENABLE_SECURITY_DOWNLOAD (BLOCK0) Set this bit to enable secure UART download mode = False R/W (0b0) - SECURE_VERSION (BLOCK0) Secure version (used by ESP-IDF anti-rollback feat = 0 R/W (0x0000) - ure) + SECURE_VERSION (BLOCK0) Secure version (used by ESP-IDF anti-rollback = 0 R/W (0x0000) + feature) BLOCK_KEY0 (BLOCK4) Purpose: USER Key0 or user data @@ -193,11 +191,13 @@ To get a dump for all eFuse registers. .. code-block:: none - espefuse.py -p PORT dump + idf.py efuse-dump + Executing action: efuse-dump + Running espefuse.py in directory + Executing "espefuse.py dump --chip esp32s3"... espefuse.py v4.6-dev Connecting.... - Detecting chip type... ESP32-S3 BLOCK0 ( ) [0 ] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000 MAC_SPI_8M_0 (BLOCK1 ) [1 ] read_regs: 3b41f270 0000ecda 00000000 030c0000 2c707800 9800cc58 BLOCK_SYS_DATA (BLOCK2 ) [2 ] read_regs: b8c93acb bcc32b88 6000f45e 4bbe25ac 8d8b16d1 924940b4 b2c4cee1 50a53ace diff --git a/docs/en/api-reference/system/inc/espefuse_summary_ESP32.rst b/docs/en/api-reference/system/inc/espefuse_summary_ESP32.rst index b36daf6d7e..4c1bad6bb9 100644 --- a/docs/en/api-reference/system/inc/espefuse_summary_ESP32.rst +++ b/docs/en/api-reference/system/inc/espefuse_summary_ESP32.rst @@ -1,14 +1,10 @@ .. code-block:: none - espefuse.py -p PORT summary + idf.py efuse-summary - espefuse.py v4.6-dev - Connecting.... - Detecting chip type... Unsupported detection protocol, switching and trying again... - Connecting..... - Detecting chip type... ESP32 + Executing action: efuse-summary + (...) - === Run "summary" command === EFUSE_NAME (Block) Description = [Meaningful Value] [Readable/Writeable] (Hex Value) ---------------------------------------------------------------------------------------- Calibration fuses: @@ -29,8 +25,8 @@ CLK8M_FREQ (BLOCK0) 8MHz clock freq override = 51 R/W (0x33) VOL_LEVEL_HP_INV (BLOCK0) This field stores the voltage level for CPU to run = 0 R/W (0b00) at 240 MHz; or for flash/PSRAM to run at 80 MHz.0 - x0: level 7; 0x1: level 6; 0x2: level 5; 0x3: leve - l 4. (RO) + x0: level 7; 0x1: level 6; 0x2: level 5; 0x3:i + level 4. (RO) CODING_SCHEME (BLOCK0) Efuse variable block length scheme = NONE (BLK1-3 len=256 bits) R/W (0b00) CONSOLE_DEBUG_DISABLE (BLOCK0) Disable ROM BASIC interpreter fallback = True R/W (0b1) @@ -97,13 +93,13 @@ To get a dump for all eFuse registers. .. code-block:: none - espefuse.py -p PORT dump + idf.py efuse-dump + Executing action: efuse-dump + Running espefuse.py in directory + Executing "espefuse.py dump --chip esp32"... espefuse.py v4.6-dev Connecting.... - Detecting chip type... Unsupported detection protocol, switching and trying again... - Connecting....... - Detecting chip type... ESP32 BLOCK0 ( ) [0 ] read_regs: 00000000 7e5a6e58 00e294b9 0000a200 00000333 00100000 00000004 BLOCK1 (flash_encryption) [1 ] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 BLOCK2 (secure_boot_v1 s) [2 ] read_regs: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 diff --git a/docs/en/security/flash-encryption.rst b/docs/en/security/flash-encryption.rst index 1005dc8373..1b6d6a3c16 100644 --- a/docs/en/security/flash-encryption.rst +++ b/docs/en/security/flash-encryption.rst @@ -55,7 +55,7 @@ Other types of data can be encrypted conditionally: Relevant eFuses --------------- -The flash encryption operation is controlled by various eFuses available on {IDF_TARGET_NAME}. The list of eFuses and their descriptions is given in the table below. The names in eFuse column are also used by espefuse.py tool. For usage in the eFuse API, modify the name by adding ``ESP_EFUSE_``, for example: esp_efuse_read_field_bit(ESP_EFUSE_DISABLE_DL_ENCRYPT). +The flash encryption operation is controlled by various eFuses available on {IDF_TARGET_NAME}. The list of eFuses and their descriptions is given in the table below. The names in eFuse column are also used by espefuse.py tool and idf.py based eFuse commands. For usage in the eFuse API, modify the name by adding ``ESP_EFUSE_``, for example: esp_efuse_read_field_bit(ESP_EFUSE_DISABLE_DL_ENCRYPT). .. Comment: As text in cells of list-table header rows does not wrap, it is necessary to make 0 header rows and apply bold typeface to the first row. Otherwise, the table goes beyond the html page limits on the right. @@ -164,7 +164,7 @@ The flash encryption operation is controlled by various eFuses available on {IDF * R/W access control is available for all the eFuse bits listed in the table above. * The default value of these bits is 0 after manufacturing. -Read and write access to eFuse bits is controlled by appropriate fields in the registers ``WR_DIS`` and ``RD_DIS``. For more information on {IDF_TARGET_NAME} eFuses, see :doc:`eFuse manager <../api-reference/system/efuse>`. To change protection bits of eFuse field using espefuse.py, use these two commands: read_protect_efuse and write_protect_efuse. Example ``espefuse.py write_protect_efuse DISABLE_DL_ENCRYPT``. +Read and write access to eFuse bits is controlled by appropriate fields in the registers ``WR_DIS`` and ``RD_DIS``. For more information on {IDF_TARGET_NAME} eFuses, see :doc:`eFuse manager <../api-reference/system/efuse>`. To change protection bits of eFuse field using idf.py, use these two commands: efuse-read-protect and efuse-write-protect (idf.py based aliases of espefuse.py commands write_protect_efuse and read_protect_efuse). Example ``idf.py efuse-write-protect DISABLE_DL_ENCRYPT``. .. only:: esp32c2 @@ -405,13 +405,13 @@ To use a host generated key, take the following steps: .. code-block:: bash - espefuse.py --port PORT burn_key flash_encryption my_flash_encryption_key.bin + idf.py --port PORT efuse-burn-key flash_encryption my_flash_encryption_key.bin .. only:: SOC_FLASH_ENCRYPTION_XTS_AES_256 .. code-block:: bash - espefuse.py --port PORT burn_key BLOCK my_flash_encryption_key.bin KEYPURPOSE + idf.py --port PORT efuse-burn-key BLOCK my_flash_encryption_key.bin KEYPURPOSE where ``BLOCK`` is a free keyblock between ``BLOCK_KEY0`` and ``BLOCK_KEY5``. And ``KEYPURPOSE`` is either ``AES_256_KEY_1``, ``XTS_AES_256_KEY_2``, ``XTS_AES_128_KEY``. See `{IDF_TARGET_NAME} Technical Reference Manual <{IDF_TARGET_TRM_EN_URL}>`_ for a description of the key purposes. @@ -419,28 +419,28 @@ To use a host generated key, take the following steps: .. code-block:: bash - espefuse.py --port PORT burn_key BLOCK my_flash_encryption_key.bin XTS_AES_128_KEY + idf.py --port PORT efuse-burn-key BLOCK my_flash_encryption_key.bin XTS_AES_128_KEY - For AES-256 (512-bit key) - ``XTS_AES_256_KEY_1`` and ``XTS_AES_256_KEY_2``. ``espefuse.py`` supports burning both these two key purposes together with a 512 bit key to two separate key blocks via the virtual key purpose ``XTS_AES_256_KEY``. When this is used ``espefuse.py`` will burn the first 256 bit of the key to the specified ``BLOCK`` and burn the corresponding block key purpose to ``XTS_AES_256_KEY_1``. The last 256 bit of the key will be burned to the first free key block after ``BLOCK`` and the corresponding block key purpose to ``XTS_AES_256_KEY_2`` + For AES-256 (512-bit key) - ``XTS_AES_256_KEY_1`` and ``XTS_AES_256_KEY_2``. ``idf.py`` supports burning both these two key purposes together with a 512 bit key to two separate key blocks via the virtual key purpose ``XTS_AES_256_KEY``. When this is used ``idf.py`` will burn the first 256 bit of the key to the specified ``BLOCK`` and burn the corresponding block key purpose to ``XTS_AES_256_KEY_1``. The last 256 bit of the key will be burned to the first free key block after ``BLOCK`` and the corresponding block key purpose to ``XTS_AES_256_KEY_2`` .. code-block:: bash - espefuse.py --port PORT burn_key BLOCK my_flash_encryption_key.bin XTS_AES_256_KEY + idf.py --port PORT efuse-burn-key BLOCK my_flash_encryption_key.bin XTS_AES_256_KEY If you wish to specify exactly which two blocks are used then it is possible to divide key into two 256 bit keys, and manually burn each half with ``XTS_AES_256_KEY_1`` and ``XTS_AES_256_KEY_2`` as key purposes: .. code-block:: bash split -b 32 my_flash_encryption_key.bin my_flash_encryption_key.bin. - espefuse.py --port PORT burn_key BLOCK my_flash_encryption_key.bin.aa XTS_AES_256_KEY_1 - espefuse.py --port PORT burn_key BLOCK+1 my_flash_encryption_key.bin.ab XTS_AES_256_KEY_2 + idf.py --port PORT efuse-burn-key BLOCK my_flash_encryption_key.bin.aa XTS_AES_256_KEY_1 + idf.py --port PORT efuse-burn-key BLOCK+1 my_flash_encryption_key.bin.ab XTS_AES_256_KEY_2 .. only:: SOC_FLASH_ENCRYPTION_XTS_AES_128 and not SOC_FLASH_ENCRYPTION_XTS_AES_256 and not SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK .. code-block:: bash - espefuse.py --port PORT burn_key BLOCK my_flash_encryption_key.bin XTS_AES_128_KEY + idf.py --port PORT efuse-burn-key BLOCK my_flash_encryption_key.bin XTS_AES_128_KEY where ``BLOCK`` is a free keyblock between ``BLOCK_KEY0`` and ``BLOCK_KEY5``. @@ -450,19 +450,19 @@ To use a host generated key, take the following steps: .. code-block:: bash - espefuse.py --port PORT burn_key BLOCK_KEY0 flash_encryption_key256.bin XTS_AES_128_KEY + idf.py --port PORT efuse-burn-key BLOCK_KEY0 flash_encryption_key256.bin XTS_AES_128_KEY For AES-128 key derived from 128 bits (SHA256(128 bits)) - ``XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS``. The FE key will be written in the lower part of eFuse BLOCK_KEY0. The upper 128 bits are not used and will remain available for reading by software. Using the special mode of the espefuse tool, shown in the ``For burning both keys together`` section below, the user can write their data to it using any espefuse commands. .. code-block:: bash - espefuse.py --port PORT burn_key BLOCK_KEY0 flash_encryption_key128.bin XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS + idf.py --port PORT efuse-burn-key BLOCK_KEY0 flash_encryption_key128.bin XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS For burning both keys together (Secure Boot and Flash Encryption): .. code-block:: bash - espefuse.py --port PORT --chip esp32c2 burn_key_digest secure_boot_signing_key.pem \ + espefuse.py --port PORT --chip esp32c2 burn_key_digest secure_boot_signing_key.pem \ burn_key BLOCK_KEY0 flash_encryption_key128.bin XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS If the key is not burned and the device is started after enabling flash encryption, the {IDF_TARGET_NAME} will generate a random key that software cannot access or modify. @@ -706,7 +706,7 @@ To check if flash encryption on your {IDF_TARGET_NAME} device is enabled, do one .. code-block:: bash - espefuse.py -p PORT summary + idf.py efuse-summary .. _reading-writing-content: @@ -806,11 +806,11 @@ If flash encryption was enabled accidentally, flashing of plaintext data will so #. In :ref:`project-configuration-menu`, disable :ref:`Enable flash encryption on boot `, then save and exit. #. Open project configuration menu again and **double-check** that you have disabled this option! If this option is left enabled, the bootloader will immediately re-enable encryption when it boots. #. With flash encryption disabled, build and flash the new bootloader and application by running ``idf.py flash``. -#. Use ``espefuse.py`` (in ``components/esptool_py/esptool``) to disable the ``{IDF_TARGET_CRYPT_CNT}`` by running: +#. Use ``idf.py`` to disable the ``{IDF_TARGET_CRYPT_CNT}`` by running: .. code-block:: bash - espefuse.py burn_efuse {IDF_TARGET_CRYPT_CNT} + idf.py efuse-burn {IDF_TARGET_CRYPT_CNT} Reset the {IDF_TARGET_NAME}. Flash encryption will be disabled, and the bootloader will boot as usual. @@ -940,15 +940,15 @@ However, before the first boot you can choose to keep any of these features enab .. code-block:: bash - espefuse.py --port PORT burn_efuse DISABLE_DL_DECRYPT - espefuse.py --port PORT write_protect_efuse DISABLE_DL_ENCRYPT + idf.py --port PORT efuse-burn DISABLE_DL_DECRYPT + idf.py --port PORT efuse-write-protect DISABLE_DL_ENCRYPT .. only:: not esp32 .. code-block:: bash - espefuse.py --port PORT burn_efuse DIS_DOWNLOAD_MANUAL_ENCRYPT - espefuse.py --port PORT write_protect_efuse DIS_DOWNLOAD_MANUAL_ENCRYPT + idf.py --port PORT efuse-burn DIS_DOWNLOAD_MANUAL_ENCRYPT + idf.py --port PORT efuse-write-protect DIS_DOWNLOAD_MANUAL_ENCRYPT .. note:: diff --git a/docs/en/security/secure-boot-v1.rst b/docs/en/security/secure-boot-v1.rst index f9e9ffe9f8..3090a9ca11 100644 --- a/docs/en/security/secure-boot-v1.rst +++ b/docs/en/security/secure-boot-v1.rst @@ -149,11 +149,11 @@ To enable a reflashable bootloader: 1. In the :ref:`project-configuration-menu`, select ``Bootloader Config`` > :ref:`CONFIG_SECURE_BOOT` > ``CONFIG_SECURE_BOOT_V1_ENABLED`` > :ref:`CONFIG_SECURE_BOOTLOADER_MODE` > ``Reflashable``. -2. If necessary, set the :ref:`CONFIG_SECURE_BOOTLOADER_KEY_ENCODING` based on the coding scheme used by the device. The coding scheme is shown in the ``Features`` line when ``esptool.py`` connects to the chip, or in the ``espefuse.py summary`` output. +2. If necessary, set the :ref:`CONFIG_SECURE_BOOTLOADER_KEY_ENCODING` based on the coding scheme used by the device. The coding scheme is shown in the ``Features`` line when ``esptool.py`` connects to the chip, or in the ``idf.py efuse-summary`` output. 3. Please follow the steps shown in :ref:`secure-boot-generate-key` to generate the signing key. The path of the generated key file must be specified in the ``Secure Boot Configuration`` menu. -4. Run ``idf.py bootloader``. A binary key file will be created, derived from the private key that is used for signing. Two sets of flashing steps will be printed. The first set of steps includes an ``espefuse.py burn_key secure_boot_v1 path_to/secure-bootloader-key-xxx.bin`` command which is used to write the bootloader key to eFuse. Flashing this key is a one-time-only process. The second set of steps can be used to reflash the bootloader with a pre-calculated digest, which is generated during the build process. +4. Run ``idf.py bootloader``. A binary key file will be created, derived from the private key that is used for signing. Two sets of flashing steps will be printed. The first set of steps includes an ``idf.py efuse-burn-key secure_boot_v1 path_to/secure-bootloader-key-xxx.bin`` command which is used to write the bootloader key to eFuse. Flashing this key is a one-time-only process. The second set of steps can be used to reflash the bootloader with a pre-calculated digest, which is generated during the build process. 5. Resume from :ref:`Step 6 of the one-time flashing process `, to flash the bootloader and enable secure boot. Watch the console log output closely to ensure there were no errors in the secure boot configuration. diff --git a/examples/system/efuse/CMakeLists.txt b/examples/system/efuse/CMakeLists.txt index 56d50e5bdb..990d5fdd07 100644 --- a/examples/system/efuse/CMakeLists.txt +++ b/examples/system/efuse/CMakeLists.txt @@ -7,7 +7,7 @@ project(efuse) idf_component_get_property(esptool_py_dir esptool_py COMPONENT_DIR) set(efuse_names "MAC" "WR_DIS") -add_custom_target(efuse-summary +add_custom_target(efuse-filter COMMAND ${CMAKE_COMMAND} -D "IDF_PATH=${IDF_PATH}" -D "esptool_py_dir=${esptool_py_dir}" diff --git a/tools/idf_py_actions/serial_ext.py b/tools/idf_py_actions/serial_ext.py index 860cff737a..71b649b7c9 100644 --- a/tools/idf_py_actions/serial_ext.py +++ b/tools/idf_py_actions/serial_ext.py @@ -9,6 +9,7 @@ from typing import Any from typing import Dict from typing import List from typing import Optional +from typing import Tuple import click from idf_py_actions.global_options import global_options @@ -18,13 +19,13 @@ from idf_py_actions.tools import get_sdkconfig_value from idf_py_actions.tools import PropertyDict from idf_py_actions.tools import run_target from idf_py_actions.tools import RunTool - PYTHON = sys.executable BAUD_RATE = { 'names': ['-b', '--baud'], - 'help': 'Baud rate for flashing. It can imply monitor baud rate as well if it hasn\'t been defined locally.', + 'help': ("Global baud rate for all idf.py subcommands if they don't overwrite it locally." + "It can imply monitor baud rate as well if it hasn't been defined locally."), 'scope': 'global', 'envvar': 'ESPBAUD', 'default': 460800, @@ -41,7 +42,7 @@ PORT = { def yellow_print(message: str, newline: Optional[str]='\n') -> None: - """Print a message to stderr with yellow highlighting """ + """Print a message to stderr with yellow highlighting""" sys.stderr.write('%s%s%s%s' % ('\033[0;33m', message, '\033[0m', newline)) sys.stderr.flush() @@ -56,7 +57,9 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: return project_desc def _get_esptool_args(args: PropertyDict) -> List: - esptool_path = os.path.join(os.environ['IDF_PATH'], 'components/esptool_py/esptool/esptool.py') + esptool_path = os.path.join( + os.environ['IDF_PATH'], 'components/esptool_py/esptool/esptool.py' + ) esptool_wrapper_path = os.environ.get('ESPTOOL_WRAPPER', '') if args.port is None: args.port = get_default_serial_port() @@ -79,7 +82,7 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: return result def _get_commandline_options(ctx: click.core.Context) -> List: - """ Return all the command line options up to first action """ + """Return all the command line options up to first action""" # This approach ignores argument parsing done Click result = [] @@ -91,8 +94,18 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: return result - def monitor(action: str, ctx: click.core.Context, args: PropertyDict, print_filter: str, monitor_baud: str, encrypted: bool, - no_reset: bool, timestamps: bool, timestamp_format: str, force_color: bool) -> None: + def monitor( + action: str, + ctx: click.core.Context, + args: PropertyDict, + print_filter: str, + monitor_baud: str, + encrypted: bool, + no_reset: bool, + timestamps: bool, + timestamp_format: str, + force_color: bool, + ) -> None: """ Run esp_idf_monitor to watch build output """ @@ -104,15 +117,21 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: if project_desc['target'] != 'linux': if no_reset and args.port is None: - msg = ('WARNING: --no-reset is ignored. ' - 'Please specify the port with the --port argument in order to use this option.') + msg = ( + 'WARNING: --no-reset is ignored. ' + 'Please specify the port with the --port argument in order to use this option.' + ) yellow_print(msg) no_reset = False args.port = args.port or get_default_serial_port() monitor_args += ['-p', args.port] - baud = monitor_baud or os.getenv('IDF_MONITOR_BAUD') or os.getenv('MONITORBAUD') + baud = ( + monitor_baud + or os.getenv('IDF_MONITOR_BAUD') + or os.getenv('MONITORBAUD') + ) if baud is None: # Baud hasn't been changed locally (by local baud argument nor by environment variables) @@ -120,18 +139,27 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: # Use the global baud rate if it has been changed by the command line. # Use project_desc['monitor_baud'] as the last option. - global_baud_defined = ctx._parameter_source['baud'] == click.core.ParameterSource.COMMANDLINE - baud = args.baud if global_baud_defined else project_desc['monitor_baud'] + global_baud_defined = ( + ctx._parameter_source['baud'] + == click.core.ParameterSource.COMMANDLINE + ) + baud = ( + args.baud if global_baud_defined else project_desc['monitor_baud'] + ) monitor_args += ['-b', baud] monitor_args += ['--toolchain-prefix', project_desc['monitor_toolprefix']] - coredump_decode = get_sdkconfig_value(project_desc['config_file'], 'CONFIG_ESP_COREDUMP_DECODE') + coredump_decode = get_sdkconfig_value( + project_desc['config_file'], 'CONFIG_ESP_COREDUMP_DECODE' + ) if coredump_decode is not None: monitor_args += ['--decode-coredumps', coredump_decode] - target_arch_riscv = get_sdkconfig_value(project_desc['config_file'], 'CONFIG_IDF_TARGET_ARCH_RISCV') + target_arch_riscv = get_sdkconfig_value( + project_desc['config_file'], 'CONFIG_IDF_TARGET_ARCH_RISCV' + ) monitor_args += ['--target', project_desc['target']] revision = project_desc.get('min_rev') if revision: @@ -168,13 +196,26 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: # Temporally ignore SIGINT, which is used in idf_monitor to spawn gdb. old_handler = signal.getsignal(signal.SIGINT) signal.signal(signal.SIGINT, signal.SIG_IGN) - try: - RunTool('idf_monitor', monitor_args, args.project_dir, build_dir=args.build_dir, hints=hints, interactive=True, convert_output=True)() + RunTool( + 'idf_monitor', + monitor_args, + args.project_dir, + build_dir=args.build_dir, + hints=hints, + interactive=True, + convert_output=True, + )() finally: signal.signal(signal.SIGINT, old_handler) - def flash(action: str, ctx: click.core.Context, args: PropertyDict, force: bool, extra_args: str) -> None: + def flash( + action: str, + ctx: click.core.Context, + args: PropertyDict, + force: bool, + extra_args: str, + ) -> None: """ Run esptool to flash the entire project, from an argfile generated by the build system """ @@ -190,7 +231,11 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: extra.append('--force') if extra_args: extra += shlex.split(extra_args) - env = {'ESPBAUD': str(args.baud), 'ESPPORT': args.port, 'SERIAL_TOOL_EXTRA_ARGS': ';'.join(extra)} + env = { + 'ESPBAUD': str(args.baud), + 'ESPPORT': args.port, + 'SERIAL_TOOL_EXTRA_ARGS': ';'.join(extra), + } run_target(action, args, env, force_progression=True) def erase_flash(action: str, ctx: click.core.Context, args: PropertyDict) -> None: @@ -199,15 +244,21 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: esptool_args += ['erase_flash'] RunTool('esptool.py', esptool_args, args.build_dir, hints=not args.no_hints)() - def global_callback(ctx: click.core.Context, global_args: Dict, tasks: PropertyDict) -> None: - encryption = any([task.name in ('encrypted-flash', 'encrypted-app-flash') for task in tasks]) + def global_callback( + ctx: click.core.Context, global_args: Dict, tasks: PropertyDict + ) -> None: + encryption = any( + [task.name in ('encrypted-flash', 'encrypted-app-flash') for task in tasks] + ) if encryption: for task in tasks: if task.name == 'monitor': task.action_args['encrypted'] = True break - def ota_targets(target_name: str, ctx: click.core.Context, args: PropertyDict) -> None: + def ota_targets( + target_name: str, ctx: click.core.Context, args: PropertyDict + ) -> None: """ Execute the target build system to build target 'target_name'. Additionally set global variables for baud and port. @@ -387,6 +438,76 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: sign_data_args += [extra_args['datafile']] RunTool('espsecure', sign_data_args, args.build_dir)() + def _parse_efuse_args(ctx: click.core.Context, args: PropertyDict, extra_args: Dict) -> List: + efuse_args = [] + efuse_args += ['-p', args.port or get_default_serial_port()] + if args.baud: + efuse_args += ['-b', str(args.baud)] + efuse_args += ['--chip', _get_project_desc(ctx, args)['target']] + if extra_args['before']: + efuse_args += ['--before', extra_args['before'].replace('-', '_')] + if extra_args['debug']: + efuse_args += ['--debug'] + if extra_args['do_not_confirm']: + efuse_args += ['--do-not-confirm'] + return efuse_args + + def efuse_burn(action: str, ctx: click.core.Context, args: PropertyDict, **extra_args: Dict) -> None: + ensure_build_directory(args, ctx.info_name) + burn_efuse_args = [PYTHON, '-m' 'espefuse', 'burn_efuse'] + burn_efuse_args += _parse_efuse_args(ctx, args, extra_args) + if extra_args['efuse_positional_args']: + burn_efuse_args += list(extra_args['efuse_positional_args']) + RunTool('espefuse', burn_efuse_args, args.build_dir)() + + def efuse_burn_key(action: str, ctx: click.core.Context, args: PropertyDict, **extra_args: str) -> None: + ensure_build_directory(args, ctx.info_name) + burn_key_args = [PYTHON, '-m' 'espefuse', 'burn_key'] + burn_key_args += _parse_efuse_args(ctx, args, extra_args) + if extra_args['no_protect_key']: + burn_key_args += ['--no-protect-key'] + if extra_args['force_write_always']: + burn_key_args += ['--force-write-always'] + if extra_args['show_sensitive_info']: + burn_key_args += ['--show-sensitive-info'] + if extra_args['image']: + burn_key_args.append(extra_args['image']) + RunTool('espefuse.py', burn_key_args, args.project_dir, build_dir=args.build_dir)() + + def efuse_dump(action: str, ctx: click.core.Context, args: PropertyDict, file_name: str, **extra_args: Dict) -> None: + ensure_build_directory(args, ctx.info_name) + dump_args = [PYTHON, '-m' 'espefuse', 'dump'] + dump_args += _parse_efuse_args(ctx, args, extra_args) + if file_name: + dump_args += ['--file_name', file_name] + RunTool('espefuse', dump_args, args.build_dir)() + + def efuse_read_protect(action: str, ctx: click.core.Context, args: PropertyDict, **extra_args: Dict) -> None: + ensure_build_directory(args, ctx.info_name) + read_protect_args = [PYTHON, '-m' 'espefuse', 'read_protect_efuse'] + read_protect_args += _parse_efuse_args(ctx, args, extra_args) + if extra_args['efuse_positional_args']: + read_protect_args += list(extra_args['efuse_positional_args']) + RunTool('espefuse', read_protect_args, args.build_dir)() + + def efuse_summary(action: str, ctx: click.core.Context, args: PropertyDict, format: str, **extra_args: Tuple) -> None: + ensure_build_directory(args, ctx.info_name) + summary_args = [PYTHON, '-m' 'espefuse', 'summary'] + summary_args += _parse_efuse_args(ctx, args, extra_args) + if format: + summary_args += ['--format', format.replace('-', '_')] + if extra_args['efuses']: + summary_args += extra_args['efuse_name'] + RunTool('espefuse', summary_args, args.build_dir)() + + def efuse_write_protect(action: str, ctx: click.core.Context, args: PropertyDict, **extra_args: Dict) -> None: + ensure_build_directory(args, ctx.info_name) + write_protect_args = [PYTHON, '-m' 'espefuse', 'write_protect_efuse'] + write_protect_args += _parse_efuse_args(ctx, args, extra_args) + if extra_args['efuse_positional_args']: + write_protect_args += list(extra_args['efuse_positional_args']) + RunTool('espefuse', write_protect_args, args.build_dir)() + BAUD_AND_PORT = [BAUD_RATE, PORT] flash_options = BAUD_AND_PORT + [ { @@ -402,6 +523,25 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: ) } ] + + EFUSE_OPTS = BAUD_AND_PORT + [ + { + 'names': ['--before'], + 'help': 'What to do before connecting to the chip.', + 'type': click.Choice(['default-reset', 'usb-reset', 'no-reset', 'no-reset-no-sync']), + }, + { + 'names': ['--debug', '-d'], + 'is_flag': True, + 'help': 'Print debug information (loglevel=DEBUG).', + }, + { + 'names': ['--do-not-confirm'], + 'is_flag': True, + 'help': 'Do not pause for confirmation before permanently writing eFuses. Use with caution!', + }, + ] + serial_actions = { 'global_action_callbacks': [global_callback], 'actions': { @@ -516,6 +656,7 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: 'nargs': 1, }, ], + }, 'secure-encrypt-flash-data': { 'callback': secure_encrypt_flash_data, @@ -644,63 +785,169 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: }, ], }, + 'efuse-burn': { + 'callback': efuse_burn, + 'help': 'Burn the eFuse with the specified name.', + 'options': EFUSE_OPTS, + 'arguments': [ + { + 'names': ['efuse-positional-args'], + 'nargs': -1, + }, + ], + }, + 'efuse-burn-key': { + 'callback': efuse_burn_key, + 'help': 'Burn a 256-bit key to EFUSE: BLOCK1, flash_encryption, BLOCK2, secure_boot_v1, secure_boot_v2, BLOCK3.', + 'options': EFUSE_OPTS + [ + { + 'names': ['--no-protect-key'], + 'help': ( + 'Disable default read- and write-protecting of the key.' + 'If this option is not set, once the key is flashed it cannot be read back or changed.' + ), + }, + { + 'names': ['--force-write-always'], + 'help': ( + "Write the eFuse even if it looks like it's already been written, or is write protected." + "Note that this option can't disable write protection, or clear any bit which has already been set." + ), + }, + { + 'names': ['--show-sensitive-info'], + 'help': ( + 'Show data to be burned (may expose sensitive data). Enabled if --debug is used.' + ), + }, + ], + 'arguments': [ + { + 'names': ['image'], + 'nargs': 1, + }, + ], + }, + 'efuse-dump': { + 'callback': efuse_dump, + 'help': 'Dump raw hex values of all eFuses.', + 'options': EFUSE_OPTS + [ + { + 'names': ['--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.' + ), + }, + ], + }, + 'efuse-read-protect': { + 'callback': efuse_read_protect, + 'help': 'Disable writing to the eFuse with the specified name.', + 'options': EFUSE_OPTS, + 'arguments': [ + { + 'names': ['efuse-positional-args'], + 'nargs': -1, + }, + ], + }, + 'efuse-summary': { + 'callback': efuse_summary, + 'help': 'Get the summary of the eFuses.', + 'options': EFUSE_OPTS + [ + { + 'names': ['--format'], + 'help': ('Summary format.'), + 'type': click.Choice(['json', 'summary', 'value-only']), + }, + ], + 'arguments': [ + { + 'names': ['efuse-name'], + 'nargs': 1, + }, + ], + }, + 'efuse-write-protect': { + 'callback': efuse_write_protect, + 'help': 'Disable writing to the eFuse with the specified name.', + 'options': EFUSE_OPTS, + 'arguments': [ + { + 'names': ['efuse-positional-args'], + 'nargs': -1, + }, + ], + }, 'monitor': { - 'callback': - monitor, - 'help': - 'Display serial output.', + 'callback': monitor, + 'help': 'Display serial output.', 'options': [ - PORT, { + PORT, + { 'names': ['--print-filter', '--print_filter'], - 'help': - ('Filter monitor output. ' - 'Restrictions on what to print can be specified as a series of : items ' - 'where is the tag string and is a character from the set ' - '{N, E, W, I, D, V, *} referring to a level. ' - 'For example, "tag1:W" matches and prints only the outputs written with ' - 'ESP_LOGW("tag1", ...) or at lower verbosity level, i.e. ESP_LOGE("tag1", ...). ' - 'Not specifying a or using "*" defaults to Verbose level. ' - 'Please see the IDF Monitor section of the ESP-IDF documentation ' - 'for a more detailed description and further examples.'), - 'default': - None, - }, { + 'help': ( + 'Filter monitor output. ' + 'Restrictions on what to print can be specified as a series of : items ' + 'where is the tag string and is a character from the set ' + '{N, E, W, I, D, V, *} referring to a level. ' + 'For example, "tag1:W" matches and prints only the outputs written with ' + 'ESP_LOGW("tag1", ...) or at lower verbosity level, i.e. ESP_LOGE("tag1", ...). ' + 'Not specifying a or using "*" defaults to Verbose level. ' + 'Please see the IDF Monitor section of the ESP-IDF documentation ' + 'for a more detailed description and further examples.' + ), + 'default': None, + }, + { 'names': ['--monitor-baud', '-b'], - 'type': - click.INT, - 'help': ('Baud rate for monitor. ' - 'If this option is not provided IDF_MONITOR_BAUD and MONITORBAUD ' - 'environment variables, global baud rate and project_description.json in build directory ' - "(generated by CMake from project's sdkconfig) " - 'will be checked for default value.'), - }, { + 'type': click.INT, + 'help': ( + 'Baud rate for monitor. ' + 'If this option is not provided IDF_MONITOR_BAUD and MONITORBAUD ' + 'environment variables, global baud rate and project_description.json in build directory ' + "(generated by CMake from project's sdkconfig) " + 'will be checked for default value.' + ), + }, + { 'names': ['--encrypted', '-E'], 'is_flag': True, - 'help': ('Enable encrypted flash targets. ' - 'IDF Monitor will invoke encrypted-flash and encrypted-app-flash targets ' - 'if this option is set. This option is set by default if IDF Monitor was invoked ' - 'together with encrypted-flash or encrypted-app-flash target.'), - }, { + 'help': ( + 'Enable encrypted flash targets. ' + 'IDF Monitor will invoke encrypted-flash and encrypted-app-flash targets ' + 'if this option is set. This option is set by default if IDF Monitor was invoked ' + 'together with encrypted-flash or encrypted-app-flash target.' + ), + }, + { 'names': ['--no-reset'], 'is_flag': True, - 'help': ('Disable reset on monitor startup. ' - 'IDF Monitor will not reset the MCU target by toggling DTR/RTS lines on startup ' - 'if this option is set.'), - }, { + 'help': ( + 'Disable reset on monitor startup. ' + 'IDF Monitor will not reset the MCU target by toggling DTR/RTS lines on startup ' + 'if this option is set.' + ), + }, + { 'names': ['--timestamps'], 'is_flag': True, 'help': 'Print a time stamp in the beginning of each line.', - }, { + }, + { 'names': ['--timestamp-format'], - 'help': ('Set the formatting of timestamps compatible with strftime(). ' - 'For example, "%Y-%m-%d %H:%M:%S".'), - 'default': None - }, { + 'help': ( + 'Set the formatting of timestamps compatible with strftime(). ' + 'For example, "%Y-%m-%d %H:%M:%S".' + ), + 'default': None, + }, + { 'names': ['--force-color'], 'is_flag': True, 'help': 'Always print ANSI for colors', - } - + }, ], 'order_dependencies': [ 'flash', @@ -741,6 +988,7 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: 'options': flash_options, 'order_dependencies': ['all', 'erase-flash'], }, + 'erase-otadata': { 'callback': ota_targets, 'help': 'Erase otadata partition.', diff --git a/tools/test_build_system/test_common.py b/tools/test_build_system/test_common.py index 1f742984fe..9da88ea787 100644 --- a/tools/test_build_system/test_common.py +++ b/tools/test_build_system/test_common.py @@ -90,7 +90,7 @@ def test_efuse_summary_cmake_functions( default_idf_env: EnvDict ) -> None: default_idf_env['IDF_CI_BUILD'] = '1' - output = run_idf_py('efuse-summary', env=default_idf_env) + output = run_idf_py('efuse-filter', env=default_idf_env) assert 'FROM_CMAKE: MAC: 00:00:00:00:00:00' in output.stdout assert 'FROM_CMAKE: WR_DIS: 0' in output.stdout