mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
feat(heap): Add walker to the heap component
Introduce new APIs in essp_heap_caps.h: - heap_caps_walk() - heap_caps_walk_all() Those functions are triggering a callback for all blocks (allocated or free) of memory present in heaps meeting the set of capabilities passed as parameter (or all heaps for heap_caps_walk_all() function) test_walker.c added to test the new functionality in test_apps/heap_test/
This commit is contained in:
parent
03756359b2
commit
5cc69ce12b
@ -49,6 +49,11 @@ else()
|
||||
list(APPEND sources "patches/esp_rom_tlsf.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_HEAP_TLSF_USE_ROM_IMPL AND CONFIG_ESP_ROM_MULTI_HEAP_WALK_PATCH)
|
||||
# This file shall be included in the build if TLSF in ROM is activated
|
||||
list(APPEND sources "patches/esp_rom_multi_heap.c")
|
||||
endif()
|
||||
|
||||
list(APPEND private_required_comp soc hal)
|
||||
endif()
|
||||
|
||||
@ -64,6 +69,8 @@ if(CONFIG_HAL_WDT_USE_ROM_IMPL)
|
||||
list(APPEND sources "patches/esp_rom_wdt.c")
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
if(CONFIG_ESP_ROM_HAS_FLASH_COUNT_PAGES_BUG OR CONFIG_ESP_ROM_HAS_CACHE_WRITEBACK_BUG)
|
||||
list(APPEND sources "patches/esp_rom_cache_esp32s2_esp32s3.c")
|
||||
endif()
|
||||
@ -216,6 +223,10 @@ else() # Regular app build
|
||||
target_link_libraries(${COMPONENT_LIB} PRIVATE "-u tlsf_set_rom_patches")
|
||||
endif()
|
||||
|
||||
if((CONFIG_ESP_ROM_TLSF_CHECK_PATCH OR CONFIG_ESP_ROM_MULTI_HEAP_WALK_PATCH))
|
||||
target_link_libraries(${COMPONENT_LIB} PRIVATE "-u esp_rom_include_multi_heap_patch")
|
||||
endif()
|
||||
|
||||
rom_linker_script("heap")
|
||||
endif()
|
||||
|
||||
|
@ -39,6 +39,10 @@ config ESP_ROM_HAS_HEAP_TLSF
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_MULTI_HEAP_WALK_PATCH
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_HAS_LAYOUT_TABLE
|
||||
bool
|
||||
default y
|
||||
|
@ -15,6 +15,7 @@
|
||||
#define ESP_ROM_HAS_HAL_WDT (1) // ROM has the implementation of Watchdog HAL driver
|
||||
#define ESP_ROM_HAS_HAL_SYSTIMER (1) // ROM has the implementation of Systimer HAL driver
|
||||
#define ESP_ROM_HAS_HEAP_TLSF (1) // ROM has the implementation of the tlsf and multi-heap library
|
||||
#define ESP_ROM_MULTI_HEAP_WALK_PATCH (1) // ROM does not contain the patch of multi_heap_walk()
|
||||
#define ESP_ROM_HAS_LAYOUT_TABLE (1) // ROM has the layout table
|
||||
#define ESP_ROM_HAS_SPI_FLASH (1) // ROM has the implementation of SPI Flash driver
|
||||
#define ESP_ROM_HAS_NEWLIB (1) // ROM has newlib (at least parts of it) functions included
|
||||
|
@ -7,6 +7,84 @@ if IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
source "$IDF_PATH/components/esp_rom/esp32c5/beta3/esp32c5/Kconfig.soc_caps.in"
|
||||
endif
|
||||
|
||||
<<<<<<< HEAD
|
||||
if IDF_TARGET_ESP32C5_MP_VERSION
|
||||
source "$IDF_PATH/components/esp_rom/esp32c5/mp/esp32c5/Kconfig.soc_caps.in"
|
||||
endif
|
||||
=======
|
||||
config ESP_ROM_HAS_CRC_BE
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_HAS_JPEG_DECODE
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_UART_CLK_IS_XTAL
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_USB_SERIAL_DEVICE_NUM
|
||||
int
|
||||
default 3
|
||||
|
||||
config ESP_ROM_HAS_RETARGETABLE_LOCKING
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_GET_CLK_FREQ
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_HAS_RVFPLIB
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_HAS_HAL_WDT
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_HAS_HAL_SYSTIMER
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_HAS_HEAP_TLSF
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_TLSF_CHECK_PATCH
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_MULTI_HEAP_WALK_PATCH
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_HAS_LAYOUT_TABLE
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_HAS_SPI_FLASH
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_WITHOUT_REGI2C
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_HAS_NEWLIB_NORMAL_FORMAT
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_WDT_INIT_PATCH
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_RAM_APP_NEEDS_MMU_INIT
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_USB_OTG_NUM
|
||||
int
|
||||
default -1
|
||||
>>>>>>> 9468f4df09 (feat(heap): Add walker to the heap component)
|
||||
|
@ -18,6 +18,7 @@
|
||||
#define ESP_ROM_HAS_HAL_SYSTIMER (1) // ROM has the implementation of Systimer HAL driver
|
||||
#define ESP_ROM_HAS_HEAP_TLSF (1) // ROM has the implementation of the tlsf and multi-heap library
|
||||
#define ESP_ROM_TLSF_CHECK_PATCH (1) // ROM does not contain the patch of tlsf_check_pool()
|
||||
#define ESP_ROM_MULTI_HEAP_WALK_PATCH (1) // ROM does not contain the patch of multi_heap_walk()
|
||||
#define ESP_ROM_HAS_LAYOUT_TABLE (1) // ROM has the layout table
|
||||
#define ESP_ROM_HAS_SPI_FLASH (1) // ROM has the implementation of SPI Flash driver
|
||||
#define ESP_ROM_WITHOUT_REGI2C (1) // ROM has no regi2c APIs
|
||||
|
@ -51,6 +51,10 @@ config ESP_ROM_TLSF_CHECK_PATCH
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_MULTI_HEAP_WALK_PATCH
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_HAS_LAYOUT_TABLE
|
||||
bool
|
||||
default y
|
||||
|
@ -18,6 +18,7 @@
|
||||
#define ESP_ROM_HAS_HAL_SYSTIMER (1) // ROM has the implementation of Systimer HAL driver
|
||||
#define ESP_ROM_HAS_HEAP_TLSF (1) // ROM has the implementation of the tlsf and multi-heap library
|
||||
#define ESP_ROM_TLSF_CHECK_PATCH (1) // ROM does not contain the patch of tlsf_check_pool()
|
||||
#define ESP_ROM_MULTI_HEAP_WALK_PATCH (1) // ROM does not contain the patch of multi_heap_walk()
|
||||
#define ESP_ROM_HAS_LAYOUT_TABLE (1) // ROM has the layout table
|
||||
#define ESP_ROM_HAS_SPI_FLASH (1) // ROM has the implementation of SPI Flash driver
|
||||
#define ESP_ROM_HAS_REGI2C_BUG (1) // ROM has the regi2c bug
|
||||
|
@ -43,6 +43,10 @@ config ESP_ROM_TLSF_CHECK_PATCH
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_MULTI_HEAP_WALK_PATCH
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_HAS_LAYOUT_TABLE
|
||||
bool
|
||||
default y
|
||||
|
@ -16,6 +16,7 @@
|
||||
#define ESP_ROM_HAS_HAL_SYSTIMER (1) // ROM has the implementation of Systimer HAL driver
|
||||
#define ESP_ROM_HAS_HEAP_TLSF (1) // ROM has the implementation of the tlsf and multi-heap library
|
||||
#define ESP_ROM_TLSF_CHECK_PATCH (1) // ROM does not contain the patch of tlsf_check_pool()
|
||||
#define ESP_ROM_MULTI_HEAP_WALK_PATCH (1) // ROM does not contain the patch of multi_heap_walk()
|
||||
#define ESP_ROM_HAS_LAYOUT_TABLE (1) // ROM has the layout table
|
||||
#define ESP_ROM_HAS_SPI_FLASH (1) // ROM has the implementation of SPI Flash driver
|
||||
#define ESP_ROM_WITHOUT_REGI2C (1) // ROM has no regi2c APIs
|
||||
|
40
components/esp_rom/include/esp_rom_multi_heap.h
Normal file
40
components/esp_rom/include/esp_rom_multi_heap.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @brief Opaque handle to a registered heap */
|
||||
typedef struct multi_heap_info *multi_heap_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Callback called when walking the given heap blocks of memory
|
||||
*
|
||||
* @param block_ptr Pointer to the block data
|
||||
* @param block_size The size of the block
|
||||
* @param block_used Block status. True if free, false if used
|
||||
* @param user_data Opaque pointer to user defined data
|
||||
*/
|
||||
typedef void (*multi_heap_walker_cb_t)(void *block_ptr, size_t block_size, int block_used, void *user_data);
|
||||
|
||||
/**
|
||||
* @brief Call the tlsf_walk_pool function of the heap given as parameter with
|
||||
* the walker function passed as parameter
|
||||
*
|
||||
* @param heap The heap to traverse
|
||||
* @param walker_func The walker to trigger on each block of the heap
|
||||
* @param user_data Opaque pointer to user defined data
|
||||
*/
|
||||
void multi_heap_walk(multi_heap_handle_t heap, multi_heap_walker_cb_t walker_func, void *user_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
58
components/esp_rom/patches/esp_rom_multi_heap.c
Normal file
58
components/esp_rom/patches/esp_rom_multi_heap.c
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is a patch for the multi_heap.c file stored in ROM
|
||||
* - added function multi_heap_walk
|
||||
* - added function multi_heap_walker
|
||||
* - added structure walker_data_t
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_rom_multi_heap.h"
|
||||
|
||||
// Hook to force the linker to include this file
|
||||
void esp_rom_include_multi_heap_patch(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Opaque types for TLSF implementation
|
||||
*/
|
||||
typedef void* tlsf_t;
|
||||
typedef void* pool_t;
|
||||
typedef void* tlsf_walker;
|
||||
|
||||
typedef struct multi_heap_info {
|
||||
void *lock;
|
||||
size_t free_bytes;
|
||||
size_t minimum_free_bytes;
|
||||
size_t pool_size;
|
||||
void* heap_data;
|
||||
} heap_t;
|
||||
|
||||
typedef struct walker_data {
|
||||
void *opaque_ptr;
|
||||
multi_heap_walker_cb_t walker;
|
||||
multi_heap_handle_t heap;
|
||||
} walker_data_t;
|
||||
|
||||
extern void tlsf_walk_pool(pool_t pool, tlsf_walker walker, void* user);
|
||||
extern pool_t tlsf_get_pool(tlsf_t tlsf);
|
||||
extern void multi_heap_internal_lock(multi_heap_handle_t heap);
|
||||
extern void multi_heap_internal_unlock(multi_heap_handle_t heap);
|
||||
|
||||
void multi_heap_walk(multi_heap_handle_t heap, multi_heap_walker_cb_t walker_func, void *user_data)
|
||||
{
|
||||
assert(heap != NULL);
|
||||
|
||||
multi_heap_internal_lock(heap);
|
||||
tlsf_walk_pool(tlsf_get_pool(heap->heap_data), walker_func, user_data);
|
||||
multi_heap_internal_unlock(heap);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -15,6 +15,10 @@
|
||||
#include "heap_private.h"
|
||||
#include "esp_system.h"
|
||||
|
||||
#if CONFIG_HEAP_TLSF_USE_ROM_IMPL
|
||||
#include "esp_rom_multi_heap.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HEAP_USE_HOOKS
|
||||
#define CALL_HOOK(hook, ...) { \
|
||||
if (hook != NULL) { \
|
||||
@ -860,3 +864,46 @@ void *heap_caps_aligned_calloc(size_t alignment, size_t n, size_t size, uint32_t
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
typedef struct walker_data {
|
||||
void *opaque_ptr;
|
||||
heap_caps_walker_cb_t cb_func;
|
||||
heap_t *heap;
|
||||
} walker_data_t;
|
||||
|
||||
__attribute__((noinline)) static void heap_caps_walker(void* block_ptr, size_t block_size, int block_used, void *user_data)
|
||||
{
|
||||
walker_data_t *walker_data = (walker_data_t*)user_data;
|
||||
|
||||
walker_heap_into_t heap_info = {
|
||||
(intptr_t)walker_data->heap->start,
|
||||
(intptr_t)walker_data->heap->end
|
||||
};
|
||||
walker_block_info_t block_info = {
|
||||
block_ptr,
|
||||
block_size,
|
||||
(bool)block_used
|
||||
};
|
||||
|
||||
walker_data->cb_func(heap_info, block_info, walker_data->opaque_ptr);
|
||||
}
|
||||
|
||||
void heap_caps_walk(uint32_t caps, heap_caps_walker_cb_t walker_func, void *user_data)
|
||||
{
|
||||
assert(walker_func != NULL);
|
||||
|
||||
bool all_heaps = caps & MALLOC_CAP_INVALID;
|
||||
heap_t *heap;
|
||||
SLIST_FOREACH(heap, ®istered_heaps, next) {
|
||||
if (heap->heap != NULL
|
||||
&& (all_heaps || (get_all_caps(heap) & caps) == caps)) {
|
||||
walker_data_t walker_data = {user_data, walker_func, heap};
|
||||
multi_heap_walk(heap->heap, heap_caps_walker, &walker_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void heap_caps_walk_all(heap_caps_walker_cb_t walker_func, void *user_data)
|
||||
{
|
||||
heap_caps_walk(MALLOC_CAP_INVALID, walker_func, user_data);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -444,6 +444,48 @@ void heap_caps_dump_all(void);
|
||||
*/
|
||||
size_t heap_caps_get_allocated_size( void *ptr );
|
||||
|
||||
/**
|
||||
* @brief Structure used to store heap related data passed to
|
||||
* the walker callback function
|
||||
*/
|
||||
typedef struct walker_heap_info {
|
||||
intptr_t start; ///< Start address of the heap in which the block is located
|
||||
intptr_t end; ///< End address of the heap in which the block is located
|
||||
} walker_heap_into_t;
|
||||
|
||||
/**
|
||||
* @brief Structure used to store block related data passed to
|
||||
* the walker callback function
|
||||
*/
|
||||
typedef struct walker_block_info {
|
||||
void *ptr; ///< Pointer to the block data
|
||||
size_t size; ///< The size of the block
|
||||
bool used; ///< Block status. True if free, false if used
|
||||
} walker_block_info_t;
|
||||
|
||||
/**
|
||||
* @brief Function callback used to walk the heaps
|
||||
* @see Definition in multi_heap.h
|
||||
*/
|
||||
typedef void (*heap_caps_walker_cb_t)(walker_heap_into_t heap_info, walker_block_info_t block_info, void *user_data);
|
||||
|
||||
/**
|
||||
* @brief Function called to walk through the heaps with the given set of capabilities
|
||||
*
|
||||
* @param caps The set of capabilities assigned to the heaps to walk through
|
||||
* @param walker_func Callback called for each block of the heaps being traversed
|
||||
* @param user_data Opaque pointer to user defined data
|
||||
*/
|
||||
void heap_caps_walk(uint32_t caps, heap_caps_walker_cb_t walker_func, void *user_data);
|
||||
|
||||
/**
|
||||
* @brief Function called to walk through all heaps defined by the heap component
|
||||
*
|
||||
* @param walker_func Callback called for each block of the heaps being traversed
|
||||
* @param user_data Opaque pointer to user defined data
|
||||
*/
|
||||
void heap_caps_walk_all(heap_caps_walker_cb_t walker_func, void *user_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -207,6 +207,26 @@ size_t multi_heap_reset_minimum_free_bytes(multi_heap_handle_t heap);
|
||||
*/
|
||||
void multi_heap_restore_minimum_free_bytes(multi_heap_handle_t heap, const size_t new_minimum_free_bytes_value);
|
||||
|
||||
/**
|
||||
* @brief Callback called when walking the given heap blocks of memory
|
||||
*
|
||||
* @param block_ptr Pointer to the block data
|
||||
* @param block_size The size of the block
|
||||
* @param block_used Block status. 0 if free, else, false
|
||||
* @param user_data Opaque pointer to user defined data
|
||||
*/
|
||||
typedef void (*multi_heap_walker_cb_t)(void *block_ptr, size_t block_size, int block_used, void *user_data);
|
||||
|
||||
/**
|
||||
* @brief Call the tlsf_walk_pool function of the heap given as parameter with
|
||||
* the walker function passed as parameter
|
||||
*
|
||||
* @param heap The heap to traverse
|
||||
* @param walker_func The walker to trigger on each block of the heap
|
||||
* @param user_data Opaque pointer to user defined data
|
||||
*/
|
||||
void multi_heap_walk(multi_heap_handle_t heap, multi_heap_walker_cb_t walker_func, void *user_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -355,13 +355,10 @@ bool multi_heap_check(multi_heap_handle_t heap, bool print_errors)
|
||||
return valid;
|
||||
}
|
||||
|
||||
__attribute__((noinline)) static void multi_heap_dump_tlsf(void* ptr, size_t size, int used, void* user)
|
||||
__attribute__((noinline)) static void multi_heap_dump_tlsf(void *ptr, size_t size, int used, void *user)
|
||||
{
|
||||
(void)user;
|
||||
MULTI_HEAP_STDERR_PRINTF("Block %p data, size: %d bytes, Free: %s \n",
|
||||
(void *)ptr,
|
||||
size,
|
||||
used ? "No" : "Yes");
|
||||
MULTI_HEAP_STDERR_PRINTF("Block %p data, size: %d bytes, Free: %s \n", (void *)ptr, size, used ? "No" : "Yes");
|
||||
}
|
||||
|
||||
void multi_heap_dump(multi_heap_handle_t heap)
|
||||
@ -431,6 +428,15 @@ void multi_heap_get_info_impl(multi_heap_handle_t heap, multi_heap_info_t *info)
|
||||
multi_heap_internal_unlock(heap);
|
||||
}
|
||||
|
||||
void multi_heap_walk(multi_heap_handle_t heap, multi_heap_walker_cb_t walker_func, void *user_data)
|
||||
{
|
||||
assert(heap != NULL);
|
||||
|
||||
multi_heap_internal_lock(heap);
|
||||
tlsf_walk_pool(tlsf_get_pool(heap->heap_data), walker_func, user_data);
|
||||
multi_heap_internal_unlock(heap);
|
||||
}
|
||||
|
||||
#endif // CONFIG_HEAP_TLSF_USE_ROM_IMPL
|
||||
|
||||
size_t multi_heap_reset_minimum_free_bytes(multi_heap_handle_t heap)
|
||||
|
@ -8,7 +8,8 @@ set(src_test "test_heap_main.c"
|
||||
"test_malloc.c"
|
||||
"test_realloc.c"
|
||||
"test_runtime_heap_reg.c"
|
||||
"test_task_tracking.c")
|
||||
"test_task_tracking.c"
|
||||
"test_walker.c")
|
||||
|
||||
idf_component_register(SRCS ${src_test}
|
||||
INCLUDE_DIRS "."
|
||||
|
55
components/heap/test_apps/heap_tests/main/test_walker.c
Normal file
55
components/heap/test_apps/heap_tests/main/test_walker.c
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include "unity.h"
|
||||
#include "stdio.h"
|
||||
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
#define PASS_CODE 0x9876BAAB
|
||||
#define ALLOC_SIZE 16
|
||||
|
||||
static bool block_found = false;
|
||||
static void heap_walker(walker_heap_into_t heap_info, walker_block_info_t block_info, void* user_data)
|
||||
{
|
||||
TEST_ASSERT(*(uint32_t*)user_data == PASS_CODE);
|
||||
TEST_ASSERT_NOT_NULL(block_info.ptr);
|
||||
|
||||
uint32_t metadata_size_head = 0;
|
||||
uint32_t metadata_size_tail = 0;
|
||||
#if !CONFIG_HEAP_POISONING_DISABLED
|
||||
metadata_size_head += 8; // sizeof(poison_head_t)
|
||||
metadata_size_tail += 4; // sizeof(poison_tail_t)
|
||||
#endif
|
||||
#if CONFIG_HEAP_TASK_TRACKING
|
||||
metadata_size_head += 4; // sizeof(TaskHandle_t)
|
||||
#endif
|
||||
|
||||
/* look for the first 4 bytes pass code to identify the memory allocated in the test */
|
||||
const uint32_t pass_code = *((uint32_t*)block_info.ptr + (metadata_size_head / sizeof(uint32_t)));
|
||||
if (pass_code == PASS_CODE) {
|
||||
TEST_ASSERT(block_info.size == ALLOC_SIZE + metadata_size_head + metadata_size_tail);
|
||||
TEST_ASSERT_TRUE(block_info.used);
|
||||
block_found = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* This test assures the proper functioning of heap_caps_walk and heap_caps_walk_all
|
||||
*/
|
||||
TEST_CASE("heap walker", "[heap]")
|
||||
{
|
||||
/* Allocate memory using the MALLOC_CAP_DEFAULT capability */
|
||||
void *default_ptr = heap_caps_malloc(ALLOC_SIZE, MALLOC_CAP_DEFAULT);
|
||||
TEST_ASSERT_NOT_NULL(default_ptr);
|
||||
|
||||
/* Write the pass code in the first word of the allocated memory */
|
||||
*((uint32_t*)default_ptr) = (uint32_t)PASS_CODE;
|
||||
|
||||
/* call the heap_caps_walker to make sure the hook function is triggered
|
||||
* and check that the allocated memory is found while walking the heap */
|
||||
uint32_t user_code = PASS_CODE;
|
||||
heap_caps_walk_all(heap_walker, &user_code);
|
||||
TEST_ASSERT_TRUE(block_found);
|
||||
}
|
Loading…
Reference in New Issue
Block a user