]> granicus.if.org Git - esp-idf/commitdiff
Fix small things noticed in MR, add documentation
authorJeroen Domburg <jeroen@espressif.com>
Tue, 13 Dec 2016 09:01:10 +0000 (17:01 +0800)
committerJeroen Domburg <jeroen@espressif.com>
Thu, 15 Dec 2016 07:03:22 +0000 (15:03 +0800)
components/esp32/heap_alloc_caps.c
components/esp32/include/esp_heap_alloc_caps.h
components/freertos/heap_regions.c
components/freertos/include/freertos/heap_regions.h
docs/Doxyfile
docs/api/mem_alloc.rst [new file with mode: 0644]
docs/index.rst

index 7ce8ba5ca664a573bd402921d46486f2dce99af1..511903c4384d9847bf7eeaefda278bb44d221392 100644 (file)
@@ -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
-because we're not using the SPI flash yet! If we enable that, this will break. ToDo: Rewrite by then.
+Warning: These variables are assumed to have the start and end of the data and iram
+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;
 
@@ -177,6 +178,8 @@ Same with loading of apps. Same with using SPI RAM.
 */
 void heap_alloc_caps_init() {
     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_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
@@ -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++) {
         if (regions[i].xTag != -1) {
             ESP_EARLY_LOGI(TAG, "At %08X len %08X (%d KiB): %s", 
index 42bc614c21fa52c2a143f212a16690152e6ab60b..21c24de6bf2c78350d659df7207b998cd7e3bfc4 100644 (file)
 #ifndef 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
-#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_PID2             (1<<4)  //Memory must be mapped to PID2 memory space
-#define MALLOC_CAP_PID3             (1<<5)  //Memory must be mapped to PID3 memory space
-#define MALLOC_CAP_PID4             (1<<6)  //Memory must be mapped to PID4 memory space
-#define MALLOC_CAP_PID5             (1<<7)  //Memory must be mapped to PID5 memory space
-#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 Flags to indicate the capabilities of the various memory systems
+ */
+#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
+#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_PID2             (1<<4)  ///< Memory must be mapped to PID2 memory space
+#define MALLOC_CAP_PID3             (1<<5)  ///< Memory must be mapped to PID3 memory space
+#define MALLOC_CAP_PID4             (1<<6)  ///< Memory must be mapped to PID4 memory space
+#define MALLOC_CAP_PID5             (1<<7)  ///< Memory must be mapped to PID5 memory space
+#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();
+
+/**
+ * @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);
+
+/**
+ * @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 );
+
+/**
+ * @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 );
 
 #endif
\ No newline at end of file
index 6e1cb103fd74067ff8a0c407662aed06f2163e71..5ff1f2817e7a83c3feb1f1cd9faeafbb7f87c2e1 100644 (file)
@@ -147,8 +147,9 @@ task.h is included from an application file. */
 #define heapBITS_PER_BYTE       ( ( size_t ) 8 )
 
 /* Define the linked list structure.  This is used to link free blocks in order
-of their memory address. */
-/* This is optimized and assumes a region is never larger than 16MiB. */
+   of their memory address. This is optimized for size of the linked list struct
+   and assumes a region is never larger than 16MiB. */
+#define HEAPREGIONS_MAX_REGIONSIZE (16*1024*1024)
 typedef struct A_BLOCK_LINK
 {
     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->xSizeInBytes < HEAPREGIONS_MAX_REGIONSIZE);
         xTotalRegionSize = pxHeapRegion->xSizeInBytes;
 
         /* Ensure the heap region starts on a correctly aligned boundary. */
index 3e632dac7adad1b4db54000a9da2f570e786a9ec..30d0dcb39cce7a8b337eb7648a98c5a48e12200c 100644 (file)
 /* The maximum amount of tags in use */
 #define HEAPREGIONS_MAX_TAGCOUNT 16
 
-
+/**
+ * @brief Structure to define a memory region
+ */
 typedef struct HeapRegionTagged
 {
-       uint8_t *pucStartAddress;
-       size_t xSizeInBytes;
-       BaseType_t xTag;
-       uint32_t xExecAddr;
+    uint8_t *pucStartAddress;       ///< Start address of the region
+    size_t xSizeInBytes;            ///< Size of the region
+    BaseType_t xTag;                ///< Tag for the region
+    uint32_t xExecAddr;             ///< If non-zero, indicates the region also has an alias in IRAM.
 } 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 );
+
+
+/**
+ * @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 );
+
+/**
+ * @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 );
+
+/**
+ * @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 );
 
 
index bdb91a4dcef9a3e317fbe87c8f88afcdadd7bfb6..2456b6c2ea161c8a6f4876915c869bae5170e595 100755 (executable)
@@ -28,7 +28,9 @@ INPUT = ../components/esp32/include/esp_wifi.h \
        ../components/app_update/include/esp_ota_ops.h \
        ../components/ethernet/include/esp_eth.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 
 ##
diff --git a/docs/api/mem_alloc.rst b/docs/api/mem_alloc.rst
new file mode 100644 (file)
index 0000000..d2af7f2
--- /dev/null
@@ -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
index 4e58cfe02f2900415e5fcaa112f4022dcc03398e..8a42e762c030bd1f592998f4812d7cf7b1e935ac 100755 (executable)
@@ -48,7 +48,8 @@ Contents:
      1.3. Flash encryption and secure boot: how they work and APIs
      1.4. Lower Power Coprocessor - TBA
      1.5. Watchdogs <api/wdts>
-     1.6. ...
+     1.6. Memory allocation <api/mem_alloc>
+     1.7. ...
    2. Memory - TBA
      2.1. Memory layout of the application (IRAM/IROM, limitations of each) - TBA
      2.2. Flash layout and partitions - TBA
@@ -111,6 +112,7 @@ Contents:
    Virtual Filesystem <api/vfs>
    Ethernet <api/esp_eth>
    Interrupt Allocation <api/intr_alloc>
+   Memory Allocation <api/mem_alloc>
    deep-sleep-stub
 
    Template <api/template>