heap: make compatible with non-OS builds, remove target dependence

This commit is contained in:
Ivan Grokhotkov 2019-12-18 17:04:49 +01:00
parent acca61c714
commit 3285ed116d
7 changed files with 43 additions and 22 deletions

View file

@ -38,5 +38,12 @@ if(CONFIG_HEAP_TRACING)
foreach(wrap ${WRAP_FUNCTIONS})
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=${wrap}")
endforeach()
endif()
if(NOT CMAKE_BUILD_EARLY_EXPANSION)
idf_build_get_property(build_components BUILD_COMPONENTS)
if(freertos IN_LIST build_components)
target_compile_options(${COMPONENT_TARGET} PRIVATE "-DMULTI_HEAP_FREERTOS")
endif()
endif()

View file

@ -28,3 +28,5 @@ COMPONENT_ADD_LDFLAGS = -l$(COMPONENT_NAME) $(addprefix $(WRAP_ARGUMENT),$(WRAP_
endif
COMPONENT_ADD_LDFRAGMENTS += linker.lf
CFLAGS += -DMULTI_HEAP_FREERTOS

View file

@ -44,9 +44,9 @@ IRAM_ATTR static void *dram_alloc_to_iram_addr(void *addr, size_t len)
assert(esp_ptr_in_diram_dram((void *)dend));
assert((dstart & 3) == 0);
assert((dend & 3) == 0);
#if CONFIG_IDF_TARGET_ESP32
#if SOC_DIRAM_INVERTED
uint32_t istart = SOC_DIRAM_IRAM_LOW + (SOC_DIRAM_DRAM_HIGH - dend);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
#else
uint32_t istart = SOC_DIRAM_IRAM_LOW + (dstart - SOC_DIRAM_DRAM_LOW);
#endif
uint32_t *iptr = (uint32_t *)istart;

View file

@ -18,12 +18,10 @@
#include "esp_log.h"
#include "multi_heap.h"
#include "multi_heap_platform.h"
#include "esp_heap_caps_init.h"
#include "soc/soc_memory_layout.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
static const char *TAG = "heap_init";
/* Linked-list of registered heaps */
@ -107,7 +105,7 @@ void heap_caps_init(void)
memcpy(heap->caps, type->caps, sizeof(heap->caps));
heap->start = region->start;
heap->end = region->start + region->size;
vPortCPUInitializeMutex(&heap->heap_mux);
MULTI_HEAP_LOCK_INIT(&heap->heap_mux);
if (type->startup_stack) {
/* Will be registered when OS scheduler starts */
heap->heap = NULL;
@ -216,7 +214,7 @@ esp_err_t heap_caps_add_region_with_caps(const uint32_t caps[], intptr_t start,
memcpy(p_new->caps, caps, sizeof(p_new->caps));
p_new->start = start;
p_new->end = end;
vPortCPUInitializeMutex(&p_new->heap_mux);
MULTI_HEAP_LOCK_INIT(&p_new->heap_mux);
p_new->heap = multi_heap_register((void *)start, end - start);
SLIST_NEXT(p_new, next) = NULL;
if (p_new->heap == NULL) {
@ -228,10 +226,10 @@ esp_err_t heap_caps_add_region_with_caps(const uint32_t caps[], intptr_t start,
/* (This insertion is atomic to registered_heaps, so
we don't need to worry about thread safety for readers,
only for writers. */
static _lock_t registered_heaps_write_lock;
_lock_acquire(&registered_heaps_write_lock);
static multi_heap_lock_t registered_heaps_write_lock = MULTI_HEAP_LOCK_STATIC_INITIALIZER;
MULTI_HEAP_LOCK(&registered_heaps_write_lock);
SLIST_INSERT_HEAD(&registered_heaps, p_new, next);
_lock_release(&registered_heaps_write_lock);
MULTI_HEAP_UNLOCK(&registered_heaps_write_lock);
err = ESP_OK;

View file

@ -15,9 +15,9 @@
#include <stdlib.h>
#include <stdint.h>
#include <freertos/FreeRTOS.h>
#include <soc/soc_memory_layout.h>
#include "multi_heap.h"
#include "multi_heap_platform.h"
#include "sys/queue.h"
#ifdef __cplusplus
@ -35,7 +35,7 @@ typedef struct heap_t_ {
uint32_t caps[SOC_MEMORY_TYPE_NO_PRIOS]; ///< Capabilities for the type of memory in this heap (as a prioritised set). Copied from soc_memory_types so it's in RAM not flash.
intptr_t start;
intptr_t end;
portMUX_TYPE heap_mux;
multi_heap_lock_t heap_mux;
multi_heap_handle_t heap;
SLIST_ENTRY(heap_t_) next;
} heap_t;

View file

@ -13,7 +13,7 @@
// limitations under the License.
#pragma once
#ifdef ESP_PLATFORM
#ifdef MULTI_HEAP_FREERTOS
#include <freertos/FreeRTOS.h>
#include "sdkconfig.h"
@ -24,21 +24,29 @@
#endif
#include <assert.h>
typedef portMUX_TYPE multi_heap_lock_t;
/* Because malloc/free can happen inside an ISR context,
we need to use portmux spinlocks here not RTOS mutexes */
#define MULTI_HEAP_LOCK(PLOCK) do { \
#define MULTI_HEAP_LOCK(PLOCK) do { \
if((PLOCK) != NULL) { \
portENTER_CRITICAL((portMUX_TYPE *)(PLOCK)); \
portENTER_CRITICAL((PLOCK)); \
} \
} while(0)
#define MULTI_HEAP_UNLOCK(PLOCK) do { \
#define MULTI_HEAP_UNLOCK(PLOCK) do { \
if ((PLOCK) != NULL) { \
portEXIT_CRITICAL((portMUX_TYPE *)(PLOCK)); \
portEXIT_CRITICAL((PLOCK)); \
} \
} while(0)
#define MULTI_HEAP_LOCK_INIT(PLOCK) do { \
vPortCPUInitializeMutex((PLOCK)); \
} while(0)
#define MULTI_HEAP_LOCK_STATIC_INITIALIZER portMUX_INITIALIZER_UNLOCKED
/* Not safe to use std i/o while in a portmux critical section,
can deadlock, so we use the ROM equivalent functions. */
@ -78,14 +86,18 @@ inline static void multi_heap_assert(bool condition, const char *format, int lin
#define MULTI_HEAP_GET_BLOCK_OWNER(HEAD) (NULL)
#endif
#else // ESP_PLATFORM
#else // MULTI_HEAP_FREERTOS
#include <assert.h>
typedef int multi_heap_lock_t;
#define MULTI_HEAP_PRINTF printf
#define MULTI_HEAP_STDERR_PRINTF(MSG, ...) fprintf(stderr, MSG, __VA_ARGS__)
#define MULTI_HEAP_LOCK(PLOCK)
#define MULTI_HEAP_UNLOCK(PLOCK)
#define MULTI_HEAP_LOCK(PLOCK) (void) (PLOCK)
#define MULTI_HEAP_UNLOCK(PLOCK) (void) (PLOCK)
#define MULTI_HEAP_LOCK_INIT(PLOCK) (void) (PLOCK)
#define MULTI_HEAP_LOCK_STATIC_INITIALIZER 0
#define MULTI_HEAP_ASSERT(CONDITION, ADDRESS) assert((CONDITION) && "Heap corrupt")
@ -93,4 +105,4 @@ inline static void multi_heap_assert(bool condition, const char *format, int lin
#define MULTI_HEAP_SET_BLOCK_OWNER(HEAD)
#define MULTI_HEAP_GET_BLOCK_OWNER(HEAD) (NULL)
#endif
#endif // MULTI_HEAP_FREERTOS

View file

@ -261,6 +261,8 @@
#define SOC_DIRAM_IRAM_HIGH 0x400C0000
#define SOC_DIRAM_DRAM_LOW 0x3FFE0000
#define SOC_DIRAM_DRAM_HIGH 0x40000000
// Byte order of D/IRAM regions is reversed between accessing as DRAM or IRAM
#define SOC_DIRAM_INVERTED 1
// Region of memory accessible via DMA. See esp_ptr_dma_capable().
#define SOC_DMA_LOW 0x3FFAE000