mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
docs: Update the CN Translation for ram-usage.rst
This commit is contained in:
parent
e1946b6446
commit
a55e6c0eb6
@ -60,7 +60,7 @@ Configuration Options for Stack Overflow Detection
|
||||
Hardware Stack Guard
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The Hardware Stack Guard is a reliable method for detecting stack overflow. This method uses the hardware's assist-debug module to monitor the CPU's stack pointer register. A panic is immediately triggered if the stack pointer register goes beyond the bounds of the current stack (see :ref:`Hardware-Stack-Guard` for more details). The Hardware Stack Guard can be enabled via the :ref:`CONFIG_ESP_SYSTEM_HW_STACK_GUARD` option.
|
||||
The Hardware Stack Guard is a reliable method for detecting stack overflow. This method uses the hardware's Debug Assistant module to monitor the CPU's stack pointer register. A panic is immediately triggered if the stack pointer register goes beyond the bounds of the current stack (see :ref:`Hardware-Stack-Guard` for more details). The Hardware Stack Guard can be enabled via the :ref:`CONFIG_ESP_SYSTEM_HW_STACK_GUARD` option.
|
||||
|
||||
End of Stack Watchpoint
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@ -72,18 +72,13 @@ Stack Canary Bytes
|
||||
|
||||
The Stack Canary Bytes feature adds a set of magic bytes at the end of each task's stack, and checks if those magic bytes have changed on every context switch. If those magic bytes are overwritten, a panic is triggered. Stack Canary Bytes can be enabled via the :ref:`CONFIG_FREERTOS_CHECK_STACKOVERFLOW` option.
|
||||
|
||||
FreeRTOS Check Stack Overflow
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
There is a less effective alternative, see :ref:`CONFIG_FREERTOS_CHECK_STACKOVERFLOW` docs for details.
|
||||
|
||||
.. note::
|
||||
|
||||
When using the End of Stack Watchpoint or Stack Canary Bytes, it is possible that a stack pointer skips over the watchpoint or canary bytes on a stack overflow and corrupts another region of RAM instead. Thus, these methods cannot detect all stack overflows.
|
||||
|
||||
.. only:: SOC_ASSIST_DEBUG_SUPPORTED
|
||||
|
||||
Recomended and default option is :ref:`CONFIG_ESP_SYSTEM_HW_STACK_GUARD` which avoids this disadvantage.
|
||||
Recommended and default option is :ref:`CONFIG_ESP_SYSTEM_HW_STACK_GUARD` which avoids this disadvantage.
|
||||
|
||||
Run-time Methods to Determine Stack Size
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -45,24 +45,54 @@ ESP-IDF 包含一系列堆 API,可以在运行时测量空闲堆内存,请
|
||||
|
||||
.. _optimize-stack-sizes:
|
||||
|
||||
栈内存大小优化
|
||||
确定栈内存大小
|
||||
--------------------
|
||||
|
||||
在 FreeRTOS 操作系统中,任务栈通常从堆中分配。每个任务的栈大小固定,且会作为参数传递给 :cpp:func:`xTaskCreate`。每个任务可用的栈内存不得超过为其分配的栈内存大小,否则将导致栈内存溢出或堆内存损坏,使原本可用的程序崩溃。
|
||||
|
||||
因此,确定每个任务栈内存的最佳大小、最小化每个任务栈内存大小、以及最小化任务栈内存的整体数量,都可以大幅减少 RAM 的使用。
|
||||
|
||||
要确定特定任务栈内存的最佳大小,请执行以下操作:
|
||||
栈溢出检测的配置选项
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- 程序运行时,如你认为某任务有未使用的栈内存,可通过其任务句柄调用 :cpp:func:`uxTaskGetStackHighWaterMark`。该函数将以字节为单位,返回任务中生命周期最短的空闲栈内存。
|
||||
.. only:: SOC_ASSIST_DEBUG_SUPPORTED
|
||||
|
||||
硬件栈保护
|
||||
~~~~~~~~~~~~
|
||||
|
||||
硬件栈保护是一种检测栈溢出的可靠方法,通过硬件的辅助调试模块来监视 CPU 的栈指针寄存器。如果栈指针寄存器超出了当前栈的边界,则立即触发紧急情况提示(更多详细信息,请参阅 :ref:`Hardware-Stack-Guard`)。可以通过 :ref:`CONFIG_ESP_SYSTEM_HW_STACK_GUARD` 选项启用硬件栈保护。
|
||||
|
||||
栈末尾监视点
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
栈末尾监视点将 CPU 监视点放置在当前栈的末尾。如果该字被覆盖(例如栈溢出),则会立即触发紧急情况提示。在未使用调试器的监视点时,可以设置 :ref:`CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK` 选项,启用栈末尾监视点功能。
|
||||
|
||||
栈金丝雀字节
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
栈金丝雀字节功能在每个任务的栈末尾添加一组魔术字节,并在每次上下文切换时检查这些字节是否已更改。如果这些魔术字节被覆盖,则会触发紧急情况提示。可以通过 :ref:`CONFIG_FREERTOS_CHECK_STACKOVERFLOW` 选项启用栈金丝雀字节功能。
|
||||
|
||||
.. note::
|
||||
|
||||
使用栈末尾监视点或栈金丝雀字节时,栈指针可能在栈溢出时跳过监视点或金丝雀字节,损坏 RAM 的其他区域。因此,上述方法并不能检测所有的栈溢出。
|
||||
|
||||
.. only:: SOC_ASSIST_DEBUG_SUPPORTED
|
||||
|
||||
推荐启用默认选项 :ref:`CONFIG_ESP_SYSTEM_HW_STACK_GUARD`,避免这个缺点。
|
||||
|
||||
任务运行时确定栈内存大小的方法
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- 调用 :cpp:func:`uxTaskGetStackHighWaterMark` 会返回任务整个生命周期中空闲栈内存的最小值,从而较好地显示出任务未使用的栈内存量。
|
||||
|
||||
- 从任务本身内部调用 :cpp:func:`uxTaskGetStackHighWaterMark` 是调用该函数最容易的方式:在任务达到其栈内存使用峰值后,调用 ``uxTaskGetStackHighWaterMark(NULL)`` 获取当前任务的高水位标记,换言之,如果有主循环,请多次执行主循环来覆盖各种状态,随后调用 :cpp:func:`uxTaskGetStackHighWaterMark`。
|
||||
- 通常可以用任务的栈内存总大小减去调用 :cpp:func:`uxTaskGetStackHighWaterMark` 的返回值,计算任务实际使用的栈内存大小,但应留出一定的安全余量,应对运行时栈内存使用量的小幅意外增长。
|
||||
|
||||
- 程序运行时,调用 :cpp:func:`uxTaskGetSystemState` 获取系统中所有任务的摘要,包括各栈内存的高水位标记值。
|
||||
- 在未使用调试器的监视点时,可以设置 :ref:`CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK` 选项。启用此选项时,系统会使用一个观察点,监视每个任务栈的最后一个字节。如果有新的数据覆盖了该字节(例如发生栈溢出),将立即触发 panic。相比默认 :ref:`CONFIG_FREERTOS_CHECK_STACKOVERFLOW` 选项的 ``Check using canary bytes``,这种方式更可靠,因其能够立即触发 panic,而不是在下一次 RTOS 上下文切换时触发。然而,两种选项都存在缺点,有时栈指针可能会跳过监视点或 canary 字节,损坏 RAM 的其他区域。
|
||||
- 调用 :cpp:func:`uxTaskGetSystemState` 来获取系统中所有任务的摘要,包括各栈内存的高水位标记值。
|
||||
|
||||
要减少特定任务栈内存大小,请执行以下操作:
|
||||
|
||||
减少栈内存大小
|
||||
--------------
|
||||
|
||||
- 避免占用过多栈内存的函数。字符串格式化函数(如 ``printf()``)会使用大量栈内存,如果任务不调用这类函数,通常可以减小其占用的栈内存。
|
||||
|
||||
@ -71,12 +101,13 @@ ESP-IDF 包含一系列堆 API,可以在运行时测量空闲堆内存,请
|
||||
- 避免在栈上分配大型变量。在 C 语言声明的默认作用域中,任何分配为自动变量的大型结构体或数组都会占用栈内存。要优化这些变量占用的栈内存大小,可以使用静态分配,或仅在需要时从堆中动态分配。
|
||||
- 避免调用深度递归函数。尽管调用单个递归函数并不一定会占用大量栈内存,但若每个函数都包含大量基于栈的变量,那么调用这些函数的开销将会很高。
|
||||
|
||||
要减少任务的整体数量,请执行以下操作:
|
||||
减少任务数量
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- 合并任务。如果从未创建某个特定任务,就不会分配该任务的栈内存,从而极大减少 RAM 使用。如果某些任务可以与另一个任务合并,通常可以将不必要的任务删除。在应用程序中,如果满足以下条件,通常可以合并或删除任务:
|
||||
合并任务。如果从未创建某个特定任务,就不会分配该任务的栈内存,从而极大减少 RAM 使用。如果某些任务可以与另一个任务合并,通常可以将不必要的任务删除。在应用程序中,如果满足以下条件,通常可以合并或删除任务:
|
||||
|
||||
- 任务所执行的内容可以按顺序分解为多个函数调用。
|
||||
- 任务所执行的内容可以分解为较小的工作,这些工作可以通过 FreeRTOS 队列或类似机制串行化,并由工作任务执行。
|
||||
- 任务所执行的内容可以按顺序分解为多个函数调用。
|
||||
- 任务所执行的内容可以分解为较小的工作,这些工作可以通过 FreeRTOS 队列或类似机制串行化,并由工作任务执行。
|
||||
|
||||
内部任务栈内存大小
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
Loading…
Reference in New Issue
Block a user