mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'docs/add_Chinese_translation_for_api-reference/system/mem_alloc' into 'master'
Provided Chinese translation for api-reference/system/mem_alloc.rst Closes DOC-4894 See merge request espressif/esp-idf!23487
This commit is contained in:
commit
0cccbc39a3
@ -1,41 +1,41 @@
|
||||
Heap Memory Allocation
|
||||
======================
|
||||
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
Stack and Heap
|
||||
--------------
|
||||
|
||||
ESP-IDF applications use the common computer architecture patterns of *stack* (dynamic memory allocated by program control flow) and *heap* (dynamic memory allocated by function calls), as well as statically allocated memory (allocated at compile time).
|
||||
ESP-IDF applications use the common computer architecture patterns of **stack** (dynamic memory allocated by program control flow), **heap** (dynamic memory allocated by function calls), and **static memory** (memory allocated at compile time).
|
||||
|
||||
Because ESP-IDF is a multi-threaded RTOS environment, each RTOS task has its own stack. By default, each of these stacks is allocated from the heap when the task is created. (See :cpp:func:`xTaskCreateStatic` for the alternative where stacks are statically allocated.)
|
||||
Because ESP-IDF is a multi-threaded RTOS environment, each RTOS task has its own stack. By default, each of these stacks is allocated from the heap when the task is created. See :cpp:func:`xTaskCreateStatic` for the alternative where stacks are statically allocated.
|
||||
|
||||
Because {IDF_TARGET_NAME} uses multiple types of RAM, it also contains multiple heaps with different capabilities. A capabilities-based memory allocator allows apps to make heap allocations for different purposes.
|
||||
|
||||
For most purposes, the standard libc ``malloc()`` and ``free()`` functions can be used for heap allocation without any special consideration.
|
||||
|
||||
However, in order to fully make use of all of the memory types and their characteristics, ESP-IDF also has a
|
||||
capabilities-based heap memory allocator. If you want to have memory with certain properties (for example, :ref:`dma-capable-memory` or executable-memory), you can create an OR-mask of the required capabilities and pass that to :cpp:func:`heap_caps_malloc`.
|
||||
For most purposes, the C Standard Library's ``malloc()`` and ``free()`` functions can be used for heap allocation without any special consideration. However, in order to fully make use of all of the memory types and their characteristics, ESP-IDF also has a capabilities-based heap memory allocator. If you want to have a memory with certain properties (e.g., :ref:`dma-capable-memory` or executable-memory), you can create an OR-mask of the required capabilities and pass that to :cpp:func:`heap_caps_malloc`.
|
||||
|
||||
Memory Capabilities
|
||||
-------------------
|
||||
|
||||
The {IDF_TARGET_NAME} contains multiple types of RAM:
|
||||
|
||||
- DRAM (Data RAM) is memory used to hold data. This is the most common kind of memory accessed as heap.
|
||||
- IRAM (Instruction RAM) usually holds executable data only. If accessed as generic memory, all accesses must be :ref:`32-bit aligned<32-Bit Accessible Memory>`.
|
||||
- D/IRAM is RAM which can be used as either Instruction or Data RAM.
|
||||
- DRAM (Data RAM) is memory that is connected to CPU's data bus and is used to hold data. This is the most common kind of memory accessed as a heap.
|
||||
- IRAM (Instruction RAM) is memory that is connected to the CPU's instruction bus and usually holds executable data only (i.e., instructions). If accessed as generic memory, all accesses must be aligned to :ref:`32-Bit Accessible Memory <32-Bit Accessible Memory>`.
|
||||
- D/IRAM is RAM that is connected to CPU's data bus and instruction bus, thus can be used either Instruction or Data RAM.
|
||||
|
||||
For more details on these internal memory types, see :ref:`memory-layout`.
|
||||
|
||||
.. only:: SOC_SPIRAM_SUPPORTED
|
||||
|
||||
It's also possible to connect external SPI RAM to the {IDF_TARGET_NAME} - :doc:`external RAM </api-guides/external-ram>` can be integrated into the {IDF_TARGET_NAME}'s memory map using the flash cache, and accessed similarly to DRAM.
|
||||
It's also possible to connect external SPI RAM to the {IDF_TARGET_NAME}. The :doc:`external RAM </api-guides/external-ram>` is integrated into the {IDF_TARGET_NAME}'s memory map via the cache, and accessed similarly to DRAM.
|
||||
|
||||
DRAM uses capability ``MALLOC_CAP_8BIT`` (accessible in single byte reads and writes). To test the free DRAM heap size at runtime, call cpp:func:`heap_caps_get_free_size(MALLOC_CAP_8BIT)`.
|
||||
All DRAM memory is single-byte accessible, thus all DRAM heaps possess the ``MALLOC_CAP_8BIT`` capability. Users can call ``heap_caps_get_free_size(MALLOC_CAP_8BIT)`` to get the free size of all DRAM heaps.
|
||||
|
||||
When calling ``malloc()``, the ESP-IDF ``malloc()`` implementation internally calls cpp:func:`heap_caps_malloc_default(size)`. This will allocate memory with capability ``MALLOC_CAP_DEFAULT``, which is byte-addressable.
|
||||
If ran out of ``MALLOC_CAP_8BIT``, the users can use ``MALLOC_CAP_IRAM_8BIT`` instead. In that case, IRAM can still be used as a "reserve" pool of internal memory if the users only access it in a 32-bit aligned manner, or if they enable ``CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY)``.
|
||||
|
||||
Because ``malloc()`` uses the capabilities-based allocation system, memory allocated using :cpp:func:`heap_caps_malloc` can be freed by calling
|
||||
the standard ``free()`` function.
|
||||
When calling ``malloc()``, the ESP-IDF ``malloc()`` internally calls ``heap_caps_malloc_default(size)``. This will allocate memory with the capability ``MALLOC_CAP_DEFAULT``, which is byte-addressable.
|
||||
|
||||
Because ``malloc()`` uses the capabilities-based allocation system, memory allocated using :cpp:func:`heap_caps_malloc` can be freed by calling the standard ``free()`` function.
|
||||
|
||||
Available Heap
|
||||
--------------
|
||||
@ -45,7 +45,7 @@ Available Heap
|
||||
DRAM
|
||||
^^^^
|
||||
|
||||
At startup, the DRAM heap contains all data memory which is not statically allocated by the app. Reducing statically allocated buffers will increase the amount of available free heap.
|
||||
At startup, the DRAM heap contains all data memory that is not statically allocated by the app. Reducing statically allocated buffers will increase the amount of available free heap.
|
||||
|
||||
To find the amount of statically allocated memory, use the :ref:`idf.py size <idf.py-size>` command.
|
||||
|
||||
@ -53,12 +53,12 @@ To find the amount of statically allocated memory, use the :ref:`idf.py size <id
|
||||
|
||||
.. note:: See the :ref:`dram` section for more details about the DRAM usage limitations.
|
||||
|
||||
.. note:: At runtime, the available heap DRAM may be less than calculated at compile time, because at startup some memory is allocated from the heap before the FreeRTOS scheduler is started (including memory for the stacks of initial FreeRTOS tasks).
|
||||
.. note:: At runtime, the available heap DRAM may be less than calculated at compile time, because, at startup, some memory is allocated from the heap before the FreeRTOS scheduler is started (including memory for the stacks of initial FreeRTOS tasks).
|
||||
|
||||
IRAM
|
||||
^^^^
|
||||
|
||||
At startup, the IRAM heap contains all instruction memory which is not used by the app executable code.
|
||||
At startup, the IRAM heap contains all instruction memory that is not used by the app executable code.
|
||||
|
||||
The :ref:`idf.py size <idf.py-size>` command can be used to find the amount of IRAM used by the app.
|
||||
|
||||
@ -81,7 +81,7 @@ At startup, all ESP-IDF apps log a summary of all heap addresses (and sizes) at
|
||||
I (278) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
|
||||
I (284) heap_init: At 4008944C len 00016BB4 (90 KiB): IRAM
|
||||
|
||||
Finding available heap
|
||||
Finding Available Heap
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
See :ref:`heap-information`.
|
||||
@ -105,11 +105,11 @@ Use the ``MALLOC_CAP_DMA`` flag to allocate memory which is suitable for use wit
|
||||
32-Bit Accessible Memory
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If a certain memory structure is only addressed in 32-bit units, for example an array of ints or pointers, it can be useful to allocate it with the ``MALLOC_CAP_32BIT`` flag. This also allows the allocator to give out IRAM memory; something which it can't do for a normal malloc() call. This can help to use all the available memory in the {IDF_TARGET_NAME}.
|
||||
If a certain memory structure is only addressed in 32-bit units, for example, an array of ints or pointers, it can be useful to allocate it with the ``MALLOC_CAP_32BIT`` flag. This also allows the allocator to give out IRAM memory, which is sometimes unavailable for a normal malloc() call. This can help to use all the available memory in the {IDF_TARGET_NAME}.
|
||||
|
||||
.. only:: CONFIG_IDF_TARGET_ARCH_XTENSA and SOC_CPU_HAS_FPU
|
||||
|
||||
Please note that on {IDF_TARGET_NAME} series chips, ``MALLOC_CAP_32BIT`` cannot be used for storing floating-point variables. This is because ``MALLOC_CAP_32BIT`` may return instruction RAM, and the floating-point assembly instructions on {IDF_TARGET_NAME} cannot access instruction RAM.
|
||||
Please note that on {IDF_TARGET_NAME} series chips, ``MALLOC_CAP_32BIT`` cannot be used for storing floating-point variables. This is because ``MALLOC_CAP_32BIT`` may return instruction RAM and the floating-point assembly instructions on {IDF_TARGET_NAME} cannot access instruction RAM.
|
||||
|
||||
Memory allocated with ``MALLOC_CAP_32BIT`` can *only* be accessed via 32-bit reads and writes, any other type of access will generate a fatal LoadStoreError exception.
|
||||
|
||||
@ -118,25 +118,25 @@ Memory allocated with ``MALLOC_CAP_32BIT`` can *only* be accessed via 32-bit rea
|
||||
External SPI Memory
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When :doc:`external RAM </api-guides/external-ram>` is enabled, external SPI RAM under 4MiB in size can be allocated using standard ``malloc`` calls, or via ``heap_caps_malloc(MALLOC_CAP_SPIRAM)``, depending on configuration. See :ref:`external_ram_config` for more details.
|
||||
When :doc:`external RAM </api-guides/external-ram>` is enabled, external SPI RAM under 4 MiB in size can be allocated using standard ``malloc`` calls, or via ``heap_caps_malloc(MALLOC_CAP_SPIRAM)``, depending on the configuration. See :ref:`external_ram_config` for more details.
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
To use the region above the 4MiB limit, you can use the :doc:`himem API</api-reference/system/himem>`.
|
||||
To use the region above the 4 MiB limit, you can use the :doc:`himem API</api-reference/system/himem>`.
|
||||
|
||||
Thread Safety
|
||||
-------------
|
||||
|
||||
Heap functions are thread safe, meaning they can be called from different tasks simultaneously without any limitations.
|
||||
Heap functions are thread-safe, meaning they can be called from different tasks simultaneously without any limitations.
|
||||
|
||||
It is technically possible to call ``malloc``, ``free``, and related functions from interrupt handler (ISR) context (see :ref:`calling-heap-related-functions-from-isr`). However this is not recommended, as heap function calls may delay other interrupts. It is strongly recommended to refactor applications so that any buffers used by an ISR are pre-allocated outside of the ISR. Support for calling heap functions from ISRs may be removed in a future update.
|
||||
It is technically possible to call ``malloc``, ``free``, and related functions from interrupt handler (ISR) context (see :ref:`calling-heap-related-functions-from-isr`). However, this is not recommended, as heap function calls may delay other interrupts. It is strongly recommended to refactor applications so that any buffers used by an ISR are pre-allocated outside of the ISR. Support for calling heap functions from ISRs may be removed in a future update.
|
||||
|
||||
.. _calling-heap-related-functions-from-isr:
|
||||
|
||||
Calling heap related functions from ISR
|
||||
Calling Heap-Related Functions from ISR
|
||||
---------------------------------------
|
||||
|
||||
The following functions from the heap component can be called form interrupt handler (ISR):
|
||||
The following functions from the heap component can be called from the interrupt handler (ISR):
|
||||
|
||||
* :cpp:func:`heap_caps_malloc`
|
||||
* :cpp:func:`heap_caps_malloc_default`
|
||||
@ -150,7 +150,7 @@ The following functions from the heap component can be called form interrupt han
|
||||
* :cpp:func:`heap_caps_aligned_alloc`
|
||||
* :cpp:func:`heap_caps_aligned_free`
|
||||
|
||||
Note however this practice is strongly discouraged.
|
||||
Note: however, this practice is strongly discouraged.
|
||||
|
||||
Heap Tracing & Debugging
|
||||
------------------------
|
||||
@ -158,20 +158,20 @@ Heap Tracing & Debugging
|
||||
The following features are documented on the :doc:`Heap Memory Debugging </api-reference/system/heap_debug>` page:
|
||||
|
||||
- :ref:`Heap Information <heap-information>` (free space, etc.)
|
||||
- :ref:`Heap allocation and free function hooks <heap-allocation-free>`
|
||||
- :ref:`Heap Allocation and Free Function Hooks <heap-allocation-free>`
|
||||
- :ref:`Heap Corruption Detection <heap-corruption>`
|
||||
- :ref:`Heap Tracing <heap-tracing>` (memory leak detection, monitoring, etc.)
|
||||
|
||||
Implementation Notes
|
||||
--------------------
|
||||
|
||||
Knowledge about the regions of memory in the chip comes from the "soc" component, which contains memory layout information for the chip, and the different capabilities of each region. Each region's capabilities are prioritised, so that (for example) dedicated DRAM and IRAM regions will be used for allocations ahead of the more versatile D/IRAM regions.
|
||||
Knowledge about the regions of memory in the chip comes from the "SoC" component, which contains memory layout information for the chip, and the different capabilities of each region. Each region's capabilities are prioritized, so that (for example) dedicated DRAM and IRAM regions will be used for allocations ahead of the more versatile D/IRAM regions.
|
||||
|
||||
Each contiguous region of memory contains its own memory heap. The heaps are created using the :ref:`multi_heap <multi-heap>` functionality. multi_heap allows any contiguous region of memory to be used as a heap.
|
||||
Each contiguous region of memory contains its own memory heap. The heaps are created using the :ref:`multi_heap <multi-heap>` functionality. ``multi_heap`` allows any contiguous region of memory to be used as a heap.
|
||||
|
||||
The heap capabilities allocator uses knowledge of the memory regions to initialize each individual heap. Allocation functions in the heap capabilities API will find the most appropriate heap for the allocation (based on desired capabilities, available space, and preferences for each region's use) and then calling :cpp:func:`multi_heap_malloc` for the heap situated in that particular region.
|
||||
The heap capabilities allocator uses knowledge of the memory regions to initialize each individual heap. Allocation functions in the heap capabilities API will find the most appropriate heap for the allocation based on desired capabilities, available space, and preferences for each region's use, and then calling :cpp:func:`multi_heap_malloc` for the heap situated in that particular region.
|
||||
|
||||
Calling ``free()`` involves finding the particular heap corresponding to the freed address, and then calling :cpp:func:`multi_heap_free` on that particular multi_heap instance.
|
||||
Calling ``free()`` involves finding the particular heap corresponding to the freed address, and then call :cpp:func:`multi_heap_free` on that particular ``multi_heap`` instance.
|
||||
|
||||
|
||||
API Reference - Heap Allocation
|
||||
@ -187,9 +187,9 @@ API Reference - Initialisation
|
||||
|
||||
.. _multi-heap:
|
||||
|
||||
API Reference - Multi Heap API
|
||||
API Reference - Multi-Heap API
|
||||
------------------------------
|
||||
|
||||
(Note: The multi heap API is used internally by the heap capabilities allocator. Most IDF programs will never need to call this API directly.)
|
||||
(Note: The multi-heap API is used internally by the heap capabilities allocator. Most IDF programs will never need to call this API directly.)
|
||||
|
||||
.. include-build-file:: inc/multi_heap.inc
|
||||
|
@ -1 +1,195 @@
|
||||
.. include:: ../../../en/api-reference/system/mem_alloc.rst
|
||||
堆内存分配
|
||||
======================
|
||||
|
||||
:link_to_translation:`en:[English]`
|
||||
|
||||
栈 (stack) 和堆 (heap) 的区别
|
||||
----------------------------------------
|
||||
|
||||
ESP-IDF 应用程序使用常见的计算机架构模式:由程序控制流动态分配的内存(即 **栈**)、由函数调用动态分配的内存(即 **堆**)以及在编译时分配的 **静态内存**。
|
||||
|
||||
由于 ESP-IDF 是一个多线程 RTOS 环境,因此每个 RTOS 任务都有自己的栈,这些栈默认在创建任务时从堆中分配。有关栈静态分配的方法,请参阅 :cpp:func:`xTaskCreateStatic`。
|
||||
|
||||
{IDF_TARGET_NAME} 使用多种类型的 RAM,因此具备不同属性的堆,即基于属性的内存分配器允许应用程序按不同目的进行堆分配。
|
||||
|
||||
多数情况下,可直接使用 C 标准函数库中的 ``malloc()`` 和 ``free()`` 函数实现堆分配。为充分利用各种内存类型及其特性,ESP-IDF 还具有基于内存属性的堆内存分配器。要配备具有特定属性的内存,如 :ref:`dma-capable-memory` 或可执行内存,可以创建具备所需属性的 OR 掩码,将其传递给 :cpp:func:`heap_caps_malloc`。
|
||||
|
||||
内存属性
|
||||
-------------------
|
||||
|
||||
{IDF_TARGET_NAME} 包含多种类型的 RAM:
|
||||
|
||||
- DRAM(数据 RAM)是连接到 CPU 数据总线上的内存,用于存储数据。这是作为堆访问最常见的一种内存。
|
||||
- IRAM(指令 RAM)是连接到 CPU 指令总线上的内存,通常仅用于存储可执行数据(即指令)。如果作为通用内存访问,则所有访问必须为 :ref:`32 位可访问内存 <32-Bit Accessible Memory>`。
|
||||
- D/IRAM 是连接到 CPU 数据总线和指令总线的 RAM,因此可用作指令 RAM 或数据 RAM。
|
||||
|
||||
有关内存类型的详细信息,请参阅 :ref:`memory-layout`。
|
||||
|
||||
.. only:: SOC_SPIRAM_SUPPORTED
|
||||
|
||||
也可将外部 SPI RAM 连接到 {IDF_TARGET_NAME}。通过缓存将 :doc:`片外 RAM </api-guides/external-ram>` 集成到 {IDF_TARGET_NAME} 的内存映射中,访问方式与 DRAM 类似。
|
||||
|
||||
所有的 DRAM 内存都可以单字节访问,因此所有的 DRAM 堆都具有 ``MALLOC_CAP_8BIT`` 属性。要获取所有 DRAM 堆的剩余空间大小,请调用 ``heap_caps_get_free_size(MALLOC_CAP_8BIT)``。
|
||||
|
||||
如果占用了所有的 ``MALLOC_CAP_8BIT`` 堆空间,则可以用 ``MALLOC_CAP_IRAM_8BIT`` 代替。此时,若只以 32 位对齐的方式访问 IRAM 内存,或者启用了 ``CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY``,则仍然可以将 IRAM 用作内部内存的“储备池”。
|
||||
|
||||
调用 ``malloc()`` 时,ESP-IDF ``malloc()`` 内部调用 ``heap_caps_malloc_default(size)``,使用属性 ``MALLOC_CAP_DEFAULT`` 分配内存。该属性可实现字节寻址功能,即存储空间的最小编址单位为字节。
|
||||
|
||||
``malloc()`` 使用基于属性的分配系统,所以使用 :cpp:func:`heap_caps_malloc` 分配的内存可以通过调用标准的 ``free()`` 函数释放。
|
||||
|
||||
可用堆空间
|
||||
-------------------
|
||||
|
||||
.. _dram-definition:
|
||||
|
||||
DRAM
|
||||
^^^^
|
||||
|
||||
启动时,DRAM 堆包含应用程序未静态分配的所有数据内存,减少静态分配的缓冲区将增加可用的空闲堆空间。
|
||||
|
||||
调用命令 :ref:`idf.py size <idf.py-size>` 可查找静态分配内存大小。
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
.. note:: 有关 DRAM 使用限制的详细信息,请参阅 :ref:`dram` 。
|
||||
|
||||
.. note:: 运行时可用的 DRAM 堆空间可能少于编译时计算的大小,因为启动时会在运行 FreeRTOS 调度程序之前从堆中分配部分内存,包括初始 FreeRTOS 任务的栈内存。
|
||||
|
||||
IRAM
|
||||
^^^^
|
||||
|
||||
启动时,IRAM 堆包含所有应用程序可执行代码未使用的指令内存。
|
||||
|
||||
调用命令 :ref:`idf.py size <idf.py-size>` 查找应用程序使用的 IRAM 量。
|
||||
|
||||
D/IRAM
|
||||
^^^^^^
|
||||
|
||||
一些内存在 {IDF_TARGET_NAME} 中可用作 DRAM 或 IRAM。如果从 D/IRAM 区域分配内存,则两种类型的内存的可用堆空间都会减少。
|
||||
|
||||
堆空间大小
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
启动时,所有 ESP-IDF 应用程序都会记录全部堆地址(和空间大小)的摘要,级别为 Info:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
I (252) heap_init: Initializing. RAM available for dynamic allocation:
|
||||
I (259) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
|
||||
I (265) heap_init: At 3FFB2EC8 len 0002D138 (180 KiB): DRAM
|
||||
I (272) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
|
||||
I (278) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
|
||||
I (284) heap_init: At 4008944C len 00016BB4 (90 KiB): IRAM
|
||||
|
||||
查找可用堆
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
请参阅 :ref:`heap-information`。
|
||||
|
||||
特殊用途
|
||||
--------------------
|
||||
|
||||
.. _dma-capable-memory:
|
||||
|
||||
DMA 存储器
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
使用 ``MALLOC_CAP_DMA`` 标志分配适合与硬件 DMA 引擎(如 SPI 和 I2S)配合使用的内存,此属性标志不包括外部 PSRAM。
|
||||
|
||||
.. only SOC_SPIRAM_SUPPORTED and not esp32::
|
||||
|
||||
EDMA 硬件功能允许将 DMA 缓冲区放置在外部 PSRAM,但可能存在其他对齐限制,详情请参阅 {IDF_TARGET_NAME} 技术参考手册。要分配一个可用 DMA 的外部内存缓冲区,请使用 ``MALLOC_CAP_SPIRAM`` 属性标志 和 :cpp:func:`heap_caps_aligned_alloc`,并指定必要的对齐方式。
|
||||
|
||||
.. _32-bit accessible memory:
|
||||
|
||||
32 位可访问内存
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
如果某个内存结构体仅以 32 位为单位寻址,例如一个整数或指针数组,则可以使用 ``MALLOC_CAP_32BIT`` 标志分配。通过这一方式,分配器能够在无法调用 malloc() 的情况下提供 IRAM 内存,从而充分利用 {IDF_TARGET_NAME} 中的所有可用内存。
|
||||
|
||||
.. only:: CONFIG_IDF_TARGET_ARCH_XTENSA and SOC_CPU_HAS_FPU
|
||||
|
||||
请注意,在 {IDF_TARGET_NAME} 系列芯片上,不可使用 ``MALLOC_CAP_32BIT`` 存储浮点变量。因为 ``MALLOC_CAP_32BIT`` 可能返回指令 RAM,而 {IDF_TARGET_NAME} 上的浮点汇编指令无法访问指令 RAM。
|
||||
|
||||
请注意,使用 ``MALLOC_CAP_32BIT`` 分配的内存 *只能* 通过 32 位读写访问,其他类型的访问将导致 LoadStoreError 异常。
|
||||
|
||||
.. only:: SOC_SPIRAM_SUPPORTED
|
||||
|
||||
外部 SPI 内存
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
当启用 :doc:`片外 RAM </api-guides/external-ram>` 时,可以根据配置调用标准 ``malloc`` 或通过 ``heap_caps_malloc(MALLOC_CAP_SPIRAM)`` 分配小于 4 MiB 的外部 SPI RAM,详情请参阅 :ref:`external_ram_config`。
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
要使用超过 4 MiB 限制的区域,可以使用 :doc:`himem API</api-reference/system/himem>`。
|
||||
|
||||
线程安全性
|
||||
-------------
|
||||
|
||||
堆函数是线程安全的,因此可不受限制,在不同任务中同时调用多个堆函数。
|
||||
|
||||
从中断处理程序 (ISR) 上下文中调用 ``malloc``、 ``free`` 和相关函数虽然在技术层面可行(请参阅 :ref:`calling-heap-related-functions-from-isr`),但不建议使用此种方法,因为调用堆函数可能会延迟其他中断。建议重构应用程序,将 ISR 使用的任何缓冲区预先分配到 ISR 之外。之后可能会删除从 ISR 调用堆函数的功能。
|
||||
|
||||
.. _calling-heap-related-functions-from-isr:
|
||||
|
||||
从 ISR 调用堆相关函数
|
||||
---------------------------------------
|
||||
|
||||
堆组件中的以下函数可以在中断处理程序 (ISR) 中调用:
|
||||
|
||||
* :cpp:func:`heap_caps_malloc`
|
||||
* :cpp:func:`heap_caps_malloc_default`
|
||||
* :cpp:func:`heap_caps_realloc_default`
|
||||
* :cpp:func:`heap_caps_malloc_prefer`
|
||||
* :cpp:func:`heap_caps_realloc_prefer`
|
||||
* :cpp:func:`heap_caps_calloc_prefer`
|
||||
* :cpp:func:`heap_caps_free`
|
||||
* :cpp:func:`heap_caps_realloc`
|
||||
* :cpp:func:`heap_caps_calloc`
|
||||
* :cpp:func:`heap_caps_aligned_alloc`
|
||||
* :cpp:func:`heap_caps_aligned_free`
|
||||
|
||||
请注意,不建议使用此种方法。
|
||||
|
||||
堆跟踪及调试
|
||||
------------------------
|
||||
|
||||
以下功能介绍详见 :doc:`堆内存调试 </api-reference/system/heap_debug>`:
|
||||
|
||||
- :ref:`堆信息 <heap-information>` (释放内存空间等)
|
||||
- :ref:`堆分配与释放函数挂钩 <heap-allocation-free>`
|
||||
- :ref:`堆损坏检测 <heap-corruption>`
|
||||
- :ref:`堆跟踪 <heap-tracing>` (检测、监控内存泄漏等)
|
||||
|
||||
实现说明
|
||||
--------------------
|
||||
|
||||
堆属性分配器对芯片内存区域的了解源于 SoC 组件,该组件包含芯片的内存布局信息以及每个区域的不同属性。各区域的功能为首要考虑因素,如会优先使用 DRAM 和 IRAM 特定区域而非用途更广的 D/IRAM 区域来分配内存。
|
||||
|
||||
每个连续的内存区域都包含其自己的内存堆,由 :ref:`multi_heap <multi-heap>` 函数创建。 ``multi_heap`` 允许将任何连续的内存区域作为堆使用。
|
||||
|
||||
堆属性分配器通过对内存区域的了解初始化每个单独的堆,堆属性 API 中的分配函数将基于所需的属性、可用空间和每个区域使用的首选项为分配函数找到最合适的堆,随后为位于特定内存区域的堆调用 :cpp:func:`multi_heap_malloc`。
|
||||
|
||||
调用 ``free()`` 查找对应释放地址的特定堆,随后在特定的 ``multi_heap`` 实例上调用 :cpp:func:`multi_heap_free`。
|
||||
|
||||
|
||||
API 参考 - 堆分配
|
||||
-------------------------------
|
||||
|
||||
.. include-build-file:: inc/esp_heap_caps.inc
|
||||
|
||||
|
||||
API 参考 - 初始化
|
||||
------------------------------
|
||||
|
||||
.. include-build-file:: inc/esp_heap_caps_init.inc
|
||||
|
||||
.. _multi-heap:
|
||||
|
||||
API 参考 - 多堆 API
|
||||
------------------------------
|
||||
|
||||
(注意:堆属性分配器在内部使用多堆 API,而多数 IDF 程序不需要直接调用此 API。)
|
||||
|
||||
.. include-build-file:: inc/multi_heap.inc
|
||||
|
Loading…
Reference in New Issue
Block a user