mem_alloc.rst 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. Heap Memory Allocation
  2. ======================
  3. Stack and Heap
  4. --------------
  5. 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).
  6. 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.)
  7. 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.
  8. For most purposes, the standard libc ``malloc()`` and ``free()`` functions can be used for heap allocation without any special consideration.
  9. However, in order to fully make use of all of the memory types and their characteristics, ESP-IDF also has a
  10. 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`.
  11. Memory Capabilities
  12. -------------------
  13. The {IDF_TARGET_NAME} contains multiple types of RAM:
  14. - DRAM (Data RAM) is memory used to hold data. This is the most common kind of memory accessed as heap.
  15. - 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>`.
  16. - D/IRAM is RAM which can be used as either Instruction or Data RAM.
  17. For more details on these internal memory types, see :ref:`memory-layout`.
  18. .. only:: SOC_SPIRAM_SUPPORTED
  19. 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.
  20. DRAM uses capability ``MALLOC_CAP_8BIT`` (accessible in single byte reads and writes). When calling ``malloc()``, the ESP-IDF ``malloc()`` implementation internally calls ``heap_caps_malloc(size, MALLOC_CAP_8BIT)`` in order to allocate DRAM that is byte-addressable. To test the free DRAM heap size at runtime, call cpp:func:`heap_caps_get_free_size(MALLOC_CAP_8BIT)`.
  21. Because malloc uses the capabilities-based allocation system, memory allocated using :cpp:func:`heap_caps_malloc` can be freed by calling
  22. the standard ``free()`` function.
  23. Available Heap
  24. --------------
  25. DRAM
  26. ^^^^
  27. 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.
  28. To find the amount of statically allocated memory, use the :ref:`idf.py size <idf.py-size>` command.
  29. .. only:: esp32
  30. .. note:: Due to a technical limitation, the maximum statically allocated DRAM usage is 160KB. The remaining 160KB (for a total of 320KB of DRAM) can only be allocated at runtime as heap.
  31. .. 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).
  32. IRAM
  33. ^^^^
  34. At startup, the IRAM heap contains all instruction memory which is not used by the app executable code.
  35. The :ref:`idf.py size <idf.py-size>` command can be used to find the amount of IRAM used by the app.
  36. D/IRAM
  37. ^^^^^^
  38. Some memory in the {IDF_TARGET_NAME} is available as either DRAM or IRAM. If memory is allocated from a D/IRAM region, the free heap size for both types of memory will decrease.
  39. Heap Sizes
  40. ^^^^^^^^^^
  41. At startup, all ESP-IDF apps log a summary of all heap addresses (and sizes) at level Info:
  42. .. code-block:: none
  43. I (252) heap_init: Initializing. RAM available for dynamic allocation:
  44. I (259) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
  45. I (265) heap_init: At 3FFB2EC8 len 0002D138 (180 KiB): DRAM
  46. I (272) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
  47. I (278) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
  48. I (284) heap_init: At 4008944C len 00016BB4 (90 KiB): IRAM
  49. Finding available heap
  50. ^^^^^^^^^^^^^^^^^^^^^^
  51. See :ref:`heap-information`.
  52. Special Capabilities
  53. --------------------
  54. .. _dma-capable-memory:
  55. DMA-Capable Memory
  56. ^^^^^^^^^^^^^^^^^^
  57. Use the ``MALLOC_CAP_DMA`` flag to allocate memory which is suitable for use with hardware DMA engines (for example SPI and I2S). This capability flag excludes any external PSRAM.
  58. .. only SOC_SPIRAM_SUPPORTED and not esp32::
  59. The EDMA hardware feature allows DMA buffers to be placed in external PSRAM, but there may be additional alignment constraints. Consult the {IDF_TARGET_NAME} Technical Reference Manual for details. To allocate a DMA-capable external memory buffer, use the ``MALLOC_CAP_SPIRAM`` capabilities flag together with :cpp:func:`heap_caps_aligned_alloc` with the necessary alignment specified.
  60. .. _32-bit accessible memory:
  61. 32-Bit Accessible Memory
  62. ^^^^^^^^^^^^^^^^^^^^^^^^
  63. If a certain memory structure is only addressed in 32-bit units, for example an array of ints or pointers, it can be
  64. useful to allocate it with the ``MALLOC_CAP_32BIT`` flag. This also allows the allocator to give out IRAM memory; something
  65. which it can't do for a normal malloc() call. This can help to use all the available memory in the {IDF_TARGET_NAME}.
  66. Memory allocated with ``MALLOC_CAP_32BIT`` can *only* be accessed via 32-bit reads and writes, any other type of access will
  67. generate a fatal LoadStoreError exception.
  68. .. only:: SOC_SPIRAM_SUPPORTED
  69. External SPI Memory
  70. ^^^^^^^^^^^^^^^^^^^
  71. 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.
  72. .. only:: esp32
  73. To use the region above the 4MiB limit, you can use the :doc:`himem API</api-reference/system/himem>`.
  74. API Reference - Heap Allocation
  75. -------------------------------
  76. .. include-build-file:: inc/esp_heap_caps.inc
  77. Thread Safety
  78. ^^^^^^^^^^^^^
  79. Heap functions are thread safe, meaning they can be called from different tasks simultaneously without any limitations.
  80. It is technically possible to call ``malloc``, ``free``, and related functions from interrupt handler (ISR) context. 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.
  81. Heap Tracing & Debugging
  82. ------------------------
  83. The following features are documented on the :doc:`Heap Memory Debugging </api-reference/system/heap_debug>` page:
  84. - :ref:`Heap Information <heap-information>` (free space, etc.)
  85. - :ref:`Heap Corruption Detection <heap-corruption>`
  86. - :ref:`Heap Tracing <heap-tracing>` (memory leak detection, monitoring, etc.)
  87. API Reference - Initialisation
  88. ------------------------------
  89. .. include-build-file:: inc/esp_heap_caps_init.inc
  90. Implementation Notes
  91. --------------------
  92. 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.
  93. 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.
  94. 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.
  95. 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.
  96. .. _multi-heap:
  97. API Reference - Multi Heap API
  98. ------------------------------
  99. (Note: The multi heap API is used internally by the heap capabilities allocator. Most IDF programs will never need to call this API directly.)
  100. .. include-build-file:: inc/multi_heap.inc