mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Fix small things noticed in MR, add documentation
This commit is contained in:
parent
293ad4cd36
commit
1e117dc3d3
@ -164,8 +164,9 @@ static void disable_mem_region(void *from, void *to) {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ToDo: These are very dependent on the linker script, and the logic involving this works only
|
Warning: These variables are assumed to have the start and end of the data and iram
|
||||||
because we're not using the SPI flash yet! If we enable that, this will break. ToDo: Rewrite by then.
|
area used statically by the program, respectively. These variables are defined in the ld
|
||||||
|
file.
|
||||||
*/
|
*/
|
||||||
extern int _bss_start, _heap_start, _init_start, _iram_text_end;
|
extern int _bss_start, _heap_start, _init_start, _iram_text_end;
|
||||||
|
|
||||||
@ -177,6 +178,8 @@ Same with loading of apps. Same with using SPI RAM.
|
|||||||
*/
|
*/
|
||||||
void heap_alloc_caps_init() {
|
void heap_alloc_caps_init() {
|
||||||
int i;
|
int i;
|
||||||
|
//Compile-time assert to see if we don't have more tags than is set in heap_regions.h
|
||||||
|
_Static_assert((sizeof(tag_desc)/sizeof(tag_desc[0]))-1 <= HEAPREGIONS_MAX_TAGCOUNT, "More than HEAPREGIONS_MAX_TAGCOUNT tags defined!");
|
||||||
//Disable the bits of memory where this code is loaded.
|
//Disable the bits of memory where this code is loaded.
|
||||||
disable_mem_region(&_bss_start, &_heap_start); //DRAM used by bss/data static variables
|
disable_mem_region(&_bss_start, &_heap_start); //DRAM used by bss/data static variables
|
||||||
disable_mem_region(&_init_start, &_iram_text_end); //IRAM used by code
|
disable_mem_region(&_init_start, &_iram_text_end); //IRAM used by code
|
||||||
@ -217,7 +220,7 @@ void heap_alloc_caps_init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_EARLY_LOGI(TAG, "Initializing. RAM available for heap:");
|
ESP_EARLY_LOGI(TAG, "Initializing. RAM available for dynamic allocation:");
|
||||||
for (i=0; regions[i].xSizeInBytes!=0; i++) {
|
for (i=0; regions[i].xSizeInBytes!=0; i++) {
|
||||||
if (regions[i].xTag != -1) {
|
if (regions[i].xTag != -1) {
|
||||||
ESP_EARLY_LOGI(TAG, "At %08X len %08X (%d KiB): %s",
|
ESP_EARLY_LOGI(TAG, "At %08X len %08X (%d KiB): %s",
|
||||||
|
@ -14,23 +14,65 @@
|
|||||||
#ifndef HEAP_ALLOC_CAPS_H
|
#ifndef HEAP_ALLOC_CAPS_H
|
||||||
#define HEAP_ALLOC_CAPS_H
|
#define HEAP_ALLOC_CAPS_H
|
||||||
|
|
||||||
#define MALLOC_CAP_EXEC (1<<0) //Memory must be able to run executable code
|
/**
|
||||||
#define MALLOC_CAP_32BIT (1<<1) //Memory must allow for aligned 32-bit data accesses
|
* @brief Flags to indicate the capabilities of the various memory systems
|
||||||
#define MALLOC_CAP_8BIT (1<<2) //Memory must allow for 8/16/...-bit data accesses
|
*/
|
||||||
#define MALLOC_CAP_DMA (1<<3) //Memory must be able to accessed by DMA
|
#define MALLOC_CAP_EXEC (1<<0) ///< Memory must be able to run executable code
|
||||||
#define MALLOC_CAP_PID2 (1<<4) //Memory must be mapped to PID2 memory space
|
#define MALLOC_CAP_32BIT (1<<1) ///< Memory must allow for aligned 32-bit data accesses
|
||||||
#define MALLOC_CAP_PID3 (1<<5) //Memory must be mapped to PID3 memory space
|
#define MALLOC_CAP_8BIT (1<<2) ///< Memory must allow for 8/16/...-bit data accesses
|
||||||
#define MALLOC_CAP_PID4 (1<<6) //Memory must be mapped to PID4 memory space
|
#define MALLOC_CAP_DMA (1<<3) ///< Memory must be able to accessed by DMA
|
||||||
#define MALLOC_CAP_PID5 (1<<7) //Memory must be mapped to PID5 memory space
|
#define MALLOC_CAP_PID2 (1<<4) ///< Memory must be mapped to PID2 memory space
|
||||||
#define MALLOC_CAP_PID6 (1<<8) //Memory must be mapped to PID6 memory space
|
#define MALLOC_CAP_PID3 (1<<5) ///< Memory must be mapped to PID3 memory space
|
||||||
#define MALLOC_CAP_PID7 (1<<9) //Memory must be mapped to PID7 memory space
|
#define MALLOC_CAP_PID4 (1<<6) ///< Memory must be mapped to PID4 memory space
|
||||||
#define MALLOC_CAP_SPISRAM (1<<10) //Memory must be in SPI SRAM
|
#define MALLOC_CAP_PID5 (1<<7) ///< Memory must be mapped to PID5 memory space
|
||||||
#define MALLOC_CAP_INVALID (1<<31) //Memory can't be used / list end marker
|
#define MALLOC_CAP_PID6 (1<<8) ///< Memory must be mapped to PID6 memory space
|
||||||
|
#define MALLOC_CAP_PID7 (1<<9) ///< Memory must be mapped to PID7 memory space
|
||||||
|
#define MALLOC_CAP_SPISRAM (1<<10) ///< Memory must be in SPI SRAM
|
||||||
|
#define MALLOC_CAP_INVALID (1<<31) ///< Memory can't be used / list end marker
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the capability-aware heap allocator.
|
||||||
|
*
|
||||||
|
* For the ESP32, this is called once in the startup code.
|
||||||
|
*/
|
||||||
void heap_alloc_caps_init();
|
void heap_alloc_caps_init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocate a chunk of memory which has the given capabilities
|
||||||
|
*
|
||||||
|
* @param xWantedSize Size, in bytes, of the amount of memory to allocate
|
||||||
|
* @param caps Bitwise OR of MALLOC_CAP_* flags indicating the type
|
||||||
|
* of memory to be returned
|
||||||
|
*
|
||||||
|
* @return A pointer to the memory allocated on success, NULL on failure
|
||||||
|
*/
|
||||||
void *pvPortMallocCaps(size_t xWantedSize, uint32_t caps);
|
void *pvPortMallocCaps(size_t xWantedSize, uint32_t caps);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the total free size of all the regions that have the given capabilities
|
||||||
|
*
|
||||||
|
* This function takes all regions capable of having the given capabilities allocated in them
|
||||||
|
* and adds up the free space they have.
|
||||||
|
*
|
||||||
|
* @param caps Bitwise OR of MALLOC_CAP_* flags indicating the type
|
||||||
|
* of memory
|
||||||
|
*
|
||||||
|
* @return Amount of free bytes in the regions
|
||||||
|
*/
|
||||||
size_t xPortGetFreeHeapSizeCaps( uint32_t caps );
|
size_t xPortGetFreeHeapSizeCaps( uint32_t caps );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the total minimum free memory of all regions with the given capabilities
|
||||||
|
*
|
||||||
|
* This adds all the lowmarks of the regions capable of delivering the memory with the
|
||||||
|
* given capabilities
|
||||||
|
*
|
||||||
|
* @param caps Bitwise OR of MALLOC_CAP_* flags indicating the type
|
||||||
|
* of memory
|
||||||
|
*
|
||||||
|
* @return Amount of free bytes in the regions
|
||||||
|
*/
|
||||||
size_t xPortGetMinimumEverFreeHeapSizeCaps( uint32_t caps );
|
size_t xPortGetMinimumEverFreeHeapSizeCaps( uint32_t caps );
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -147,8 +147,9 @@ task.h is included from an application file. */
|
|||||||
#define heapBITS_PER_BYTE ( ( size_t ) 8 )
|
#define heapBITS_PER_BYTE ( ( size_t ) 8 )
|
||||||
|
|
||||||
/* Define the linked list structure. This is used to link free blocks in order
|
/* Define the linked list structure. This is used to link free blocks in order
|
||||||
of their memory address. */
|
of their memory address. This is optimized for size of the linked list struct
|
||||||
/* This is optimized and assumes a region is never larger than 16MiB. */
|
and assumes a region is never larger than 16MiB. */
|
||||||
|
#define HEAPREGIONS_MAX_REGIONSIZE (16*1024*1024)
|
||||||
typedef struct A_BLOCK_LINK
|
typedef struct A_BLOCK_LINK
|
||||||
{
|
{
|
||||||
struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */
|
struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */
|
||||||
@ -496,6 +497,7 @@ const HeapRegionTagged_t *pxHeapRegion;
|
|||||||
}
|
}
|
||||||
|
|
||||||
configASSERT(pxHeapRegion->xTag < HEAPREGIONS_MAX_TAGCOUNT);
|
configASSERT(pxHeapRegion->xTag < HEAPREGIONS_MAX_TAGCOUNT);
|
||||||
|
configASSERT(pxHeapRegion->xSizeInBytes < HEAPREGIONS_MAX_REGIONSIZE);
|
||||||
xTotalRegionSize = pxHeapRegion->xSizeInBytes;
|
xTotalRegionSize = pxHeapRegion->xSizeInBytes;
|
||||||
|
|
||||||
/* Ensure the heap region starts on a correctly aligned boundary. */
|
/* Ensure the heap region starts on a correctly aligned boundary. */
|
||||||
|
@ -19,19 +19,68 @@
|
|||||||
/* The maximum amount of tags in use */
|
/* The maximum amount of tags in use */
|
||||||
#define HEAPREGIONS_MAX_TAGCOUNT 16
|
#define HEAPREGIONS_MAX_TAGCOUNT 16
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Structure to define a memory region
|
||||||
|
*/
|
||||||
typedef struct HeapRegionTagged
|
typedef struct HeapRegionTagged
|
||||||
{
|
{
|
||||||
uint8_t *pucStartAddress;
|
uint8_t *pucStartAddress; ///< Start address of the region
|
||||||
size_t xSizeInBytes;
|
size_t xSizeInBytes; ///< Size of the region
|
||||||
BaseType_t xTag;
|
BaseType_t xTag; ///< Tag for the region
|
||||||
uint32_t xExecAddr;
|
uint32_t xExecAddr; ///< If non-zero, indicates the region also has an alias in IRAM.
|
||||||
} HeapRegionTagged_t;
|
} HeapRegionTagged_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the heap allocator by feeding it the usable memory regions and their tags.
|
||||||
|
*
|
||||||
|
* This takes an array of heapRegionTagged_t structs, the last entry of which is a dummy entry
|
||||||
|
* which has pucStartAddress set to NULL. It will initialize the heap allocator to serve memory
|
||||||
|
* from these ranges.
|
||||||
|
*
|
||||||
|
* @param pxHeapRegions Array of region definitions
|
||||||
|
*/
|
||||||
|
|
||||||
void vPortDefineHeapRegionsTagged( const HeapRegionTagged_t * const pxHeapRegions );
|
void vPortDefineHeapRegionsTagged( const HeapRegionTagged_t * const pxHeapRegions );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocate memory from a region with a certain tag
|
||||||
|
*
|
||||||
|
* Like pvPortMalloc, this returns an allocated chunk of memory. This function,
|
||||||
|
* however, forces the allocator to allocate from a region specified by a
|
||||||
|
* specific tag.
|
||||||
|
*
|
||||||
|
* @param xWantedSize Size needed, in bytes
|
||||||
|
* @param tag Tag of the memory region the allocation has to be from
|
||||||
|
*
|
||||||
|
* @return Pointer to allocated memory if succesful.
|
||||||
|
* NULL if unsuccesful.
|
||||||
|
*/
|
||||||
void *pvPortMallocTagged( size_t xWantedSize, BaseType_t tag );
|
void *pvPortMallocTagged( size_t xWantedSize, BaseType_t tag );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the lowest amount of memory free for a certain tag
|
||||||
|
*
|
||||||
|
* This function allows the user to see what the least amount of
|
||||||
|
* free memory for a certain tag is.
|
||||||
|
*
|
||||||
|
* @param tag Tag of the memory region
|
||||||
|
*
|
||||||
|
* @return Minimum amount of free bytes available in the runtime of
|
||||||
|
* the program
|
||||||
|
*/
|
||||||
size_t xPortGetMinimumEverFreeHeapSizeTagged( BaseType_t tag );
|
size_t xPortGetMinimumEverFreeHeapSizeTagged( BaseType_t tag );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the amount of free bytes in a certain tagged region
|
||||||
|
*
|
||||||
|
* Works like xPortGetFreeHeapSize but allows the user to specify
|
||||||
|
* a specific tag
|
||||||
|
*
|
||||||
|
* @param tag Tag of the memory region
|
||||||
|
*
|
||||||
|
* @return Remaining amount of free bytes in region
|
||||||
|
*/
|
||||||
size_t xPortGetFreeHeapSizeTagged( BaseType_t tag );
|
size_t xPortGetFreeHeapSizeTagged( BaseType_t tag );
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,7 +28,9 @@ INPUT = ../components/esp32/include/esp_wifi.h \
|
|||||||
../components/app_update/include/esp_ota_ops.h \
|
../components/app_update/include/esp_ota_ops.h \
|
||||||
../components/ethernet/include/esp_eth.h \
|
../components/ethernet/include/esp_eth.h \
|
||||||
../components/ulp/include/esp32/ulp.h \
|
../components/ulp/include/esp32/ulp.h \
|
||||||
../components/esp32/include/esp_intr_alloc.h
|
../components/esp32/include/esp_intr_alloc.h \
|
||||||
|
../components/esp32/include/esp_heap_alloc_caps.h \
|
||||||
|
../components/freertos/include/freertos/heap_regions.h
|
||||||
|
|
||||||
## Get warnings for functions that have no documentation for their parameters or return value
|
## Get warnings for functions that have no documentation for their parameters or return value
|
||||||
##
|
##
|
||||||
|
78
docs/api/mem_alloc.rst
Normal file
78
docs/api/mem_alloc.rst
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
Memory allocation
|
||||||
|
====================
|
||||||
|
|
||||||
|
Overview
|
||||||
|
--------
|
||||||
|
|
||||||
|
The ESP32 has multiple types of RAM. Internally, there's IRAM, DRAM as well as RAM that can be used as both. It's also
|
||||||
|
possible to connect external SPI flash to the ESP32; it's memory can be integrated into the ESP32s memory map using
|
||||||
|
the flash cache.
|
||||||
|
|
||||||
|
In order to make use of all this memory, esp-idf has a capabilities-based memory allocator. Basically, if you want to have
|
||||||
|
memory with certain properties (for example, DMA-capable, accessible by a certain PID, or capable of executing code), you
|
||||||
|
can create an OR-mask of the required capabilities and pass that to pvPortMallocCaps. For instance, the normal malloc
|
||||||
|
code internally allocates memory with ```pvPortMallocCaps(size, MALLOC_CAP_8BIT)``` in order to get data memory that is
|
||||||
|
byte-addressable.
|
||||||
|
|
||||||
|
Internally, this allocator is split in two pieces. The allocator in the FreeRTOS directory can allocate memory from
|
||||||
|
tagged regions: a tag is an integer value and every region of free memory has one of these tags. The esp32-specific
|
||||||
|
code initializes these regions with specific tags, and contains the logic to select applicable tags from the
|
||||||
|
capabilities given by the user. While shown in the public API, tags are used in the communication between the two parts
|
||||||
|
and should not be used directly.
|
||||||
|
|
||||||
|
Special Uses
|
||||||
|
------------
|
||||||
|
|
||||||
|
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 ESP32.
|
||||||
|
|
||||||
|
|
||||||
|
API Reference
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Header Files
|
||||||
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
|
* `esp_heap_alloc_caps.h <https://github.com/espressif/esp-idf/blob/master/components/esp32/include/esp_heap_alloc_caps.h>`_
|
||||||
|
* `heap_regions.h <https://github.com/espressif/esp-idf/blob/master/components/freertos/include/freertos/heap_regions.h>`_
|
||||||
|
|
||||||
|
|
||||||
|
Macros
|
||||||
|
^^^^^^
|
||||||
|
|
||||||
|
.. doxygendefine:: MALLOC_CAP_EXEC
|
||||||
|
.. doxygendefine:: MALLOC_CAP_32BIT
|
||||||
|
.. doxygendefine:: MALLOC_CAP_8BIT
|
||||||
|
.. doxygendefine:: MALLOC_CAP_DMA
|
||||||
|
.. doxygendefine:: MALLOC_CAP_PID2
|
||||||
|
.. doxygendefine:: MALLOC_CAP_PID3
|
||||||
|
.. doxygendefine:: MALLOC_CAP_PID4
|
||||||
|
.. doxygendefine:: MALLOC_CAP_PID5
|
||||||
|
.. doxygendefine:: MALLOC_CAP_PID6
|
||||||
|
.. doxygendefine:: MALLOC_CAP_PID7
|
||||||
|
.. doxygendefine:: MALLOC_CAP_SPISRAM
|
||||||
|
.. doxygendefine:: MALLOC_CAP_INVALID
|
||||||
|
|
||||||
|
Type Definitions
|
||||||
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. doxygentypedef:: HeapRegionTagged_t
|
||||||
|
|
||||||
|
Enumerations
|
||||||
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Structures
|
||||||
|
^^^^^^^^^^
|
||||||
|
|
||||||
|
Functions
|
||||||
|
^^^^^^^^^
|
||||||
|
|
||||||
|
.. doxygenfunction:: heap_alloc_caps_init
|
||||||
|
.. doxygenfunction:: pvPortMallocCaps
|
||||||
|
.. doxygenfunction:: xPortGetFreeHeapSizeCaps
|
||||||
|
.. doxygenfunction:: xPortGetMinimumEverFreeHeapSizeCaps
|
||||||
|
.. doxygenfunction:: vPortDefineHeapRegionsTagged
|
||||||
|
.. doxygenfunction:: pvPortMallocTagged
|
||||||
|
.. doxygenfunction:: xPortGetMinimumEverFreeHeapSizeTagged
|
||||||
|
.. doxygenfunction:: xPortGetFreeHeapSizeTagged
|
@ -48,7 +48,8 @@ Contents:
|
|||||||
1.3. Flash encryption and secure boot: how they work and APIs
|
1.3. Flash encryption and secure boot: how they work and APIs
|
||||||
1.4. Lower Power Coprocessor - TBA
|
1.4. Lower Power Coprocessor - TBA
|
||||||
1.5. Watchdogs <api/wdts>
|
1.5. Watchdogs <api/wdts>
|
||||||
1.6. ...
|
1.6. Memory allocation <api/mem_alloc>
|
||||||
|
1.7. ...
|
||||||
2. Memory - TBA
|
2. Memory - TBA
|
||||||
2.1. Memory layout of the application (IRAM/IROM, limitations of each) - TBA
|
2.1. Memory layout of the application (IRAM/IROM, limitations of each) - TBA
|
||||||
2.2. Flash layout and partitions - TBA
|
2.2. Flash layout and partitions - TBA
|
||||||
@ -111,6 +112,7 @@ Contents:
|
|||||||
Virtual Filesystem <api/vfs>
|
Virtual Filesystem <api/vfs>
|
||||||
Ethernet <api/esp_eth>
|
Ethernet <api/esp_eth>
|
||||||
Interrupt Allocation <api/intr_alloc>
|
Interrupt Allocation <api/intr_alloc>
|
||||||
|
Memory Allocation <api/mem_alloc>
|
||||||
deep-sleep-stub
|
deep-sleep-stub
|
||||||
|
|
||||||
Template <api/template>
|
Template <api/template>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user