heap: add check for usage of flash content from iram

this commits:
- adds build-time test to check that no call to flash regions are done from IRAM functions

- resolves problems related to IRAM function using content in flash memory

- update heap_caps_alloc_failed to use a default function name in DRAM
  when necessary instead of creating a function name variable in DRAM for
  each call of heap_caps_alloc_failed. This allows to save some extra bytes
  in RAM.
This commit is contained in:
Guillaume Souchere 2022-11-04 15:48:09 +01:00 committed by BOT
parent 5f735a22ec
commit 598e77e287
5 changed files with 26 additions and 5 deletions

View File

@ -22,7 +22,7 @@ endif()
idf_component_register(SRCS "${srcs}" idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS include INCLUDE_DIRS include
LDFRAGMENTS linker.lf LDFRAGMENTS linker.lf
PRIV_REQUIRES soc) PRIV_REQUIRES soc spi_flash)
if(CONFIG_HEAP_TRACING) if(CONFIG_HEAP_TRACING)
set(WRAP_FUNCTIONS set(WRAP_FUNCTIONS

View File

@ -22,7 +22,7 @@
#include "esp_log.h" #include "esp_log.h"
#include "heap_private.h" #include "heap_private.h"
#include "esp_system.h" #include "esp_system.h"
#include "esp_private/cache_utils.h"
// forward declaration // forward declaration
IRAM_ATTR static void *heap_caps_realloc_base( void *ptr, size_t size, uint32_t caps); IRAM_ATTR static void *heap_caps_realloc_base( void *ptr, size_t size, uint32_t caps);
@ -61,10 +61,16 @@ IRAM_ATTR static void *dram_alloc_to_iram_addr(void *addr, size_t len)
} }
static void heap_caps_alloc_failed(size_t requested_size, uint32_t caps, const char *function_name) IRAM_ATTR static void heap_caps_alloc_failed(size_t requested_size, uint32_t caps, const char *function_name)
{ {
static const DRAM_ATTR char *default_func_name = "<function_name>";
if (alloc_failed_callback) { if (alloc_failed_callback) {
alloc_failed_callback(requested_size, caps, function_name); if (!spi_flash_cache_enabled() && !esp_ptr_internal(function_name)) {
alloc_failed_callback(requested_size, caps, default_func_name);
}
else {
alloc_failed_callback(requested_size, caps, function_name);
}
} }
#ifdef CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS #ifdef CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS

View File

@ -51,7 +51,7 @@ extern SLIST_HEAD(registered_heap_ll, heap_t_) registered_heaps;
bool heap_caps_match(const heap_t *heap, uint32_t caps); bool heap_caps_match(const heap_t *heap, uint32_t caps);
/* return all possible capabilities (across all priorities) for a given heap */ /* return all possible capabilities (across all priorities) for a given heap */
inline static uint32_t get_all_caps(const heap_t *heap) inline static __attribute__((always_inline)) uint32_t get_all_caps(const heap_t *heap)
{ {
if (heap->heap == NULL) { if (heap->heap == NULL) {
return 0; return 0;

View File

@ -1,3 +1,17 @@
idf_component_register(SRC_DIRS "." idf_component_register(SRC_DIRS "."
PRIV_INCLUDE_DIRS "." PRIV_INCLUDE_DIRS "."
PRIV_REQUIRES cmock test_utils heap) PRIV_REQUIRES cmock test_utils heap)
if(CONFIG_COMPILER_DUMP_RTL_FILES)
idf_build_get_property(elf_file_name EXECUTABLE GENERATOR_EXPRESSION)
add_custom_target(check_test_app_sections ALL
COMMAND ${PYTHON} $ENV{IDF_PATH}/tools/ci/check_callgraph.py
--rtl-dir ${CMAKE_BINARY_DIR}/esp-idf/heap/
--elf-file ${CMAKE_BINARY_DIR}/${elf_file_name}
find-refs
--from-sections=.iram0.text
--to-sections=.flash.text,.flash.rodata
--exit-code
DEPENDS ${elf_file_name}
)
endif()

View File

@ -26,3 +26,4 @@ CONFIG_SPIRAM_BANKSWITCH_ENABLE=n
CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y
CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL=y CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL=y
CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER=n CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER=n
CONFIG_COMPILER_DUMP_RTL_FILES=y