diff --git a/components/heap/CMakeLists.txt b/components/heap/CMakeLists.txt index 2e194b5ae..07e27ccef 100644 --- a/components/heap/CMakeLists.txt +++ b/components/heap/CMakeLists.txt @@ -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() + diff --git a/components/heap/component.mk b/components/heap/component.mk index 266fbada0..e93f53096 100644 --- a/components/heap/component.mk +++ b/components/heap/component.mk @@ -28,3 +28,5 @@ COMPONENT_ADD_LDFLAGS = -l$(COMPONENT_NAME) $(addprefix $(WRAP_ARGUMENT),$(WRAP_ endif COMPONENT_ADD_LDFRAGMENTS += linker.lf + +CFLAGS += -DMULTI_HEAP_FREERTOS diff --git a/components/heap/heap_caps.c b/components/heap/heap_caps.c index 9e2ddd3a4..1a11c9702 100644 --- a/components/heap/heap_caps.c +++ b/components/heap/heap_caps.c @@ -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; diff --git a/components/heap/heap_caps_init.c b/components/heap/heap_caps_init.c index 32e7cd7e2..48dc95f63 100644 --- a/components/heap/heap_caps_init.c +++ b/components/heap/heap_caps_init.c @@ -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(®istered_heaps_write_lock); + static multi_heap_lock_t registered_heaps_write_lock = MULTI_HEAP_LOCK_STATIC_INITIALIZER; + MULTI_HEAP_LOCK(®istered_heaps_write_lock); SLIST_INSERT_HEAD(®istered_heaps, p_new, next); - _lock_release(®istered_heaps_write_lock); + MULTI_HEAP_UNLOCK(®istered_heaps_write_lock); err = ESP_OK; diff --git a/components/heap/heap_private.h b/components/heap/heap_private.h index 0826badc3..b5babaa90 100644 --- a/components/heap/heap_private.h +++ b/components/heap/heap_private.h @@ -15,9 +15,9 @@ #include #include -#include #include #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; diff --git a/components/heap/multi_heap_platform.h b/components/heap/multi_heap_platform.h index 19215288a..b64a63403 100644 --- a/components/heap/multi_heap_platform.h +++ b/components/heap/multi_heap_platform.h @@ -13,7 +13,7 @@ // limitations under the License. #pragma once -#ifdef ESP_PLATFORM +#ifdef MULTI_HEAP_FREERTOS #include #include "sdkconfig.h" @@ -24,21 +24,29 @@ #endif #include +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 +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 diff --git a/components/soc/esp32/include/soc/soc.h b/components/soc/esp32/include/soc/soc.h index 72527687f..741a50ffe 100644 --- a/components/soc/esp32/include/soc/soc.h +++ b/components/soc/esp32/include/soc/soc.h @@ -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