forked from espressif/esp-idf
docs: Sync CN and EN files
This commit is contained in:
@@ -13,17 +13,17 @@ In certain situations, the execution of the program can not be continued in a we
|
||||
- CPU Exceptions: |CPU_EXCEPTIONS_LIST|
|
||||
- System level checks and safeguards:
|
||||
|
||||
.. list::
|
||||
.. list::
|
||||
|
||||
- :doc:`Interrupt watchdog <../api-reference/system/wdts>` timeout
|
||||
- :doc:`Task watchdog <../api-reference/system/wdts>` timeout (only fatal if :ref:`CONFIG_ESP_TASK_WDT_PANIC` is set)
|
||||
- Cache access error
|
||||
:SOC_MEMPROT_SUPPORTED: - Memory protection fault
|
||||
- Brownout detection event
|
||||
- Stack overflow
|
||||
- Stack smashing protection check
|
||||
- Heap integrity check
|
||||
- Undefined behavior sanitizer (UBSAN) checks
|
||||
- :doc:`Interrupt watchdog <../api-reference/system/wdts>` timeout
|
||||
- :doc:`Task watchdog <../api-reference/system/wdts>` timeout (only fatal if :ref:`CONFIG_ESP_TASK_WDT_PANIC` is set)
|
||||
- Cache access error
|
||||
:SOC_MEMPROT_SUPPORTED: - Memory protection fault
|
||||
- Brownout detection event
|
||||
- Stack overflow
|
||||
- Stack smashing protection check
|
||||
- Heap integrity check
|
||||
- Undefined behavior sanitizer (UBSAN) checks
|
||||
|
||||
- Failed assertions, via ``assert``, ``configASSERT`` and similar macros.
|
||||
|
||||
@@ -32,7 +32,7 @@ This guide explains the procedure used in ESP-IDF for handling these errors, and
|
||||
Panic Handler
|
||||
-------------
|
||||
|
||||
Every error cause listed in the `Overview`_ will be handled by the *panic handler*.
|
||||
Every error cause listed in the :ref:`Overview` will be handled by the *panic handler*.
|
||||
|
||||
The panic handler will start by printing the cause of the error to the console. For CPU exceptions, the message will be similar to
|
||||
|
||||
@@ -46,29 +46,29 @@ For some of the system level checks (interrupt watchdog, cache access error), th
|
||||
|
||||
Guru Meditation Error: Core 0 panic'ed (|CACHE_ERR_MSG|). Exception was unhandled.
|
||||
|
||||
In all cases, the error cause will be printed in parentheses. See `Guru Meditation Errors`_ for a list of possible error causes.
|
||||
In all cases, the error cause will be printed in parentheses. See :ref:`Guru-Meditation-Errors` for a list of possible error causes.
|
||||
|
||||
Subsequent behavior of the panic handler can be set using :ref:`CONFIG_ESP_SYSTEM_PANIC` configuration choice. The available options are:
|
||||
|
||||
- Print registers and reboot (``CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT``) — default option.
|
||||
|
||||
This will print register values at the point of the exception, print the backtrace, and restart the chip.
|
||||
This will print register values at the point of the exception, print the backtrace, and restart the chip.
|
||||
|
||||
- Print registers and halt (``CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT``)
|
||||
|
||||
Similar to the above option, but halt instead of rebooting. External reset is required to restart the program.
|
||||
Similar to the above option, but halt instead of rebooting. External reset is required to restart the program.
|
||||
|
||||
- Silent reboot (``CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT``)
|
||||
|
||||
Do not print registers or backtrace, restart the chip immediately.
|
||||
Do not print registers or backtrace, restart the chip immediately.
|
||||
|
||||
- Invoke GDB Stub (``CONFIG_ESP_SYSTEM_PANIC_GDBSTUB``)
|
||||
|
||||
Start GDB server which can communicate with GDB over console UART port. This option will only provide read-only debugging or post-mortem debugging. See `GDB Stub`_ for more details.
|
||||
Start GDB server which can communicate with GDB over console UART port. This option will only provide read-only debugging or post-mortem debugging. See `GDB Stub`_ for more details.
|
||||
|
||||
.. note::
|
||||
|
||||
The ``CONFIG_ESP_SYSTEM_PANIC_GDBSTUB`` choice in the configuration option :ref:`CONFIG_ESP_SYSTEM_PANIC` is only available when the component ``esp_gdbstub`` is included in the build.
|
||||
The ``CONFIG_ESP_SYSTEM_PANIC_GDBSTUB`` choice in the configuration option :ref:`CONFIG_ESP_SYSTEM_PANIC` is only available when the component ``esp_gdbstub`` is included in the build.
|
||||
|
||||
The behavior of the panic handler is affected by three other configuration options.
|
||||
|
||||
@@ -78,7 +78,7 @@ The behavior of the panic handler is affected by three other configuration optio
|
||||
|
||||
- If :ref:`CONFIG_ESP_PANIC_HANDLER_IRAM` is disabled (disabled by default), the panic handler code is placed in flash memory, not IRAM. This means that if ESP-IDF crashes while flash cache is disabled, the panic handler will automatically re-enable flash cache before running GDB Stub or Core Dump. This adds some minor risk, if the flash cache status is also corrupted during the crash.
|
||||
|
||||
If this option is enabled, the panic handler code (including required UART functions) is placed in IRAM, and hence will decrease the usable memory space in SRAM. But this may be necessary to debug some complex issues with crashes while flash cache is disabled (for example, when writing to SPI flash) or when flash cache is corrupted when an exception is triggered.
|
||||
If this option is enabled, the panic handler code (including required UART functions) is placed in IRAM, and hence will decrease the usable memory space in SRAM. But this may be necessary to debug some complex issues with crashes while flash cache is disabled (for example, when writing to SPI flash) or when flash cache is corrupted when an exception is triggered.
|
||||
|
||||
- If :ref:`CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS` is enabled (disabled by default) and set to a number higher than 0, the panic handler will delay the reboot for that amount of time in seconds. This can help if the tool used to monitor serial output does not provide a possibility to stop and examine the serial output. In that case, delaying the reboot will allow users to examine and debug the panic handler output (backtrace, etc.) for the duration of the delay. After the delay, the device will reboot. The reset reason is preserved.
|
||||
|
||||
@@ -134,7 +134,7 @@ Unless the ``CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT`` option is enabled, the pani
|
||||
|
||||
.. only:: CONFIG_IDF_TARGET_ARCH_XTENSA
|
||||
|
||||
::
|
||||
.. code-block:: none
|
||||
|
||||
Core 0 register dump:
|
||||
PC : 0x400e14ed PS : 0x00060030 A0 : 0x800d0805 A1 : 0x3ffb5030
|
||||
@@ -148,7 +148,7 @@ Unless the ``CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT`` option is enabled, the pani
|
||||
|
||||
.. only:: CONFIG_IDF_TARGET_ARCH_RISCV
|
||||
|
||||
::
|
||||
.. code-block:: none
|
||||
|
||||
Core 0 register dump:
|
||||
MEPC : 0x420048b4 RA : 0x420048b4 SP : 0x3fc8f2f0 GP : 0x3fc8a600
|
||||
@@ -176,7 +176,7 @@ If :doc:`IDF Monitor <tools/idf-monitor>` is used, Program Counter values will b
|
||||
|
||||
.. only:: CONFIG_IDF_TARGET_ARCH_XTENSA
|
||||
|
||||
::
|
||||
.. code-block:: none
|
||||
|
||||
Core 0 register dump:
|
||||
PC : 0x400e14ed PS : 0x00060030 A0 : 0x800d0805 A1 : 0x3ffb5030
|
||||
@@ -197,7 +197,7 @@ If :doc:`IDF Monitor <tools/idf-monitor>` is used, Program Counter values will b
|
||||
|
||||
.. only:: CONFIG_IDF_TARGET_ARCH_RISCV
|
||||
|
||||
::
|
||||
.. code-block:: none
|
||||
|
||||
Core 0 register dump:
|
||||
MEPC : 0x420048b4 RA : 0x420048b4 SP : 0x3fc8f2f0 GP : 0x3fc8a600
|
||||
@@ -220,7 +220,7 @@ If :doc:`IDF Monitor <tools/idf-monitor>` is used, Program Counter values will b
|
||||
Moreover, :doc:`IDF Monitor <tools/idf-monitor>` is also capable of generating and printing a backtrace thanks to the stack dump provided by the board in the panic handler.
|
||||
The output looks like this:
|
||||
|
||||
::
|
||||
.. code-block:: none
|
||||
|
||||
Backtrace:
|
||||
|
||||
@@ -238,7 +238,7 @@ If :doc:`IDF Monitor <tools/idf-monitor>` is used, Program Counter values will b
|
||||
|
||||
This option will let the compiler generate DWARF information for each function of the project. Then, when a CPU exception occurs, the panic handler will parse these data and determine the backtrace of the task that failed. The output looks like this:
|
||||
|
||||
::
|
||||
.. code-block:: none
|
||||
|
||||
Backtrace: 0x42009e9a:0x3fc92120 0x42009ea6:0x3fc92120 0x42009ec2:0x3fc92130 0x42024620:0x3fc92150 0x40387d7c:0x3fc92160 0xfffffffe:0x3fc92170
|
||||
|
||||
@@ -256,7 +256,9 @@ GDB Stub
|
||||
|
||||
If the ``CONFIG_ESP_SYSTEM_PANIC_GDBSTUB`` option is enabled, the panic handler will not reset the chip when a fatal error happens. Instead, it will start a GDB remote protocol server, commonly referred to as GDB Stub. When this happens, a GDB instance running on the host computer can be instructed to connect to the {IDF_TARGET_NAME} UART port.
|
||||
|
||||
If :doc:`IDF Monitor <tools/idf-monitor>` is used, GDB is started automatically when a GDB Stub prompt is detected on the UART. The output looks like this::
|
||||
If :doc:`IDF Monitor <tools/idf-monitor>` is used, GDB is started automatically when a GDB Stub prompt is detected on the UART. The output looks like this:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
Entering gdb stub now.
|
||||
$T0b#e6GNU gdb (crosstool-NG crosstool-ng-1.22.0-80-gff1f415) 7.10
|
||||
@@ -286,11 +288,12 @@ The GDB prompt can be used to inspect CPU registers, local and static variables,
|
||||
|
||||
RTC Watchdog Timeout
|
||||
--------------------
|
||||
|
||||
{IDF_TARGET_RTCWDT_RTC_RESET:default="Not updated", esp32="RTCWDT_RTC_RESET", esp32s2="RTCWDT_RTC_RST", esp32s3="RTCWDT_RTC_RST", esp32c3="RTCWDT_RTC_RST", esp32c2="RTCWDT_RTC_RST", esp32c6="LP_WDT_SYS", esp32h2="LP_WDT_SYS", esp32p4="LP_WDT_SYS"}
|
||||
|
||||
The RTC watchdog is used in the startup code to keep track of execution time and it also helps to prevent a lock-up caused by an unstable power source. It is enabled by default (see :ref:`CONFIG_BOOTLOADER_WDT_ENABLE`). If the execution time is exceeded, the RTC watchdog will restart the system. In this case, the first stage (ROM) bootloader will print a message with the ``RTC Watchdog Timeout`` reason for the reboot.
|
||||
|
||||
::
|
||||
.. code-block:: none
|
||||
|
||||
rst:0x10 ({IDF_TARGET_RTCWDT_RTC_RESET})
|
||||
|
||||
@@ -310,7 +313,7 @@ This section explains the meaning of different error causes, printed in parens a
|
||||
|
||||
.. note::
|
||||
|
||||
See the `Guru Meditation Wikipedia article <https://en.wikipedia.org/wiki/Guru_Meditation>`_ for historical origins of "Guru Meditation".
|
||||
See the `Guru Meditation Wikipedia article <https://en.wikipedia.org/wiki/Guru_Meditation>`_ for historical origins of "Guru Meditation".
|
||||
|
||||
|
||||
|ILLEGAL_INSTR_MSG|
|
||||
@@ -322,9 +325,9 @@ This CPU exception indicates that the instruction which was executed was not a v
|
||||
|
||||
- Failure to read next instruction from SPI flash. This usually happens if:
|
||||
|
||||
- Application has reconfigured the SPI flash pins as some other function (GPIO, UART, etc.). Consult the Hardware Design Guidelines and the datasheet for the chip or module for details about the SPI flash pins.
|
||||
- Application has reconfigured the SPI flash pins as some other function (GPIO, UART, etc.). Consult the Hardware Design Guidelines and the datasheet for the chip or module for details about the SPI flash pins.
|
||||
|
||||
- Some external device has accidentally been connected to the SPI flash pins, and has interfered with communication between {IDF_TARGET_NAME} and SPI flash.
|
||||
- Some external device has accidentally been connected to the SPI flash pins, and has interfered with communication between {IDF_TARGET_NAME} and SPI flash.
|
||||
|
||||
- In C++ code, exiting from a non-void function without returning a value is considered to be an undefined behavior. When optimizations are enabled, the compiler will often omit the epilogue in such functions. This most often results in an |ILLEGAL_INSTR_MSG| exception. By default, ESP-IDF build system enables ``-Werror=return-type`` which means that missing return statements are treated as compile time errors. However if the application project disables compiler warnings, this issue might go undetected and the |ILLEGAL_INSTR_MSG| exception will occur at run time.
|
||||
|
||||
@@ -424,7 +427,9 @@ Other Fatal Errors
|
||||
|
||||
{IDF_TARGET_NAME} has a built-in brownout detector, which is enabled by default. The brownout detector can trigger a system reset if the supply voltage goes below a safe level. The brownout detector can be configured using :ref:`CONFIG_ESP_BROWNOUT_DET` and :ref:`CONFIG_ESP_BROWNOUT_DET_LVL_SEL` options.
|
||||
|
||||
When the brownout detector triggers, the following message is printed::
|
||||
When the brownout detector triggers, the following message is printed:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
Brownout detector was triggered
|
||||
|
||||
@@ -436,7 +441,9 @@ Other Fatal Errors
|
||||
Corrupt Heap
|
||||
^^^^^^^^^^^^
|
||||
|
||||
ESP-IDF's heap implementation contains a number of run-time checks of the heap structure. Additional checks ("Heap Poisoning") can be enabled in menuconfig. If one of the checks fails, a message similar to the following will be printed::
|
||||
ESP-IDF's heap implementation contains a number of run-time checks of the heap structure. Additional checks ("Heap Poisoning") can be enabled in menuconfig. If one of the checks fails, a message similar to the following will be printed:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
CORRUPT HEAP: Bad tail at 0x3ffe270a. Expected 0xbaad5678 got 0xbaac5678
|
||||
assertion "head != NULL" failed: file "/Users/user/esp/esp-idf/components/heap/multi_heap_poisoning.c", line 201, function: multi_heap_free
|
||||
@@ -480,19 +487,20 @@ ESP-IDF provides a custom FreeRTOS stack overflow detecting mechanism based on w
|
||||
Generally, this may cause the watchpoint to be triggered up to 28 bytes earlier than expected. The value 32 is chosen because it is larger than the stack canary size in FreeRTOS (20 bytes). Adopting this approach ensures that the watchpoint triggers before the stack canary is corrupted, not after.
|
||||
|
||||
.. note::
|
||||
|
||||
Not every stack overflow is guaranteed to trigger the watchpoint. It is possible that the task writes to memory beyond the stack canary location, in which case the watchpoint will not be triggered.
|
||||
|
||||
If watchpoint triggers, the message will be similar to:
|
||||
|
||||
.. only:: CONFIG_IDF_TARGET_ARCH_XTENSA
|
||||
|
||||
::
|
||||
.. code-block:: none
|
||||
|
||||
Debug exception reason: Stack canary watchpoint triggered (task_name)
|
||||
|
||||
.. only:: CONFIG_IDF_TARGET_ARCH_RISCV
|
||||
|
||||
::
|
||||
.. code-block:: none
|
||||
|
||||
Guru Meditation Error: Core 0 panic'ed (Breakpoint). Exception was unhandled.
|
||||
|
||||
@@ -507,7 +515,9 @@ See :ref:`CONFIG_FREERTOS_CHECK_STACKOVERFLOW`
|
||||
Stack Smashing
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
Stack smashing protection (based on GCC ``-fstack-protector*`` flags) can be enabled in ESP-IDF using :ref:`CONFIG_COMPILER_STACK_CHECK_MODE` option. If stack smashing is detected, message similar to the following will be printed::
|
||||
Stack smashing protection (based on GCC ``-fstack-protector*`` flags) can be enabled in ESP-IDF using :ref:`CONFIG_COMPILER_STACK_CHECK_MODE` option. If stack smashing is detected, message similar to the following will be printed:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
Stack smashing protect failure!
|
||||
|
||||
@@ -537,9 +547,10 @@ The backtrace should point to the function where stack smashing has occurred. Ch
|
||||
|
||||
CPU Lockup
|
||||
^^^^^^^^^^
|
||||
A CPU lockup reset happens when there is a double exception, i.e. when an exception occurs while the CPU is already in an exception handler. The most common cause for this is when the cache is in such a state that accessing external memory not possible. If this is the case then the panic handler will crash as well due to being unable to fetch instructions or read data.
|
||||
|
||||
If this is the case you can try placing the panic handler code in IRAM, which can be accessed when cache is disabled, to get more information about the cause of the lockup. This can be done with :ref:`CONFIG_ESP_PANIC_HANDLER_IRAM`.
|
||||
A CPU lockup reset happens when there is a double exception, i.e. when an exception occurs while the CPU is already in an exception handler. The most common cause for this is when the cache is in a state where accessing external memory becomes impossible. In such cases, the panic handler will crash as well due to being unable to fetch instructions or read data.
|
||||
|
||||
To gather more information about the cause of the lockup, you can try placing the panic handler code in IRAM, which remains accessible even when the cache is disabled. This can be done with :ref:`CONFIG_ESP_PANIC_HANDLER_IRAM`.
|
||||
|
||||
|
||||
Undefined Behavior Sanitizer (UBSAN) Checks
|
||||
@@ -560,7 +571,9 @@ UBSAN is disabled by default. It can be enabled at file, component, or project l
|
||||
|
||||
When enabling UBSAN for code which uses the SOC hardware register header files (``soc/xxx_reg.h``), it is recommended to disable shift-base sanitizer using ``-fno-sanitize=shift-base`` option. This is due to the fact that ESP-IDF register header files currently contain patterns which cause false positives for this specific sanitizer option.
|
||||
|
||||
To enable UBSAN at project level, add the following code at the end of the project's ``CMakeLists.txt`` file::
|
||||
To enable UBSAN at project level, add the following code at the end of the project's ``CMakeLists.txt`` file:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
idf_build_set_property(COMPILE_OPTIONS "-fsanitize=undefined" "-fno-sanitize=shift-base" APPEND)
|
||||
|
||||
@@ -568,29 +581,37 @@ Alternatively, pass these options through the ``EXTRA_CFLAGS`` and ``EXTRA_CXXFL
|
||||
|
||||
Enabling UBSAN results in significant increase of code and data size. Most applications, except for the trivial ones, will not fit into the available RAM of the microcontroller when UBSAN is enabled for the whole application. Therefore it is recommended that UBSAN is instead enabled for specific components under test.
|
||||
|
||||
To enable UBSAN for a specific component (``component_name``) from the project's ``CMakeLists.txt`` file, add the following code at the end of the file::
|
||||
To enable UBSAN for a specific component (``component_name``) from the project's ``CMakeLists.txt`` file, add the following code at the end of the file:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
idf_component_get_property(lib component_name COMPONENT_LIB)
|
||||
target_compile_options(${lib} PRIVATE "-fsanitize=undefined" "-fno-sanitize=shift-base")
|
||||
|
||||
.. note::
|
||||
|
||||
See the build system documentation for more information about :ref:`build properties <cmake-build-properties>` and :ref:`component properties <cmake-component-properties>`.
|
||||
See the build system documentation for more information about :ref:`build properties <cmake-build-properties>` and :ref:`component properties <cmake-component-properties>`.
|
||||
|
||||
To enable UBSAN for a specific component (``component_name``) from ``CMakeLists.txt`` of the same component, add the following at the end of the file::
|
||||
To enable UBSAN for a specific component (``component_name``) from ``CMakeLists.txt`` of the same component, add the following at the end of the file:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-fsanitize=undefined" "-fno-sanitize=shift-base")
|
||||
|
||||
UBSAN Output
|
||||
""""""""""""
|
||||
|
||||
When UBSAN detects an error, a message and the backtrace are printed, for example::
|
||||
When UBSAN detects an error, a message and the backtrace are printed, for example:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
Undefined behavior of type out_of_bounds
|
||||
|
||||
Backtrace:0x4008b383:0x3ffcd8b0 0x4008c791:0x3ffcd8d0 0x4008c587:0x3ffcd8f0 0x4008c6be:0x3ffcd950 0x400db74f:0x3ffcd970 0x400db99c:0x3ffcd9a0
|
||||
|
||||
When using :doc:`IDF Monitor <tools/idf-monitor>`, the backtrace will be decoded to function names and source code locations, pointing to the location where the issue has happened (here it is ``main.c:128``)::
|
||||
When using :doc:`IDF Monitor <tools/idf-monitor>`, the backtrace will be decoded to function names and source code locations, pointing to the location where the issue has happened (here it is ``main.c:128``):
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
0x4008b383: panic_abort at /path/to/esp-idf/components/esp_system/panic.c:367
|
||||
|
||||
@@ -608,34 +629,34 @@ The types of errors reported by UBSAN can be as follows:
|
||||
|
||||
|
||||
.. list-table::
|
||||
:widths: 40 60
|
||||
:header-rows: 1
|
||||
:widths: 40 60
|
||||
:header-rows: 1
|
||||
|
||||
* - Name
|
||||
- Meaning
|
||||
* - ``type_mismatch``, ``type_mismatch_v1``
|
||||
- Incorrect pointer value: null, unaligned, not compatible with the given type.
|
||||
* - ``add_overflow``, ``sub_overflow``, ``mul_overflow``, ``negate_overflow``
|
||||
- Integer overflow during addition, subtraction, multiplication, negation.
|
||||
* - ``divrem_overflow``
|
||||
- Integer division by 0 or ``INT_MIN``.
|
||||
* - ``shift_out_of_bounds``
|
||||
- Overflow in left or right shift operators.
|
||||
* - ``out_of_bounds``
|
||||
- Access outside of bounds of an array.
|
||||
* - ``unreachable``
|
||||
- Unreachable code executed.
|
||||
* - ``missing_return``
|
||||
- Non-void function has reached its end without returning a value (C++ only).
|
||||
* - ``vla_bound_not_positive``
|
||||
- Size of variable length array is not positive.
|
||||
* - ``load_invalid_value``
|
||||
- Value of ``bool`` or ``enum`` (C++ only) variable is invalid (out of bounds).
|
||||
* - ``nonnull_arg``
|
||||
- Null argument passed to a function which is declared with a ``nonnull`` attribute.
|
||||
* - ``nonnull_return``
|
||||
- Null value returned from a function which is declared with ``returns_nonnull`` attribute.
|
||||
* - ``builtin_unreachable``
|
||||
- ``__builtin_unreachable`` function called.
|
||||
* - ``pointer_overflow``
|
||||
- Overflow in pointer arithmetic.
|
||||
* - Name
|
||||
- Meaning
|
||||
* - ``type_mismatch``, ``type_mismatch_v1``
|
||||
- Incorrect pointer value: null, unaligned, not compatible with the given type.
|
||||
* - ``add_overflow``, ``sub_overflow``, ``mul_overflow``, ``negate_overflow``
|
||||
- Integer overflow during addition, subtraction, multiplication, negation.
|
||||
* - ``divrem_overflow``
|
||||
- Integer division by 0 or ``INT_MIN``.
|
||||
* - ``shift_out_of_bounds``
|
||||
- Overflow in left or right shift operators.
|
||||
* - ``out_of_bounds``
|
||||
- Access outside of bounds of an array.
|
||||
* - ``unreachable``
|
||||
- Unreachable code executed.
|
||||
* - ``missing_return``
|
||||
- Non-void function has reached its end without returning a value (C++ only).
|
||||
* - ``vla_bound_not_positive``
|
||||
- Size of variable length array is not positive.
|
||||
* - ``load_invalid_value``
|
||||
- Value of ``bool`` or ``enum`` (C++ only) variable is invalid (out of bounds).
|
||||
* - ``nonnull_arg``
|
||||
- Null argument passed to a function which is declared with a ``nonnull`` attribute.
|
||||
* - ``nonnull_return``
|
||||
- Null value returned from a function which is declared with ``returns_nonnull`` attribute.
|
||||
* - ``builtin_unreachable``
|
||||
- ``__builtin_unreachable`` function called.
|
||||
* - ``pointer_overflow``
|
||||
- Overflow in pointer arithmetic.
|
||||
|
@@ -15,10 +15,12 @@ Frame Format
|
||||
|
||||
ESP-NOW uses a vendor-specific action frame to transmit ESP-NOW data. The default ESP-NOW bit rate is 1 Mbps.
|
||||
|
||||
Currently, ESP-NOW supports two versions: v1.0 and v2.0. The maximum packet length supported by v2.0 devices is ESP_NOW_MAX_DATA_LEN_V2 bytes, while the maximum packet length supported by v1.0 devices is ESP_NOW_MAX_DATA_LEN bytes.
|
||||
Currently, ESP-NOW supports two versions: v1.0 and v2.0. The maximum packet length supported by v2.0 devices is 1490 (``ESP_NOW_MAX_DATA_LEN_V2``) bytes, while the maximum packet length supported by v1.0 devices is 250 (``ESP_NOW_MAX_DATA_LEN``) bytes.
|
||||
|
||||
The v2.0 devices are capable of receiving packets from both v2.0 and v1.0 devices. In contrast, v1.0 devices can only receive packets from other v1.0 devices.
|
||||
However, v1.0 devices can receive v2.0 packets if the packet length is less than or equal to ESP_NOW_MAX_IE_DATA_LEN.
|
||||
For packets exceeding this length, the v1.0 devices will either truncate the data to the first ESP_NOW_MAX_IE_DATA_LEN bytes or discard the packet entirely.
|
||||
|
||||
However, v1.0 devices can receive v2.0 packets if the packet length is less than or equal to 250 (``ESP_NOW_MAX_IE_DATA_LEN``).For packets exceeding this length, the v1.0 devices will either truncate the data to the first 250 (``ESP_NOW_MAX_IE_DATA_LEN``) bytes or discard the packet entirely.
|
||||
|
||||
For detailed behavior, please refer to the documentation corresponding to the specific IDF version.
|
||||
|
||||
The format of the vendor-specific action frame is as follows:
|
||||
|
@@ -1,5 +1,6 @@
|
||||
ESP-Modbus
|
||||
==========
|
||||
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
The Espressif ESP-Modbus Library (esp-modbus) supports Modbus communication in the networks based on RS485, Wi-Fi, and Ethernet interfaces.
|
||||
|
@@ -85,8 +85,8 @@ Advantages
|
||||
|
||||
- {IDF_TARGET_NAME} provides the facility to permanently revoke individual public keys. This can be configured conservatively or aggressively.
|
||||
|
||||
- Conservatively: The old key is revoked after the bootloader and application have successfully migrated to a new key.
|
||||
- Aggressively: The key is revoked as soon as verification with this key fails.
|
||||
- Conservatively: The old key is revoked after the bootloader and application have successfully migrated to a new key.
|
||||
- Aggressively: The key is revoked as soon as verification with this key fails.
|
||||
|
||||
- The same image format and signature verification method is applied for applications and the second stage bootloader.
|
||||
|
||||
@@ -166,7 +166,7 @@ The signature block starts on a 4 KB aligned boundary and has a flash sector of
|
||||
- {IDF_TARGET_ECDSA_TIME}
|
||||
- {IDF_TARGET_CPU_FREQ}
|
||||
|
||||
The above table compares the time taken to verify a signature in a particular scheme. It does not indicate the boot-up time.
|
||||
The above table compares the time taken to verify a signature in a particular scheme. It does not indicate the boot-up time.
|
||||
|
||||
The content of each signature block is shown in the following table:
|
||||
|
||||
@@ -216,7 +216,7 @@ The content of each signature block is shown in the following table:
|
||||
|
||||
.. note::
|
||||
|
||||
R and M' are used for hardware-assisted Montgomery Multiplication.
|
||||
R and M' are used for hardware-assisted Montgomery Multiplication.
|
||||
|
||||
.. only:: SOC_SECURE_BOOT_V2_ECC
|
||||
|
||||
@@ -399,11 +399,11 @@ How To Enable Secure Boot v2
|
||||
|
||||
.. important::
|
||||
|
||||
A signing key generated this way will use the best random number source available to the OS and its Python installation, which is `/dev/urandom` on OSX/Linux and `CryptGenRandom()` on Windows. If this random number source is weak, then the private key will be weak.
|
||||
A signing key generated this way will use the best random number source available to the OS and its Python installation, which is `/dev/urandom` on OSX/Linux and `CryptGenRandom()` on Windows. If this random number source is weak, then the private key will be weak.
|
||||
|
||||
.. important::
|
||||
|
||||
For production environments, we recommend generating the key pair using OpenSSL or another industry-standard encryption program. See :ref:`secure-boot-v2-generate-key` for more details.
|
||||
For production environments, we recommend generating the key pair using OpenSSL or another industry-standard encryption program. See :ref:`secure-boot-v2-generate-key` for more details.
|
||||
|
||||
7. Run ``idf.py bootloader`` to build a Secure Boot-enabled bootloader. The build output will include a prompt for a flashing command, using ``esptool.py write_flash``.
|
||||
|
||||
@@ -419,11 +419,11 @@ How To Enable Secure Boot v2
|
||||
|
||||
.. note::
|
||||
|
||||
Secure Boot will not be enabled until after a valid partition table and app image have been flashed. This is to prevent accidents before the system is fully configured.
|
||||
Secure Boot will not be enabled until after a valid partition table and app image have been flashed. This is to prevent accidents before the system is fully configured.
|
||||
|
||||
.. note::
|
||||
|
||||
If the {IDF_TARGET_NAME} is reset or powered down during the first boot, it will start the process again on the next boot.
|
||||
If the {IDF_TARGET_NAME} is reset or powered down during the first boot, it will start the process again on the next boot.
|
||||
|
||||
11. On subsequent boots, the Secure Boot hardware will verify that the second stage bootloader has not changed, and the second stage bootloader will verify the signed app image using the validated public key portion of its appended signature block.
|
||||
|
||||
@@ -445,21 +445,21 @@ The following keys must be read-protected on the device, the respective hardware
|
||||
|
||||
.. list::
|
||||
|
||||
:SOC_FLASH_ENC_SUPPORTED:* Flash encryption key
|
||||
:SOC_FLASH_ENC_SUPPORTED:* Flash encryption key
|
||||
|
||||
:SOC_HMAC_SUPPORTED:* HMAC keys
|
||||
:SOC_HMAC_SUPPORTED:* HMAC keys
|
||||
|
||||
:SOC_ECDSA_SUPPORTED:* ECDSA keys
|
||||
:SOC_ECDSA_SUPPORTED:* ECDSA keys
|
||||
|
||||
:SOC_KEY_MANAGER_SUPPORTED:* Key Manager keys
|
||||
:SOC_KEY_MANAGER_SUPPORTED:* Key Manager keys
|
||||
|
||||
**Non-read protected keys**:
|
||||
The following keys must not be read-protected on the device as the software needs to access them (readable by software):
|
||||
|
||||
.. list::
|
||||
|
||||
:SOC_SECURE_BOOT_SUPPORTED:* Secure boot public key digest
|
||||
* User data
|
||||
:SOC_SECURE_BOOT_SUPPORTED:* Secure boot public key digest
|
||||
* User data
|
||||
|
||||
When Secure Boot is enabled, it shall disable the ability to read-protect further eFuses by default. If you want keep the ability to read-protect an eFuse later in the application (e.g, a key mentioned in the above list of read-protected keys) then you need to enable the config :ref:`CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS` at the same time when you enable Secure Boot.
|
||||
|
||||
@@ -467,7 +467,7 @@ Ideally, it is strongly recommended that all such keys must been burned before e
|
||||
|
||||
.. note::
|
||||
|
||||
If :doc:`/security/flash-encryption` is enabled by the 2nd stage bootloader at the time of enabling Secure Boot, it ensures that the flash encryption key generated on the first boot shall already be read-protected.
|
||||
If :doc:`/security/flash-encryption` is enabled by the second stage bootloader at the time of enabling Secure Boot, it ensures that the flash encryption key generated on the first boot shall already be read-protected.
|
||||
|
||||
.. _secure-boot-v2-generate-key:
|
||||
|
||||
@@ -478,11 +478,11 @@ The build system will prompt you with a command to generate a new signing key vi
|
||||
|
||||
.. only:: esp32 or SOC_SECURE_BOOT_V2_RSA
|
||||
|
||||
The ``--version 2`` parameter will generate the RSA 3072 private key for Secure Boot v2. Additionally ``--scheme rsa3072`` can be passed as well to generate RSA 3072 private key.
|
||||
The ``--version 2`` parameter will generate the RSA 3072 private key for Secure Boot v2. Additionally ``--scheme rsa3072`` can be passed as well to generate RSA 3072 private key.
|
||||
|
||||
.. only:: SOC_SECURE_BOOT_V2_ECC
|
||||
|
||||
Select the ECDSA scheme by passing ``--version 2 --scheme ecdsa256`` or ``--version 2 --scheme ecdsa192`` to generate corresponding ECDSA private key.
|
||||
Select the ECDSA scheme by passing ``--version 2 --scheme ecdsa256`` or ``--version 2 --scheme ecdsa192`` to generate corresponding ECDSA private key.
|
||||
|
||||
The strength of the signing key is proportional to (a) the random number source of the system, and (b) the correctness of the algorithm used. For production devices, we recommend generating signing keys from a system with a quality entropy source and using the best available {IDF_TARGET_SBV2_SCHEME} key generation utilities.
|
||||
|
||||
@@ -502,13 +502,13 @@ For example, to generate a signing key using the OpenSSL command line:
|
||||
|
||||
.. code-block::
|
||||
|
||||
openssl ecparam -name prime192v1 -genkey -noout -out my_secure_boot_signing_key.pem
|
||||
openssl ecparam -name prime192v1 -genkey -noout -out my_secure_boot_signing_key.pem
|
||||
|
||||
For the ECC NIST256p curve
|
||||
|
||||
.. code-block::
|
||||
|
||||
openssl ecparam -name prime256v1 -genkey -noout -out my_secure_boot_signing_key.pem
|
||||
openssl ecparam -name prime256v1 -genkey -noout -out my_secure_boot_signing_key.pem
|
||||
|
||||
Remember that the strength of the Secure Boot system depends on keeping the signing key private.
|
||||
|
||||
@@ -529,13 +529,13 @@ After the app image and partition table are built, the build system will print s
|
||||
|
||||
.. code-block::
|
||||
|
||||
idf.py secure-sign-data BINARY_FILE --keyfile PRIVATE_SIGNING_KEY
|
||||
idf.py secure-sign-data BINARY_FILE --keyfile PRIVATE_SIGNING_KEY
|
||||
|
||||
The above command appends the image signature to the existing binary. You can use the `--output` argument to write the signed binary to a separate file:
|
||||
|
||||
.. code-block::
|
||||
|
||||
idf.py secure-sign-data --keyfile PRIVATE_SIGNING_KEY --output SIGNED_BINARY_FILE BINARY_FILE
|
||||
idf.py secure-sign-data --keyfile PRIVATE_SIGNING_KEY --output SIGNED_BINARY_FILE BINARY_FILE
|
||||
|
||||
|
||||
Signing Using Pre-calculated Signatures
|
||||
@@ -547,7 +547,7 @@ In such cases, the firmware image should be built by disabling the option :ref:`
|
||||
|
||||
.. code-block::
|
||||
|
||||
idf.py secure-sign-data --pub-key PUBLIC_SIGNING_KEY --signature SIGNATURE_FILE --output SIGNED_BINARY_FILE BINARY_FILE
|
||||
idf.py secure-sign-data --pub-key PUBLIC_SIGNING_KEY --signature SIGNATURE_FILE --output SIGNED_BINARY_FILE BINARY_FILE
|
||||
|
||||
The above command verifies the signature, generates a signature block (refer to :ref:`signature-block-format`), and appends it to the binary file.
|
||||
|
||||
@@ -563,13 +563,13 @@ In such cases, disable the option :ref:`CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES
|
||||
|
||||
.. note::
|
||||
|
||||
For all the above three remote signing workflows, the signed binary is written to the filename provided to the ``--output`` argument, and the option ``--append_signatures`` allows us to append multiple signatures (up to 3) to the image.
|
||||
For all the above three remote signing workflows, the signed binary is written to the filename provided to the ``--output`` argument, and the option ``--append_signatures`` allows us to append multiple signatures (up to 3) to the image.
|
||||
|
||||
.. only:: not SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
|
||||
|
||||
.. note::
|
||||
|
||||
For all the above three remote signing workflows, the signed binary is written to the filename provided to the ``--output`` argument.
|
||||
For all the above three remote signing workflows, the signed binary is written to the filename provided to the ``--output`` argument.
|
||||
|
||||
|
||||
Secure Boot Best Practices
|
||||
@@ -600,7 +600,7 @@ Secure Boot Best Practices
|
||||
|
||||
* The bootloader should be signed with all the private key(s) that are needed for the life of the device, before it is flashed.
|
||||
* The build system can sign with at most one private key, user has to run manual commands to append more signatures if necessary.
|
||||
* You can use the append functionality of ``idf.py secure-sign-data``, this command would also printed at the end of the Secure Boot V2 enabled bootloader compilation.
|
||||
* You can use the append functionality of ``idf.py secure-sign-data``, this command would also printed at the end of the Secure Boot v2 enabled bootloader compilation.
|
||||
|
||||
.. code-block::
|
||||
|
||||
@@ -674,12 +674,12 @@ Secure Boot is integrated into the ESP-IDF build system, so ``idf.py build`` wil
|
||||
|
||||
However, it is possible to use the ``idf.py`` or the ``openssl`` tool to generate standalone signatures and verify them. Using ``idf.py`` is recommended, but in case you need to generate or verify signatures in non-ESP-IDF environments, you could also use the ``openssl`` commands as the Secure Boot v2 signature generation is compliant with the standard signing algorithms.
|
||||
|
||||
Generating and Verifying signatures using ``idf.py``
|
||||
Generating and Verifying Signatures Using ``idf.py``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
1. To sign a binary image:
|
||||
|
||||
.. code-block::
|
||||
.. code-block::
|
||||
|
||||
idf.py secure-sign-data --keyfile ./my_signing_key.pem --output ./image_signed.bin image-unsigned.bin
|
||||
|
||||
@@ -687,11 +687,11 @@ Keyfile is the PEM file containing an {IDF_TARGET_SBV2_KEY} private signing key.
|
||||
|
||||
2. To verify a signed binary image:
|
||||
|
||||
.. code-block::
|
||||
.. code-block::
|
||||
|
||||
idf.py secure-verify-signature --keyfile ./my_signing_key.pem image_signed.bin
|
||||
|
||||
Keyfile is the PEM file containing an {IDF_TARGET_SBV2_KEY} public/\private signing key.
|
||||
Keyfile is the PEM file containing an {IDF_TARGET_SBV2_KEY} public/private signing key.
|
||||
|
||||
Generating and Verifying signatures using OpenSSL
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -770,7 +770,7 @@ If Secure Boot is used without :doc:`flash-encryption`, it is possible to launch
|
||||
|
||||
.. important::
|
||||
|
||||
{IDF_TARGET_NAME} has only one eFuse key block, which is used for both keys: Secure Boot and Flash Encryption. The eFuse key block can only be burned once. Therefore these keys should be burned together at the same time. Please note that ``Secure Boot`` and ``Flash Encryption`` can not be enabled separately as subsequent writes to the eFuse key block shall return an error.
|
||||
{IDF_TARGET_NAME} has only one eFuse key block, which is used for both keys: Secure Boot and Flash Encryption. The eFuse key block can only be burned once. Therefore these keys should be burned together at the same time. Please note that ``Secure Boot`` and ``Flash Encryption`` can not be enabled separately as subsequent writes to the eFuse key block shall return an error.
|
||||
|
||||
|
||||
.. _signed-app-verify-v2:
|
||||
|
@@ -13,17 +13,17 @@
|
||||
- CPU 异常:|CPU_EXCEPTIONS_LIST|
|
||||
- 系统级检查错误:
|
||||
|
||||
.. list::
|
||||
.. list::
|
||||
|
||||
- :doc:`中断看门狗 <../api-reference/system/wdts>` 超时
|
||||
- :doc:`任务看门狗 <../api-reference/system/wdts>` 超时(只有开启 :ref:`CONFIG_ESP_TASK_WDT_PANIC` 后才会触发严重错误)
|
||||
- 高速缓存访问错误
|
||||
:SOC_MEMPROT_SUPPORTED: - 内存保护故障
|
||||
- 掉电检测事件
|
||||
- 堆栈溢出
|
||||
- 堆栈粉碎保护检查
|
||||
- 堆完整性检查
|
||||
- 未定义行为清理器 (UBSAN) 检查
|
||||
- :doc:`中断看门狗 <../api-reference/system/wdts>` 超时
|
||||
- :doc:`任务看门狗 <../api-reference/system/wdts>` 超时(只有开启 :ref:`CONFIG_ESP_TASK_WDT_PANIC` 后才会触发严重错误)
|
||||
- 高速缓存访问错误
|
||||
:SOC_MEMPROT_SUPPORTED: - 内存保护故障
|
||||
- 掉电检测事件
|
||||
- 堆栈溢出
|
||||
- 堆栈粉碎保护检查
|
||||
- 堆完整性检查
|
||||
- 未定义行为清理器 (UBSAN) 检查
|
||||
|
||||
- 使用 ``assert``、``configASSERT`` 等类似的宏断言失败。
|
||||
|
||||
@@ -50,25 +50,25 @@
|
||||
|
||||
紧急处理程序接下来的行为将取决于 :ref:`CONFIG_ESP_SYSTEM_PANIC` 的设置,支持的选项包括:
|
||||
|
||||
- 打印 CPU 寄存器,然后重启(``CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT``)- 默认选项
|
||||
- 打印 CPU 寄存器,然后重启 (``CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT``) - 默认选项
|
||||
|
||||
打印系统发生异常时 CPU 寄存器的值,打印回溯,最后重启芯片。
|
||||
打印系统发生异常时 CPU 寄存器的值,打印回溯,最后重启芯片。
|
||||
|
||||
- 打印 CPU 寄存器,然后暂停(``CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT``)
|
||||
- 打印 CPU 寄存器,然后暂停 (``CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT``)
|
||||
|
||||
与上一个选项类似,但不会重启,而是选择暂停程序的运行。重启程序需要外部执行复位操作。
|
||||
与上一个选项类似,但不会重启,而是选择暂停程序的运行。重启程序需要外部执行复位操作。
|
||||
|
||||
- 静默重启(``CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT``)
|
||||
- 静默重启 (``CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT``)
|
||||
|
||||
不打印 CPU 寄存器的值,也不打印回溯,立即重启芯片。
|
||||
不打印 CPU 寄存器的值,也不打印回溯,立即重启芯片。
|
||||
|
||||
- 调用 GDB Stub(``CONFIG_ESP_SYSTEM_PANIC_GDBSTUB``)
|
||||
- 调用 GDB Stub (``CONFIG_ESP_SYSTEM_PANIC_GDBSTUB``)
|
||||
|
||||
启动 GDB 服务器,通过控制台 UART 接口与 GDB 进行通信。该选项只提供只读调试或者事后调试,详细信息请参阅 `GDB Stub`_。
|
||||
启动 GDB 服务器,通过控制台 UART 接口与 GDB 进行通信。该选项只提供只读调试或者事后调试,详细信息请参阅 `GDB Stub`_。
|
||||
|
||||
.. note::
|
||||
|
||||
仅当构建中包含组件 ``esp_gdbstub`` 时,配置选项 :ref:`CONFIG_ESP_SYSTEM_PANIC` 中的 ``CONFIG_ESP_SYSTEM_PANIC_GDBSTUB`` 选项可用。
|
||||
仅当构建中包含组件 ``esp_gdbstub`` 时,配置选项 :ref:`CONFIG_ESP_SYSTEM_PANIC` 中的 ``CONFIG_ESP_SYSTEM_PANIC_GDBSTUB`` 选项可用。
|
||||
|
||||
紧急处理程序的行为还受到另外两个配置项的影响:
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
|
||||
- 如果 :ref:`CONFIG_ESP_PANIC_HANDLER_IRAM` 被禁用(默认情况下禁用),紧急处理程序的代码会放置在 flash 而不是 IRAM 中。这意味着,如果 ESP-IDF 在 flash 高速缓存禁用时崩溃,在运行 GDB Stub 和内核转储之前紧急处理程序会自动重新使能 flash 高速缓存。如果 flash 高速缓存也崩溃了,这样做会增加一些小风险。
|
||||
|
||||
如果使能了该选项,紧急处理程序的代码(包括所需的 UART 函数)会放置在 IRAM 中,导致 SRAM 中的可用内存空间变小。当禁用 flash 高速缓存(如写入 SPI flash)时或触发异常导致 flash 高速缓存崩溃时,可用此选项调试一些复杂的崩溃问题。
|
||||
如果使能了该选项,紧急处理程序的代码(包括所需的 UART 函数)会放置在 IRAM 中,导致 SRAM 中的可用内存空间变小。当禁用 flash 高速缓存(如写入 SPI flash)时或触发异常导致 flash 高速缓存崩溃时,可用此选项调试一些复杂的崩溃问题。
|
||||
|
||||
- 如果启用 :ref:`CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS` (默认为禁用)并将其配置为大于 0 的数字,紧急处理程序将基于该数字延迟重启的时间,单位为秒。如果用于监测串行输出的工具不支持停止和检查串行输出,可启用该选项。在这种情况下,借助延迟重启,用户可以在延迟期间检查和调试紧急处理程序的输出(例如回溯)。延迟结束后,设备将重新启动,并记录重置原因。
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
|
||||
.. only:: CONFIG_IDF_TARGET_ARCH_XTENSA
|
||||
|
||||
::
|
||||
.. code-block:: none
|
||||
|
||||
Core 0 register dump:
|
||||
PC : 0x400e14ed PS : 0x00060030 A0 : 0x800d0805 A1 : 0x3ffb5030
|
||||
@@ -148,7 +148,7 @@
|
||||
|
||||
.. only:: CONFIG_IDF_TARGET_ARCH_RISCV
|
||||
|
||||
::
|
||||
.. code-block:: none
|
||||
|
||||
Core 0 register dump:
|
||||
MEPC : 0x420048b4 RA : 0x420048b4 SP : 0x3fc8f2f0 GP : 0x3fc8a600
|
||||
@@ -176,7 +176,7 @@
|
||||
|
||||
.. only:: CONFIG_IDF_TARGET_ARCH_XTENSA
|
||||
|
||||
::
|
||||
.. code-block:: none
|
||||
|
||||
Core 0 register dump:
|
||||
PC : 0x400e14ed PS : 0x00060030 A0 : 0x800d0805 A1 : 0x3ffb5030
|
||||
@@ -197,7 +197,7 @@
|
||||
|
||||
.. only:: CONFIG_IDF_TARGET_ARCH_RISCV
|
||||
|
||||
::
|
||||
.. code-block:: none
|
||||
|
||||
Core 0 register dump:
|
||||
MEPC : 0x420048b4 RA : 0x420048b4 SP : 0x3fc8f2f0 GP : 0x3fc8a600
|
||||
@@ -220,7 +220,7 @@
|
||||
此外,由于紧急处理程序中提供了堆栈转储,因此 :doc:`IDF 监视器 <tools/idf-monitor>` 也可以生成并打印回溯。
|
||||
输出结果如下:
|
||||
|
||||
::
|
||||
.. code-block:: none
|
||||
|
||||
Backtrace:
|
||||
|
||||
@@ -238,7 +238,7 @@
|
||||
|
||||
该选项会让编译器为项目的每个函数生成 DWARF 信息。然后,当 CPU 异常发生时,紧急处理程序将解析这些数据并生成出错任务的堆栈回溯信息。输出结果如下:
|
||||
|
||||
::
|
||||
.. code-block:: none
|
||||
|
||||
Backtrace: 0x42009e9a:0x3fc92120 0x42009ea6:0x3fc92120 0x42009ec2:0x3fc92130 0x42024620:0x3fc92150 0x40387d7c:0x3fc92160 0xfffffffe:0x3fc92170
|
||||
|
||||
@@ -256,7 +256,9 @@ GDB Stub
|
||||
|
||||
如果启用了 ``CONFIG_ESP_SYSTEM_PANIC_GDBSTUB`` 选项,在发生严重错误时,紧急处理程序不会复位芯片,相反,它将启动 GDB 远程协议服务器,通常称为 GDB Stub。发生这种情况时,可以让主机上运行的 GDB 实例通过 UART 端口连接到 ESP32。
|
||||
|
||||
如果使用了 :doc:`IDF 监视器 <tools/idf-monitor>`,该工具会在 UART 端口检测到 GDB Stub 提示符后自动启动 GDB,输出会类似于::
|
||||
如果使用了 :doc:`IDF 监视器 <tools/idf-monitor>`,该工具会在 UART 端口检测到 GDB Stub 提示符后自动启动 GDB,输出会类似于:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
Entering gdb stub now.
|
||||
$T0b#e6GNU gdb (crosstool-NG crosstool-ng-1.22.0-80-gff1f415) 7.10
|
||||
@@ -286,11 +288,12 @@ GDB Stub
|
||||
|
||||
RTC 看门狗超时
|
||||
----------------
|
||||
{IDF_TARGET_RTCWDT_RTC_RESET:default="Not updated", esp32="RTCWDT_RTC_RESET", esp32s2="RTCWDT_RTC_RST", esp32s3="RTCWDT_RTC_RST", esp32c3="RTCWDT_RTC_RST", esp32c2="RTCWDT_RTC_RST", esp32c6="LP_WDT_SYS", esp32h2="LP_WDT_SYS", esp32p4="LP_WDT_SYS"}
|
||||
|
||||
{IDF_TARGET_RTCWDT_RTC_RESET:default="未更新", esp32="RTCWDT_RTC_RESET", esp32s2="RTCWDT_RTC_RST", esp32s3="RTCWDT_RTC_RST", esp32c3="RTCWDT_RTC_RST", esp32c2="RTCWDT_RTC_RST", esp32c6="LP_WDT_SYS", esp32h2="LP_WDT_SYS", esp32p4="LP_WDT_SYS"}
|
||||
|
||||
RTC 看门狗在启动代码中用于跟踪执行时间,也有助于防止由于电源不稳定引起的锁定。RTC 看门狗默认启用,参见 :ref:`CONFIG_BOOTLOADER_WDT_ENABLE`。如果执行时间超时,RTC 看门狗将自动重启系统。此时,一级 (ROM) 引导加载程序将打印消息 ``RTC Watchdog Timeout`` 说明重启原因。
|
||||
|
||||
::
|
||||
.. code-block:: none
|
||||
|
||||
rst:0x10 ({IDF_TARGET_RTCWDT_RTC_RESET})
|
||||
|
||||
@@ -310,7 +313,7 @@ Guru Meditation 错误
|
||||
|
||||
.. note::
|
||||
|
||||
想要了解 "Guru Meditation" 的历史渊源,请参阅 `维基百科 <https://en.wikipedia.org/wiki/Guru_Meditation>`_ 。
|
||||
想要了解 "Guru Meditation" 的历史渊源,请参阅 `维基百科 <https://en.wikipedia.org/wiki/Guru_Meditation>`_ 。
|
||||
|
||||
|
||||
|ILLEGAL_INSTR_MSG|
|
||||
@@ -322,9 +325,9 @@ Guru Meditation 错误
|
||||
|
||||
- 无法从 SPI flash 中读取下一条指令,这通常发生在:
|
||||
|
||||
- 应用程序将 SPI flash 的管脚重新配置为其它功能(如 GPIO、UART 等)。有关 SPI flash 管脚的详细信息,请参阅硬件设计指南和芯片/模组的数据手册。
|
||||
- 应用程序将 SPI flash 的管脚重新配置为其它功能(如 GPIO、UART 等)。有关 SPI flash 管脚的详细信息,请参阅硬件设计指南和芯片/模组的数据手册。
|
||||
|
||||
- 某些外部设备意外连接到 SPI flash 的管脚上,干扰了 {IDF_TARGET_NAME} 和 SPI flash 之间的通信。
|
||||
- 某些外部设备意外连接到 SPI flash 的管脚上,干扰了 {IDF_TARGET_NAME} 和 SPI flash 之间的通信。
|
||||
|
||||
- 在 C++ 代码中,退出 non-void 函数而无返回值被认为是未定义的行为。启用优化后,编译器通常会忽略此类函数的结尾,导致 |ILLEGAL_INSTR_MSG| 异常。默认情况下,ESP-IDF 构建系统启用 ``-Werror=return-type``,这意味着缺少返回语句会被视为编译时错误。但是,如果应用程序项目禁用了编译器警告,可能就无法检测到该问题,在运行时就会出现 |ILLEGAL_INSTR_MSG| 异常。
|
||||
|
||||
@@ -402,8 +405,8 @@ Interrupt wdt timeout on CPU0 / CPU1
|
||||
|
||||
.. only:: SOC_MEMPROT_SUPPORTED
|
||||
|
||||
内存保护错误
|
||||
^^^^^^^^^^^^
|
||||
Memory Protection Fault
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
ESP-IDF 中使用 {IDF_TARGET_NAME} 的权限控制功能来防止以下类型的内存访问:
|
||||
|
||||
@@ -424,7 +427,9 @@ Interrupt wdt timeout on CPU0 / CPU1
|
||||
|
||||
{IDF_TARGET_NAME} 内部集成掉电检测电路,并且会默认启用。如果电源电压低于安全值,掉电检测器可以触发系统复位。掉电检测器可以使用 :ref:`CONFIG_ESP_BROWNOUT_DET` 和 :ref:`CONFIG_ESP_BROWNOUT_DET_LVL_SEL` 这两个选项进行设置。
|
||||
|
||||
当掉电检测器被触发时,会打印如下信息::
|
||||
当掉电检测器被触发时,会打印如下信息:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
Brownout detector was triggered
|
||||
|
||||
@@ -434,9 +439,11 @@ Interrupt wdt timeout on CPU0 / CPU1
|
||||
|
||||
|
||||
堆不完整
|
||||
^^^^^^^^^^^
|
||||
^^^^^^^^
|
||||
|
||||
ESP-IDF 堆的实现包含许多运行时的堆结构检查,可以在 menuconfig 中开启额外的检查(“Heap Poisoning”)。如果其中的某项检查失败,则会打印类似如下信息::
|
||||
ESP-IDF 堆的实现包含许多运行时的堆结构检查,可以在 menuconfig 中开启额外的检查(“Heap Poisoning”)。如果其中的某项检查失败,则会打印类似如下信息:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
CORRUPT HEAP: Bad tail at 0x3ffe270a. Expected 0xbaad5678 got 0xbaac5678
|
||||
assertion "head != NULL" failed: file "/Users/user/esp/esp-idf/components/heap/multi_heap_poisoning.c", line 201, function: multi_heap_free
|
||||
@@ -452,7 +459,7 @@ ESP-IDF 堆的实现包含许多运行时的堆结构检查,可以在 menuconf
|
||||
.. _Hardware-Stack-Guard:
|
||||
|
||||
硬件堆栈保护
|
||||
""""""""""""""""""""
|
||||
""""""""""""
|
||||
|
||||
{IDF_TARGET_NAME} 集成了辅助调试模块,支持监测堆栈指针 (SP) 寄存器,确保其值位于已分配给堆栈的内存范围内。发生中断处理或 FreeRTOS 切换上下文时,辅助调试模块都会设置新的堆栈监测范围。注意,该操作会对性能产生一定影响。
|
||||
|
||||
@@ -473,26 +480,27 @@ ESP-IDF 堆的实现包含许多运行时的堆结构检查,可以在 menuconf
|
||||
.. _FreeRTOS-End-Of-Stack-Watchpoint:
|
||||
|
||||
FreeRTOS 任务堆栈末尾监视点
|
||||
""""""""""""""""""""""""""""""""
|
||||
"""""""""""""""""""""""""""
|
||||
|
||||
ESP-IDF 支持基于监视点的 FreeRTOS 堆栈溢出检测机制。每次 FreeRTOS 切换任务上下文时,都会设置一个监视点,用于监视堆栈的最后 32 字节。
|
||||
|
||||
通常,该设置会提前触发监视点,触发点可能会比预期提前多达 28 字节。基于 FreeRTOS 中堆栈金丝雀的大小为 20 字节,故将观察范围设置为 32 字节,确保可以在堆栈金丝雀遭到破坏前及时触发监测点。
|
||||
|
||||
.. note::
|
||||
|
||||
并非每次堆栈溢出都能触发监视点。如果任务绕过堆栈金丝雀的位置访问堆栈,则无法触发监视点。
|
||||
|
||||
监视点触发后,将打印类似如下信息:
|
||||
|
||||
.. only:: CONFIG_IDF_TARGET_ARCH_XTENSA
|
||||
|
||||
::
|
||||
.. code-block:: none
|
||||
|
||||
Debug exception reason: Stack canary watchpoint triggered (task_name)
|
||||
|
||||
.. only:: CONFIG_IDF_TARGET_ARCH_RISCV
|
||||
|
||||
::
|
||||
.. code-block:: none
|
||||
|
||||
Guru Meditation Error: Core 0 panic'ed (Breakpoint). Exception was unhandled.
|
||||
|
||||
@@ -500,14 +508,16 @@ ESP-IDF 支持基于监视点的 FreeRTOS 堆栈溢出检测机制。每次 Free
|
||||
|
||||
|
||||
FreeRTOS 堆栈检查
|
||||
"""""""""""""""""""""
|
||||
"""""""""""""""""
|
||||
|
||||
请参见 :ref:`CONFIG_FREERTOS_CHECK_STACKOVERFLOW`。
|
||||
|
||||
堆栈粉碎
|
||||
^^^^^^^^^^
|
||||
^^^^^^^^
|
||||
|
||||
堆栈粉碎保护(基于 GCC ``-fstack-protector*`` 标志)可以通过 ESP-IDF 中的 :ref:`CONFIG_COMPILER_STACK_CHECK_MODE` 选项来开启。如果检测到堆栈粉碎,则会打印类似如下的信息::
|
||||
堆栈粉碎保护(基于 GCC ``-fstack-protector*`` 标志)可以通过 ESP-IDF 中的 :ref:`CONFIG_COMPILER_STACK_CHECK_MODE` 选项来开启。如果检测到堆栈粉碎,则会打印类似如下的信息:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
Stack smashing protect failure!
|
||||
|
||||
@@ -532,8 +542,19 @@ FreeRTOS 堆栈检查
|
||||
.. |CACHE_ERR_MSG| replace:: Cache error
|
||||
.. |STACK_OVERFLOW| replace:: 堆栈溢出
|
||||
|
||||
|
||||
.. only:: SOC_CPU_HAS_LOCKUP_RESET
|
||||
|
||||
CPU 锁死
|
||||
^^^^^^^^
|
||||
|
||||
若出现双重异常,即当 CPU 已经在异常处理程序中时,又出现了其他异常,则 CPU 会锁死,并触发系统复位。当 cache 出现问题,导致 CPU 无法访问外部存储时,CPU 就会进入锁死状态。此时,紧急处理程序也会因为无法获取指令或读取数据而崩溃。
|
||||
|
||||
通过配置选项 :ref:`CONFIG_ESP_PANIC_HANDLER_IRAM`,可以将紧急处理程序的代码放在 IRAM 中,这样即使 cache 被禁用也可以访问 IRAM,从而获取更多关于锁死原因的信息。
|
||||
|
||||
|
||||
未定义行为清理器 (UBSAN) 检查
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
未定义行为清理器 (UBSAN) 是一种编译器功能,它会为可能不正确的操作添加运行时检查,例如:
|
||||
|
||||
@@ -544,13 +565,15 @@ FreeRTOS 堆栈检查
|
||||
请参考 `GCC 文档 <https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html>`_ 中的 ``-fsanitize=undefined`` 选项,查看支持检查的完整列表。
|
||||
|
||||
使能 UBSAN
|
||||
""""""""""""""
|
||||
""""""""""
|
||||
|
||||
默认情况下未启用 UBSAN。可以通过在构建系统中添加编译器选项 ``-fsanitize=undefined`` 在文件、组件或项目级别上使能 UBSAN。
|
||||
|
||||
在对使用 SoC 硬件寄存器头文件(``soc/xxx_reg.h``)的代码使能 UBSAN 时,建议使用 ``-fno-sanitize=shift-base`` 选项禁用移位基数清理器。这是由于 ESP-IDF 寄存器头文件目前包含的模式会对这个特定的清理器选项造成误报。
|
||||
|
||||
要在项目级使能 UBSAN,请在项目 CMakeLists.txt 文件的末尾添加以下内容::
|
||||
要在项目级使能 UBSAN,请在项目 CMakeLists.txt 文件的末尾添加以下内容:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
idf_build_set_property(COMPILE_OPTIONS "-fsanitize=undefined" "-fno-sanitize=shift-base" APPEND)
|
||||
|
||||
@@ -558,29 +581,37 @@ FreeRTOS 堆栈检查
|
||||
|
||||
使能 UBSAN 会明显增加代码量和数据大小。当为整个应用程序使能 UBSAN 时,微控制器的可用 RAM 无法容纳大多数应用程序(除了一些微小程序)。因此,建议为特定的待测组件使能 UBSAN。
|
||||
|
||||
要为项目 CMakeLists.txt 文件中的特定组件(``component_name``)启用 UBSAN,请在文件末尾添加以下内容::
|
||||
要为项目 CMakeLists.txt 文件中的特定组件(``component_name``)启用 UBSAN,请在文件末尾添加以下内容:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
idf_component_get_property(lib component_name COMPONENT_LIB)
|
||||
target_compile_options(${lib} PRIVATE "-fsanitize=undefined" "-fno-sanitize=shift-base")
|
||||
|
||||
.. 注意::
|
||||
.. note::
|
||||
|
||||
关于 :ref:`构建属性 <cmake-build-properties>` 和 :ref:`组件属性 <cmake-component-properties>` 的更多信息,请查看构建系统文档。
|
||||
关于 :ref:`构建属性 <cmake-build-properties>` 和 :ref:`组件属性 <cmake-component-properties>` 的更多信息,请查看构建系统文档。
|
||||
|
||||
要为同一组件的 CMakeLists.txt 中的特定组件(``component_name``)使能 UBSAN,在文件末尾添加以下内容::
|
||||
要为同一组件的 CMakeLists.txt 中的特定组件(``component_name``)使能 UBSAN,在文件末尾添加以下内容:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-fsanitize=undefined" "-fno-sanitize=shift-base")
|
||||
|
||||
UBSAN 输出
|
||||
""""""""""""""""
|
||||
""""""""""
|
||||
|
||||
当 UBSAN 检测到一个错误时,会打印一个信息和回溯,例如::
|
||||
当 UBSAN 检测到一个错误时,会打印一个信息和回溯,例如:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
Undefined behavior of type out_of_bounds
|
||||
|
||||
Backtrace:0x4008b383:0x3ffcd8b0 0x4008c791:0x3ffcd8d0 0x4008c587:0x3ffcd8f0 0x4008c6be:0x3ffcd950 0x400db74f:0x3ffcd970 0x400db99c:0x3ffcd9a0
|
||||
|
||||
当使用 :doc:`IDF 监视器 <tools/idf-monitor>` 时,回溯会被解码为函数名以及源代码位置,并指向问题发生的位置(这里是 ``main.c:128``)::
|
||||
当使用 :doc:`IDF 监视器 <tools/idf-monitor>` 时,回溯会被解码为函数名以及源代码位置,并指向问题发生的位置(这里是 ``main.c:128``):
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
0x4008b383: panic_abort at /path/to/esp-idf/components/esp_system/panic.c:367
|
||||
|
||||
@@ -598,34 +629,34 @@ UBSAN 报告的错误类型为以下几种:
|
||||
|
||||
|
||||
.. list-table::
|
||||
:widths: 40 60
|
||||
:header-rows: 1
|
||||
:widths: 40 60
|
||||
:header-rows: 1
|
||||
|
||||
* - 名称
|
||||
- 含义
|
||||
* - ``type_mismatch``、``type_mismatch_v1``
|
||||
- 指针值不正确:空、未对齐、或与给定类型不兼容
|
||||
* - ``add_overflow``、``sub_overflow``、``mul_overflow``、``negate_overflow``
|
||||
- 加法、减法、乘法、求反过程中的整数溢出
|
||||
* - ``divrem_overflow``
|
||||
- 整数除以 0 或 ``INT_MIN``
|
||||
* - ``shift_out_of_bounds``
|
||||
- 左移或右移运算符导致的溢出
|
||||
* - ``out_of_bounds``
|
||||
- 访问超出数组范围
|
||||
* - ``unreachable``
|
||||
- 执行无法访问的代码
|
||||
* - ``missing_return``
|
||||
- Non-void 函数已结束而没有返回值(仅限 C++)
|
||||
* - ``vla_bound_not_positive``
|
||||
- 可变长度数组的大小不是正数
|
||||
* - ``load_invalid_value``
|
||||
- bool 或 enum(仅 C++)变量的值无效(超出范围)
|
||||
* - ``nonnull_arg``
|
||||
- 对于 ``nonnull`` 属性的函数,传递给函数的参数为空
|
||||
* - ``nonnull_return``
|
||||
- 对于 ``returns_nonnull`` 属性的函数,函数返回值为空
|
||||
* - ``builtin_unreachable``
|
||||
- 调用 ``__builtin_unreachable`` 函数
|
||||
* - ``pointer_overflow``
|
||||
- 指针运算过程中的溢出
|
||||
* - 名称
|
||||
- 含义
|
||||
* - ``type_mismatch``、``type_mismatch_v1``
|
||||
- 指针值不正确:空、未对齐、或与给定类型不兼容
|
||||
* - ``add_overflow``、``sub_overflow``、``mul_overflow``、``negate_overflow``
|
||||
- 加法、减法、乘法、求反过程中的整数溢出
|
||||
* - ``divrem_overflow``
|
||||
- 整数除以 0 或 ``INT_MIN``
|
||||
* - ``shift_out_of_bounds``
|
||||
- 左移或右移运算符导致的溢出
|
||||
* - ``out_of_bounds``
|
||||
- 访问超出数组范围
|
||||
* - ``unreachable``
|
||||
- 执行无法访问的代码
|
||||
* - ``missing_return``
|
||||
- Non-void 函数已结束而没有返回值(仅限 C++)
|
||||
* - ``vla_bound_not_positive``
|
||||
- 可变长度数组的大小不是正数
|
||||
* - ``load_invalid_value``
|
||||
- bool 或 enum(仅 C++)变量的值无效(超出范围)
|
||||
* - ``nonnull_arg``
|
||||
- 对于 ``nonnull`` 属性的函数,传递给函数的参数为空
|
||||
* - ``nonnull_return``
|
||||
- 对于 ``returns_nonnull`` 属性的函数,函数返回值为空
|
||||
* - ``builtin_unreachable``
|
||||
- 调用 ``__builtin_unreachable`` 函数
|
||||
* - ``pointer_overflow``
|
||||
- 指针运算过程中的溢出
|
||||
|
@@ -314,4 +314,5 @@ ESP-IDF 支持动态 :doc:`/api-reference/system/intr_alloc` 和中断抢占。
|
||||
- 要提高诸如 ``fread`` 和 ``fgets`` 等缓冲读取函数的执行速度,可以增加文件缓冲区的大小。Newlib 的默认值为 128 字节,但可将其增加到 4096、8192 或 16384 字节。为此,可以使用 ``setvbuf`` 函数对特定文件指针进行局部设置,或者通过修改 :ref:`CONFIG_FATFS_VFS_FSTAT_BLKSIZE` 设置来进行全局修改。
|
||||
|
||||
.. note::
|
||||
|
||||
增加缓冲区的大小会增加堆内存的使用量。
|
||||
|
@@ -82,7 +82,6 @@ ESP-NETIF 组件使用了系统事件,典型的网络启动代码如下所示
|
||||
|
||||
初始化网络接口可能有些复杂,ESP-NETIF 提供了一些创建常见接口(例如 Wi-Fi 和以太网)的快捷方式。
|
||||
|
||||
|
||||
请参考以下示例来了解如何初始化默认接口:
|
||||
|
||||
.. list::
|
||||
|
@@ -13,10 +13,15 @@ CTR 与 CBC-MAC 协议 (CCMP) 可用来保护动作帧的安全。ESP-NOW 广泛
|
||||
帧格式
|
||||
------------
|
||||
|
||||
ESP-NOW 使用供应商的动作帧传输数据,默认比特率为 1 Mbps。目前 ESP-NOW 支持两个版本: v1.0 和 v2.0。
|
||||
ESP-NOW 使用供应商的动作帧传输数据,默认比特率为 1 Mbps。
|
||||
|
||||
v2.0 的设备支持的最大数据包长度为 ESP_NOW_MAX_DATA_LEN_V2 bytes; v1.0 的设备支持的最大数据包长度为 ESP_NOW_MAX_DATA_LEN bytes。
|
||||
v2.0 设备可以接收来自 v2.0 和 v1.0 设备的数据包。v1.0 设备能接收来自 v1.0 的数据包。v1.0 设备可以接收长度不超过 ESP_NOW_MAX_IE_DATA_LEN 的 v2.0 数据包,而对于长度超过 ESP_NOW_MAX_IE_DATA_LEN 的数据包,它要么只接收前 ESP_NOW_MAX_IE_DATA_LEN 字节,要么丢弃数据包。具体行为请参考对应 IDF 版本中的文档。
|
||||
目前 ESP-NOW 支持两个版本:v1.0 和 v2.0。v2.0 的设备支持的最大数据包长度为 1490 (``ESP_NOW_MAX_DATA_LEN_V2``) 字节;v1.0 的设备支持的最大数据包长度为 250 (``ESP_NOW_MAX_DATA_LEN``) 字节。
|
||||
|
||||
v2.0 设备可以接收来自 v2.0 和 v1.0 设备的数据包。v1.0 设备只能接收来自 v1.0 设备的数据包。
|
||||
|
||||
当然,v1.0 设备也可以接收长度不超过 250 (``ESP_NOW_MAX_IE_DATA_LEN``) 的 v2.0 数据包,只是如果长度超过此值,就只接收前 250 (``ESP_NOW_MAX_IE_DATA_LEN``) 字节,或是直接丢弃数据包。
|
||||
|
||||
具体行为请参考对应 IDF 版本中的文档。
|
||||
|
||||
供应商的动作帧格式为:
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
ESP-Modbus
|
||||
==========
|
||||
|
||||
:link_to_translation:`en:[English]`
|
||||
|
||||
乐鑫的 ESP-Modbus 库 (esp-modbus) 支持基于 RS485、Wi-Fi 和以太网接口的 Modbus 通信。
|
||||
@@ -8,14 +9,14 @@ ESP-Modbus
|
||||
* `GitHub 上的 ESP-Modbus 组件 <https://github.com/espressif/esp-modbus>`__
|
||||
|
||||
托管文档
|
||||
--------------------
|
||||
--------
|
||||
|
||||
相应文档请参阅:
|
||||
|
||||
* `ESP-Modbus 文档 <https://docs.espressif.com/projects/esp-modbus>`__
|
||||
|
||||
应用示例
|
||||
-------------------
|
||||
--------
|
||||
|
||||
以下示例分别介绍了 ESP-Modbus 库的串行端口、TCP 端口的从机和主机实现。
|
||||
|
||||
@@ -30,8 +31,6 @@ ESP-Modbus
|
||||
详情请参阅具体示例的 ``README.md`` 。
|
||||
|
||||
协议参考
|
||||
-------------------
|
||||
--------
|
||||
|
||||
- Modbus 组织与规范协议请参阅 `The Modbus Organization <https://modbus.org/specs.php>`_。
|
||||
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
:orphan:
|
||||
|
||||
安全启动 (secure boot) v2
|
||||
============================
|
||||
=========================
|
||||
|
||||
:link_to_translation:`en:[English]`
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
{IDF_TARGET_SBV2_KEY:default="RSA-3072", esp32c2="ECDSA-256 或 ECDSA-192", esp32c6="RSA-3072、ECDSA-256 或 ECDSA-192", esp32h2="RSA-3072、ECDSA-256 或 ECDSA-192", esp32p4="RSA-3072、ECDSA-256 或 ECDSA-192", esp32c5="RSA-3072、ECDSA-256、或 ECDSA-192", esp32c61="ECDSA-256 或 ECDSA-192"}
|
||||
|
||||
{IDF_TARGET_SECURE_BOOT_OPTION_TEXT:default="", esp32c6="推荐使用 RSA,其验证时间更短。可以在菜单中选择 RSA 和 ECDSA 方案。", esp32h2="推荐使用 RSA,其验证时间更短。可以在菜单中选择 RSA 和 ECDSA 方案。", esp32p4="推荐使用 RSA,其验证时间更短。可以在菜单中选择 RSA 和 ECDSA 方案。", esp32c5="推荐使用 RSA,其验证时间更短。可以在菜单中选择 RSA 和 ECDSA 方案。"}
|
||||
{IDF_TARGET_SECURE_BOOT_OPTION_TEXT:default="", esp32c6="推荐使用 RSA,其验证时间更短。可以在菜单中选择 RSA 和 ECDSA 方案。", esp32h2="推荐使用 RSA,其验证时间更短。可以在菜单中选择 RSA 和 ECDSA 方案。", esp32p4="推荐使用 RSA,其验证时间更短。可以在菜单中选择 RSA 和 ECDSA 方案。"}
|
||||
|
||||
{IDF_TARGET_ECO_VERSION:default="", esp32="(v3.0 及以上版本)", esp32c3="(v0.3 及以上版本)"}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
芯片版本低于 v3.0 的 ESP32 安全启动请参阅 :doc:`secure-boot-v1`。如果当前芯片版本支持安全启动 v2,推荐使用此模式,相比安全启动 v1 更安全且灵活。
|
||||
|
||||
安全启动 v2 使用基于 {IDF_TARGET_SBV2_SCHEME} 的应用程序和 :ref:`second-stage-bootloader` 验证。若需要使用 {IDF_TARGET_SBV2_SCHEME} 方案对应用程序签名,且无需对引导加载程序签名,同样可以参考本文档。
|
||||
安全启动 v2 使用基于 {IDF_TARGET_SBV2_SCHEME} 的应用程序和 :ref:`second-stage-bootloader` 验证。若需要使用 {IDF_TARGET_SBV2_SCHEME} 方案对应用程序签名,且无需对引导加载程序 (bootloader) 签名,同样可以参考本文档。
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
在本指南中,最常用的命令形式为 ``idf.py secure-<command>``,这是对应 ``espsecure.py <command>`` 的封装。基于 ``idf.py`` 的命令能提供更好的用户体验,但与基于 ``espsecure.py`` 的命令相比,可能会损失一部分高级功能。
|
||||
|
||||
背景
|
||||
----------
|
||||
----
|
||||
|
||||
安全启动通过检查每个启动的软件是否已签名来确保设备不会运行任何未经授权(即未签名)的代码。在 {IDF_TARGET_NAME} 上,这些软件包括二级引导加载程序和每个应用程序的二进制文件。注意,一级 (ROM) 引导加载程序是无法更改的 ROM 代码,因此不需要签名。
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
|
||||
|
||||
优势
|
||||
----------
|
||||
----
|
||||
|
||||
- {IDF_TARGET_SBV2_SCHEME} 的公钥存储在设备上,而相应的 {IDF_TARGET_SBV2_SCHEME} 私钥存储在私密位置,设备无法访问。
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
|
||||
|
||||
使用安全启动 v2
|
||||
----------------------
|
||||
---------------
|
||||
|
||||
以下为使用安全启动 v2 流程的概述。有关如何启用安全启动,请参阅 :ref:`secure-boot-v2-howto`。
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
.. _signature-block-format:
|
||||
|
||||
签名块格式
|
||||
----------------------
|
||||
----------
|
||||
|
||||
签名块以 4 KB 的整数倍为起始位置,拥有独立 flash 扇区。签名计算覆盖了镜像中的所有字节,包括填充字节,请参阅 :ref:`secure_padding`。
|
||||
|
||||
@@ -152,21 +152,21 @@
|
||||
|
||||
.. only:: not esp32p4 or not esp32c5
|
||||
|
||||
.. list-table:: 签名验证耗时比较
|
||||
:widths: 10 10 20
|
||||
:header-rows: 1
|
||||
.. list-table:: 签名验证耗时比较
|
||||
:widths: 10 10 20
|
||||
:header-rows: 1
|
||||
|
||||
* - **验证方案**
|
||||
- **耗时**
|
||||
- **CPU 频率**
|
||||
* - RSA-3072
|
||||
- {IDF_TARGET_RSA_TIME}
|
||||
- {IDF_TARGET_CPU_FREQ}
|
||||
* - ECDSA-P256
|
||||
- {IDF_TARGET_ECDSA_TIME}
|
||||
- {IDF_TARGET_CPU_FREQ}
|
||||
* - **验证方案**
|
||||
- **耗时**
|
||||
- **CPU 频率**
|
||||
* - RSA-3072
|
||||
- {IDF_TARGET_RSA_TIME}
|
||||
- {IDF_TARGET_CPU_FREQ}
|
||||
* - ECDSA-P256
|
||||
- {IDF_TARGET_ECDSA_TIME}
|
||||
- {IDF_TARGET_CPU_FREQ}
|
||||
|
||||
上表比较了特定方案中验证签名所需的时间,不代表启动时间。
|
||||
上表比较了特定方案中验证签名所需的时间,不代表启动时间。
|
||||
|
||||
各签名块内容如下表所示:
|
||||
|
||||
@@ -216,7 +216,7 @@
|
||||
|
||||
.. note::
|
||||
|
||||
R 和 M' 用于硬件辅助的蒙哥马利乘法 (Montgomery Multiplication)。
|
||||
R 和 M' 用于硬件辅助的蒙哥马利乘法 (Montgomery Multiplication)。
|
||||
|
||||
.. only:: SOC_SECURE_BOOT_V2_ECC
|
||||
|
||||
@@ -264,7 +264,7 @@
|
||||
.. _secure_padding:
|
||||
|
||||
安全填充
|
||||
--------------
|
||||
--------
|
||||
|
||||
在安全启动 v2 方案中,应用程序镜像经过处理,会填充到与 flash MMU 页面大小边界对齐,确保只有经过验证的内容会映射到内部地址空间,这称为安全填充。填充后会进行镜像签名计算,随后将签名块 (4 KB) 附加到镜像上。
|
||||
|
||||
@@ -301,7 +301,7 @@
|
||||
.. _verify_signature-block:
|
||||
|
||||
验证签名块
|
||||
-----------------------------
|
||||
----------
|
||||
|
||||
如果签名块的第一个字节是 ``0xe7``,并且偏移量 1196 处存储了有效的 CRC32,则签名块有效,否则无效。
|
||||
|
||||
@@ -309,7 +309,7 @@
|
||||
.. _verify_image:
|
||||
|
||||
验证镜像
|
||||
-----------------------------
|
||||
--------
|
||||
|
||||
如果存储在某个签名块中的公钥是适用于当前设备的有效公钥,且该签名块中存储的签名与从 flash 中读取的镜像数据计算出的签名匹配,则该镜像通过验证。
|
||||
|
||||
@@ -327,10 +327,10 @@
|
||||
|
||||
.. only:: SOC_SECURE_BOOT_V2_ECC and SOC_SECURE_BOOT_V2_RSA
|
||||
|
||||
1. 使用公钥,采用 RSA-PSS(RFC8017 的第 8.1.2 节)算法或 ECDSA(RFC6090 的第 5.3.3 节)算法,验证引导加载程序镜像的签名,并与步骤 (2) 中计算的镜像摘要比较。
|
||||
3. 使用公钥,采用 RSA-PSS(RFC8017 的第 8.1.2 节)算法或 ECDSA(RFC6090 的第 5.3.3 节)算法,验证引导加载程序镜像的签名,并与步骤 (2) 中计算的镜像摘要比较。
|
||||
|
||||
|
||||
bootloader 大小
|
||||
引导加载程序的大小
|
||||
------------------
|
||||
|
||||
启用安全启动和/或 flash 加密都会增加引导加载程序的大小,因此可能需要更新分区表偏移量,请参阅 :ref:`bootloader-size`。
|
||||
@@ -341,7 +341,7 @@ bootloader 大小
|
||||
.. _efuse-usage:
|
||||
|
||||
使用 eFuse
|
||||
-----------
|
||||
----------
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
@@ -373,7 +373,7 @@ bootloader 大小
|
||||
.. _secure-boot-v2-howto:
|
||||
|
||||
启用安全启动 v2
|
||||
----------------------------
|
||||
---------------
|
||||
|
||||
1. 打开 :ref:`project-configuration-menu`,在 ``Security features`` 下设置 ``Enable hardware Secure Boot in bootloader`` 以启用安全启动模式。
|
||||
|
||||
@@ -399,11 +399,11 @@ bootloader 大小
|
||||
|
||||
.. important::
|
||||
|
||||
通过此方法生成的签名密钥将使用操作系统和其 Python 安装中提供的最佳随机数源,在 OSX/Linux 上为 `/dev/urandom`,在 Windows 上为 `CryptGenRandom()`。如果此随机数源不足以提供足够的安全性,那么生成的私钥也不足以提供足够的安全性。
|
||||
通过此方法生成的签名密钥将使用操作系统和其 Python 安装中提供的最佳随机数源,在 OSX/Linux 上为 `/dev/urandom`,在 Windows 上为 `CryptGenRandom()`。如果此随机数源不足以提供足够的安全性,那么生成的私钥也不足以提供足够的安全性。
|
||||
|
||||
.. important::
|
||||
|
||||
在生产环境下,建议使用 OpenSSL 或其他行业标准的加密程序生成密钥对,详情请参阅 :ref:`secure-boot-v2-generate-key`。
|
||||
在生产环境下,建议使用 OpenSSL 或其他行业标准的加密程序生成密钥对,详情请参阅 :ref:`secure-boot-v2-generate-key`。
|
||||
|
||||
7. 运行 ``idf.py bootloader`` 构建启用了安全启动的引导加载程序,构建输出中会包含一个烧录命令的提示,使用 ``esptool.py write_flash`` 烧录。
|
||||
|
||||
@@ -413,23 +413,23 @@ bootloader 大小
|
||||
|
||||
.. note::
|
||||
|
||||
如果启用了安全启动,``idf.py flash`` 不会烧录引导加载程序。
|
||||
如果启用了安全启动,``idf.py flash`` 不会烧录引导加载程序。
|
||||
|
||||
10. 重置 {IDF_TARGET_NAME},它将启动你烧录的二级引导加载程序。该二级引导加载程序会在芯片上启用安全启动,然后验证应用程序镜像签名,并启动应用程序。请查看 {IDF_TARGET_NAME} 的串行控制器输出,确保已启用安全启动,且没有因构建配置发生错误。
|
||||
10. 重置 {IDF_TARGET_NAME} 将启动烧录的二级引导加载程序。该二级引导加载程序会在芯片上启用安全启动,然后验证应用程序镜像签名,并启动应用程序。请查看 {IDF_TARGET_NAME} 的串行控制器输出,确保已启用安全启动,且没有因构建配置发生错误。
|
||||
|
||||
.. note::
|
||||
|
||||
在烧录了有效的分区表和应用程序镜像之前,安全启动不会启用,避免在系统完全配置前发生意外情况。
|
||||
在烧录了有效的分区表和应用程序镜像之前,安全启动不会启用,避免在系统完全配置前发生意外情况。
|
||||
|
||||
.. note::
|
||||
|
||||
如果在初次启动过程中重置或关闭了 {IDF_TARGET_NAME},它会在下次启动时重新开始上述步骤。
|
||||
如果在初次启动过程中重置或关闭了 {IDF_TARGET_NAME},它会在下次启动时重新开始上述步骤。
|
||||
|
||||
11. 在后续启动过程中,安全启动硬件会验证二级引导加载程序是否更改,二级引导加载程序会使用其附加的签名块中经验证的公钥部分,验证已签名的应用程序镜像。
|
||||
|
||||
|
||||
启用安全启动后的限制
|
||||
-----------------------------------------
|
||||
--------------------
|
||||
|
||||
- 任何更新过的引导加载程序或应用程序都需要使用与已存储在 eFuse 中的摘要相匹配的密钥来签名。
|
||||
|
||||
@@ -438,28 +438,28 @@ bootloader 大小
|
||||
- 一旦启用安全启动,就无法再对 eFuse 密钥进行读保护,这可以避免攻击者对存储公共密钥摘要的 eFuse 块进行读保护,进而导致系统无法验证和处理签名,系统服务无法正常运行。有关读保护密钥的更多信息,请参阅下方详细说明。
|
||||
|
||||
烧录读保护密钥
|
||||
~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
**读保护密钥**:
|
||||
以下密钥受到读保护后,相应的硬件将直接访问这些密钥(软件无法读取):
|
||||
|
||||
.. list::
|
||||
|
||||
:SOC_FLASH_ENC_SUPPORTED:* flash 加密密钥
|
||||
:SOC_FLASH_ENC_SUPPORTED:* flash 加密密钥
|
||||
|
||||
:SOC_HMAC_SUPPORTED:* HMAC 密钥
|
||||
:SOC_HMAC_SUPPORTED:* HMAC 密钥
|
||||
|
||||
:SOC_ECDSA_SUPPORTED:* ECDSA 密钥
|
||||
:SOC_ECDSA_SUPPORTED:* ECDSA 密钥
|
||||
|
||||
:SOC_KEY_MANAGER_SUPPORTED:* 密钥管理器密钥
|
||||
:SOC_KEY_MANAGER_SUPPORTED:* 密钥管理器密钥
|
||||
|
||||
**不受读保护的密钥**:
|
||||
因软件访问需要(软件可读取),以下密钥不受读保护:
|
||||
|
||||
.. list::
|
||||
|
||||
:SOC_SECURE_BOOT_SUPPORTED:* 安全启动公共密钥摘要
|
||||
* 用户数据
|
||||
:SOC_SECURE_BOOT_SUPPORTED:* 安全启动公共密钥摘要
|
||||
* 用户数据
|
||||
|
||||
启用安全启动后,默认禁用 eFuses 读保护功能。如后续需在应用程序中对某个 eFuse(例如上述读保护密钥列表中的密钥)进行读保护,请在启用安全启动的同时启用配置项 :ref:`CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS`。
|
||||
|
||||
@@ -467,22 +467,22 @@ bootloader 大小
|
||||
|
||||
.. note::
|
||||
|
||||
如果在启用安全启动时,第二阶段引导加载程序启用了 :doc:`/security/flash-encryption`,则首次启动时生成的 flash 加密密钥已经受到读保护。
|
||||
如果在启用安全启动时,二级引导加载程序启用了 :doc:`/security/flash-encryption`,则首次启动时生成的 flash 加密密钥已经受到读保护。
|
||||
|
||||
.. _secure-boot-v2-generate-key:
|
||||
|
||||
生成安全启动签名密钥
|
||||
----------------------------------
|
||||
--------------------
|
||||
|
||||
根据构建系统提示,使用 ``idf.py secure-generate-signing-key`` 命令生成新签名密钥。
|
||||
|
||||
.. only:: esp32 or SOC_SECURE_BOOT_V2_RSA
|
||||
|
||||
参数 ``--version 2`` 会为安全启动 v2 生成 RSA 3072 私钥。此外,也可以传递 ``--scheme rsa3072`` 生成 RSA 3072 私钥。
|
||||
参数 ``--version 2`` 会为安全启动 v2 生成 RSA 3072 私钥。此外,也可以传递 ``--scheme rsa3072`` 生成 RSA 3072 私钥。
|
||||
|
||||
.. only:: SOC_SECURE_BOOT_V2_ECC
|
||||
|
||||
传递 ``--version 2 --scheme ecdsa256`` 或 ``--version 2 --scheme ecdsa192`` 选择 ECDSA 方案,生成相应的 ECDSA 私钥。
|
||||
传递 ``--version 2 --scheme ecdsa256`` 或 ``--version 2 --scheme ecdsa192`` 选择 ECDSA 方案,生成相应的 ECDSA 私钥。
|
||||
|
||||
签名密钥的强度取决于 (a) 系统的随机数源和 (b) 所用算法的正确性。对于生产设备,建议从具有高质量熵源的系统生成签名密钥,并使用最佳的可用 {IDF_TARGET_SBV2_SCHEME} 密钥生成工具。
|
||||
|
||||
@@ -502,13 +502,13 @@ bootloader 大小
|
||||
|
||||
.. code-block::
|
||||
|
||||
openssl ecparam -name prime192v1 -genkey -noout -out my_secure_boot_signing_key.pem
|
||||
openssl ecparam -name prime192v1 -genkey -noout -out my_secure_boot_signing_key.pem
|
||||
|
||||
生成 ECC NIST256p 曲线密钥
|
||||
|
||||
.. code-block::
|
||||
|
||||
openssl ecparam -name prime256v1 -genkey -noout -out my_secure_boot_signing_key.pem
|
||||
openssl ecparam -name prime256v1 -genkey -noout -out my_secure_boot_signing_key.pem
|
||||
|
||||
注意,安全启动系统的强度取决于能否保持签名密钥的私密性。
|
||||
|
||||
@@ -516,10 +516,10 @@ bootloader 大小
|
||||
.. _remote-sign-v2-image:
|
||||
|
||||
远程镜像签名
|
||||
------------------------
|
||||
------------
|
||||
|
||||
使用 ``idf.py`` 进行签名
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
对于生产构建,将签名密钥存储在远程签名服务器上,而不是本地构建机器上,是一种比较好的方案,这也是默认的 ESP-IDF 安全启动配置。可以使用命令行工具 ``espsecure.py`` 在远程系统上为应用程序镜像和分区表数据签名,供安全启动使用。
|
||||
|
||||
@@ -529,17 +529,17 @@ bootloader 大小
|
||||
|
||||
.. code-block::
|
||||
|
||||
idf.py secure-sign-data BINARY_FILE --keyfile PRIVATE_SIGNING_KEY
|
||||
idf.py secure-sign-data BINARY_FILE --keyfile PRIVATE_SIGNING_KEY
|
||||
|
||||
上述命令将镜像签名附加到现有的二进制文件中,可以使用 `--output` 参数将签名后的二进制文件写入单独的文件:
|
||||
|
||||
.. code-block::
|
||||
|
||||
idf.py secure-sign-data --keyfile PRIVATE_SIGNING_KEY --output SIGNED_BINARY_FILE BINARY_FILE
|
||||
idf.py secure-sign-data --keyfile PRIVATE_SIGNING_KEY --output SIGNED_BINARY_FILE BINARY_FILE
|
||||
|
||||
|
||||
使用预计算的签名进行签名
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
如果存在为镜像生成的有效预计算签名及相应公钥,可以使用这些签名生成一个签名扇区,并将其附加到镜像中。注意,预计算的签名应计算在镜像中的所有字节,包括安全填充字节。
|
||||
|
||||
@@ -547,13 +547,13 @@ bootloader 大小
|
||||
|
||||
.. code-block::
|
||||
|
||||
idf.py secure-sign-data --pub-key PUBLIC_SIGNING_KEY --signature SIGNATURE_FILE --output SIGNED_BINARY_FILE BINARY_FILE
|
||||
idf.py secure-sign-data --pub-key PUBLIC_SIGNING_KEY --signature SIGNATURE_FILE --output SIGNED_BINARY_FILE BINARY_FILE
|
||||
|
||||
上述命令会验证签名,生成签名块(请参阅 :ref:`signature-block-format`),并将其附加到二进制文件中。
|
||||
|
||||
|
||||
使用外部硬件安全模块 (HSM) 进行签名
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
为了提高安全性,可能需要使用外部硬件安全模块 (HSM) 存储私钥,该私钥无法直接访问,但具备一个接口,可以生成二进制文件及其相应公钥的签名。
|
||||
|
||||
@@ -563,17 +563,17 @@ bootloader 大小
|
||||
|
||||
.. note::
|
||||
|
||||
在上述三种远程签名工作流程中,已签名的二进制文件将写入提供给 ``--output`` 参数的文件名中。选项 ``--append_signatures`` 支持将多个签名(最多 3 个)附加到镜像中。
|
||||
在上述三种远程签名工作流程中,已签名的二进制文件将写入提供给 ``--output`` 参数的文件名中。选项 ``--append_signatures`` 支持将多个签名(最多 3 个)附加到镜像中。
|
||||
|
||||
.. only:: not SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
|
||||
|
||||
.. note::
|
||||
|
||||
在上述三种远程签名工作流程中,已签名的二进制文件将写入提供给 ``--output`` 参数的文件名中。
|
||||
在上述三种远程签名工作流程中,已签名的二进制文件将写入提供给 ``--output`` 参数的文件名中。
|
||||
|
||||
|
||||
使用安全启动的建议
|
||||
--------------------------
|
||||
------------------
|
||||
|
||||
* 在具备高质量熵源的系统上生成签名密钥。
|
||||
* 时刻对签名密钥保密,泄漏此密钥将危及安全启动系统。
|
||||
@@ -584,7 +584,7 @@ bootloader 大小
|
||||
.. only:: SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
|
||||
|
||||
密钥管理
|
||||
--------------
|
||||
--------
|
||||
|
||||
* 应独立计算并分别存储 1 到 3 个 {IDF_TARGET_SBV2_KEY} 公钥对(密钥 #0, #1, #2)。
|
||||
* 完成烧录后,应设置 KEY_DIGEST eFuse 为写保护位。
|
||||
@@ -596,11 +596,11 @@ bootloader 大小
|
||||
|
||||
|
||||
多个密钥管理
|
||||
-------------
|
||||
------------
|
||||
|
||||
* 在烧录引导加载程序之前,应使用设备整个生命周期所需的所有私钥对引导加载程序签名。
|
||||
* 构建系统每次只能使用一个私钥签名,如果需要,你必须手动运行命令以附加更多签名。
|
||||
* 你可以使用 ``idf.py secure-sign-data`` 的附加功能,此命令也将在启用安全启动 v2 的引导加载程序编译的末尾显示。
|
||||
* 构建系统每次只能使用一个私钥签名,如果需要,必须手动运行命令以附加更多签名。
|
||||
* 可以使用 ``idf.py secure-sign-data`` 的附加功能,此命令也将在启用安全启动 v2 的引导加载程序编译的末尾显示。
|
||||
|
||||
.. code-block::
|
||||
|
||||
@@ -616,7 +616,7 @@ bootloader 大小
|
||||
.. _secure-boot-v2-key-revocation:
|
||||
|
||||
撤销密钥管理
|
||||
--------------
|
||||
------------
|
||||
|
||||
* 密钥按线性顺序处理,即密钥 #0、密钥 #1、密钥 #2。
|
||||
* 撤销一个密钥后,其余未被撤销的密钥仍可用于应用程序签名。例如,如密钥 #1 被撤销,仍然可以使用密钥 #0 和密钥 #2 给应用程序签名。
|
||||
@@ -630,7 +630,7 @@ bootloader 大小
|
||||
如果在开发流程中需要保留未使用摘要槽,则应从外部启用安全启动 (:ref:`enable-secure-boot-v2-externally`),而不是在启动设备时启用安全启动,这样引导加载程序就无需启用安全启动,从而避免安全隐患。
|
||||
|
||||
保守方法
|
||||
~~~~~~~~~~~~
|
||||
~~~~~~~~
|
||||
|
||||
假设一个受信任的私钥 (N-1) 受到威胁,需要升级到新的密钥对 (N)。
|
||||
|
||||
@@ -652,7 +652,7 @@ bootloader 大小
|
||||
.. _secure-boot-v2-aggressive-key-revocation:
|
||||
|
||||
激进方法
|
||||
~~~~~~~~~~~~~~
|
||||
~~~~~~~~
|
||||
|
||||
ROM 代码具备一项额外功能,即在签名验证失败时可以撤销公钥摘要。
|
||||
|
||||
@@ -666,49 +666,49 @@ bootloader 大小
|
||||
.. _secure-boot-v2-technical-details:
|
||||
|
||||
技术细节
|
||||
-----------------
|
||||
--------
|
||||
|
||||
以下章节包含安全启动元件的详细参考描述。
|
||||
以下章节包含对各安全启动要素的详细参考描述。
|
||||
|
||||
安全启动已集成到 ESP-IDF 构建系统中,因此 ``idf.py build`` 将进行应用程序镜像签名。启用 :ref:`CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES` 后,``idf.py bootloader`` 将生成一个已签名的引导加载程序。
|
||||
|
||||
另外,也可以使用 ``idf.py`` 或 ``openssl`` 工具生成独立签名并进行验证。建议使用 ``idf.py``,但如果需在非 ESP-IDF 环境中生成或验证签名,也可以使用 ``openssl`` 命令,因为安全引导 v2 生成签名符合标准的签名算法。
|
||||
当然,也可以使用 ``idf.py`` 或 ``openssl`` 工具生成独立的签名并对其进行验证。推荐使用 ``idf.py``,但如果需要在非 ESP-IDF 环境中生成或验证签名,也可以使用 ``openssl`` 命令,安全启动 v2 的签名生成符合标准签名算法。
|
||||
|
||||
用 ``idf.py`` 生成和验证签名
|
||||
使用 ``idf.py`` 生成并验证签名
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
1. 二进制镜像签名:
|
||||
|
||||
.. code-block::
|
||||
|
||||
idf.py secure-sign-data --keyfile ./my_signing_key.pem --output ./image_signed.bin image-unsigned.bin
|
||||
idf.py secure-sign-data --keyfile ./my_signing_key.pem --output ./image_signed.bin image-unsigned.bin
|
||||
|
||||
Keyfile 是包含 {IDF_TARGET_SBV2_KEY} 签名私钥的 PEM 文件。
|
||||
|
||||
2. 验证签名的二进制镜像:
|
||||
2. 验证二进制镜像签名:
|
||||
|
||||
.. code-block::
|
||||
.. code-block::
|
||||
|
||||
idf.py secure-verify-signature --keyfile ./my_signing_key.pem image_signed.bin
|
||||
|
||||
Keyfile 是包含 {IDF_TARGET_SBV2_KEY} 公钥/私钥签名的 PEM 文件。
|
||||
Keyfile 是包含 {IDF_TARGET_SBV2_KEY} 签名公钥/私钥的 PEM 文件。
|
||||
|
||||
用 OpenSSL 生成和验证签名
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
使用 OpenSSL 生成并验证签名
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
最好使用 ``idf.py`` 工具生成和验证签名,但如果需要使用 OpenSSL 执行这些操作,可参考以下命令:
|
||||
一般推荐使用 ``idf.py`` 工具来生成并验证签名,如果想通过 OpenSSL 生成并验证签名,请参照下列命令:
|
||||
|
||||
1. 生成需要计算签名的二进制文件镜像的摘要。
|
||||
1. 生成镜像二进制文件的摘要。
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
openssl dgst -sha256 -binary BINARY_FILE > DIGEST_BINARY_FILE
|
||||
|
||||
2. 使用上一步计算出的摘要生成该镜像的签名。
|
||||
2. 使用上述摘要,生成镜像签名。
|
||||
|
||||
.. only:: SOC_SECURE_BOOT_V2_RSA
|
||||
.. only:: SOC_SECURE_BOOT_V2_RSA
|
||||
|
||||
用于生成 RSA-PSS 签名:
|
||||
生成 RSA-PSS 签名:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
@@ -722,7 +722,7 @@ Keyfile 是包含 {IDF_TARGET_SBV2_KEY} 公钥/私钥签名的 PEM 文件。
|
||||
|
||||
.. only:: SOC_SECURE_BOOT_V2_ECC
|
||||
|
||||
用于生成 ECDSA 签名:
|
||||
生成 ECDSA 签名:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
@@ -735,7 +735,7 @@ Keyfile 是包含 {IDF_TARGET_SBV2_KEY} 公钥/私钥签名的 PEM 文件。
|
||||
|
||||
.. only:: SOC_SECURE_BOOT_V2_RSA
|
||||
|
||||
For verifying an RSA-PSS signature:
|
||||
验证 RSA-PSS 签名:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
@@ -749,7 +749,7 @@ Keyfile 是包含 {IDF_TARGET_SBV2_KEY} 公钥/私钥签名的 PEM 文件。
|
||||
|
||||
.. only:: SOC_SECURE_BOOT_V2_ECC
|
||||
|
||||
用于验证 ECDSA 签名:
|
||||
验证 ECDSA 签名:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
@@ -762,7 +762,7 @@ Keyfile 是包含 {IDF_TARGET_SBV2_KEY} 公钥/私钥签名的 PEM 文件。
|
||||
.. _secure-boot-v2-and-flash-encr:
|
||||
|
||||
安全启动 & flash 加密
|
||||
------------------------------
|
||||
---------------------
|
||||
|
||||
如果使用安全启动时没有启用 :doc:`flash-encryption`,可能会发生 ``time-of-check to time-of-use`` 攻击,即在验证并运行镜像后交换 flash 内容。因此,建议同时使用这两个功能。
|
||||
|
||||
@@ -770,7 +770,7 @@ Keyfile 是包含 {IDF_TARGET_SBV2_KEY} 公钥/私钥签名的 PEM 文件。
|
||||
|
||||
.. important::
|
||||
|
||||
{IDF_TARGET_NAME} 只有一个 eFuse 密钥块,用于存储两种密钥:安全启动和 flash 加密,但 eFuse 密钥块只能烧录一次,因此建议同时烧录这两种密钥。注意,``Secure Boot`` 和 ``Flash Encryption`` 无法分别启用,否则后续写入 eFuse 密钥块将返回错误。
|
||||
{IDF_TARGET_NAME} 只有一个 eFuse 密钥块,用于存储两种密钥:安全启动和 flash 加密,但 eFuse 密钥块只能烧录一次,因此建议同时烧录这两种密钥。注意,``Secure Boot`` 和 ``Flash Encryption`` 无法分别启用,否则后续写入 eFuse 密钥块将返回错误。
|
||||
|
||||
|
||||
.. _signed-app-verify-v2:
|
||||
@@ -798,7 +798,7 @@ Keyfile 是包含 {IDF_TARGET_SBV2_KEY} 公钥/私钥签名的 PEM 文件。
|
||||
.. _signed-app-verify-v2-howto:
|
||||
|
||||
启用已签名的应用程序验证
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
1. 打开 :ref:`project-configuration-menu` > ``Security features``。
|
||||
|
||||
@@ -812,7 +812,7 @@ Keyfile 是包含 {IDF_TARGET_SBV2_KEY} 公钥/私钥签名的 PEM 文件。
|
||||
|
||||
.. only:: SOC_SECURE_BOOT_V2_ECC and not SOC_SECURE_BOOT_V2_RSA
|
||||
|
||||
1. 确保 ``App Signing Scheme`` 设置为 ``ECDSA (v2)``。
|
||||
2. 确保 ``App Signing Scheme`` 设置为 ``ECDSA (v2)``。
|
||||
|
||||
.. only:: SOC_SECURE_BOOT_V2_RSA and SOC_SECURE_BOOT_V2_ECC
|
||||
|
||||
@@ -831,11 +831,11 @@ Keyfile 是包含 {IDF_TARGET_SBV2_KEY} 公钥/私钥签名的 PEM 文件。
|
||||
|
||||
|
||||
进阶功能
|
||||
-----------------
|
||||
--------
|
||||
|
||||
JTAG 调试
|
||||
~~~~~~~~~~~~~~
|
||||
~~~~~~~~~
|
||||
|
||||
启用安全启动模式时,eFuse 会默认禁用 JTAG。初次启动时,引导加载程序即禁用 JTAG 调试功能,并启用安全启动模式。
|
||||
启用安全启动模式时,eFuse 会默认禁用 JTAG。初次启动时,引导加载程序禁用 JTAG 调试功能,并启用安全启动模式。
|
||||
|
||||
有关在启用安全启动或已签名应用程序验证的情况下使用 JTAG 调试的更多信息,请参阅 :ref:`jtag-debugging-security-features`。
|
||||
|
Reference in New Issue
Block a user