From 6ec373daf55b57b325fb676452c9bb367a8681bb Mon Sep 17 00:00:00 2001 From: jiangguangming Date: Fri, 19 Mar 2021 17:29:42 +0800 Subject: [PATCH] heap_tlsf: use tlsf IMPL in ESP32C2 ROM --- components/esp_rom/CMakeLists.txt | 4 +++ components/esp_rom/esp32c2/ld/esp32c2.rom.ld | 2 +- components/heap/CMakeLists.txt | 7 ++-- components/heap/Kconfig | 17 ++++++++++ components/heap/heap_caps_init.c | 4 +++ components/heap/heap_tlsf.h | 3 ++ components/heap/linker.lf | 3 +- components/heap/multi_heap.c | 32 +++++++++++++++--- components/heap/multi_heap_internal.h | 34 ++++++++++++-------- components/heap/multi_heap_poisoning.c | 23 ++++++------- tools/ci/check_copyright_ignore.txt | 2 -- 11 files changed, 95 insertions(+), 36 deletions(-) diff --git a/components/esp_rom/CMakeLists.txt b/components/esp_rom/CMakeLists.txt index 491fa11447..03da151226 100644 --- a/components/esp_rom/CMakeLists.txt +++ b/components/esp_rom/CMakeLists.txt @@ -195,6 +195,10 @@ else() # Regular app build # only link them if the toolchain is also using 32-bit time_t and nano formatting was requested. rom_linker_script("newlib-nano") endif() + + if(CONFIG_HEAP_ROM_IMPL) + rom_linker_script("heap") + endif() endif() if(CONFIG_IDF_TARGET_ARCH_XTENSA) diff --git a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld index 83262f27b6..ac697b95c3 100644 --- a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld +++ b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld @@ -256,7 +256,7 @@ PROVIDE( multi_heap_get_block_address_impl = 0x40000330 ); PROVIDE( multi_heap_get_allocated_size_impl = 0x40000334 ); PROVIDE( multi_heap_register_impl = 0x40000338 ); PROVIDE( multi_heap_set_lock = 0x4000033c ); -PROVIDE( multi_heap_mutex_init = 0x40000340 ); +PROVIDE( multi_heap_os_funcs_init = 0x40000340 ); PROVIDE( multi_heap_internal_lock = 0x40000344 ); PROVIDE( multi_heap_internal_unlock = 0x40000348 ); PROVIDE( multi_heap_get_first_block = 0x4000034c ); diff --git a/components/heap/CMakeLists.txt b/components/heap/CMakeLists.txt index d22fbaaacd..ceedec32e7 100644 --- a/components/heap/CMakeLists.txt +++ b/components/heap/CMakeLists.txt @@ -1,8 +1,11 @@ set(srcs "heap_caps.c" "heap_caps_init.c" - "multi_heap.c" - "heap_tlsf.c") + "multi_heap.c") + +if(NOT CONFIG_HEAP_ROM_IMPL) + list(APPEND srcs "heap_tlsf.c") +endif() if(NOT CONFIG_HEAP_POISONING_DISABLED) list(APPEND srcs "multi_heap_poisoning.c") diff --git a/components/heap/Kconfig b/components/heap/Kconfig index 5b9dc56189..6fdd0ab40c 100644 --- a/components/heap/Kconfig +++ b/components/heap/Kconfig @@ -71,4 +71,21 @@ menu "Heap memory debugging" help When enabled, if a memory allocation operation fails it will cause a system abort. + config HEAP_HAS_ROM_IMPL + bool + default y if IDF_TARGET_ESP32C2 + + config HEAP_ROM_IMPL + bool "Use heap implementation in ROM" + depends on HEAP_HAS_ROM_IMPL + default y + help + Enable this flag to use heap functions from ROM instead of ESP-IDF. + + If keeping this as "n" in your project, you will have less free IRAM. + If making this as "y" in your project, you will increase free IRAM, + but you will lose the possibility to debug this module, and some new + features will be added and bugs will be fixed in the IDF source + but cannot be synced to ROM. + endmenu diff --git a/components/heap/heap_caps_init.c b/components/heap/heap_caps_init.c index 1b6892bb10..bbefa0482a 100644 --- a/components/heap/heap_caps_init.c +++ b/components/heap/heap_caps_init.c @@ -49,6 +49,10 @@ void heap_caps_enable_nonos_stack_heaps(void) */ void heap_caps_init(void) { +#ifdef CONFIG_HEAP_ROM_IMPL + extern void multi_heap_in_rom_init(void); + multi_heap_in_rom_init(); +#endif /* Get the array of regions that we can use for heaps (with reserved memory removed already.) */ diff --git a/components/heap/heap_tlsf.h b/components/heap/heap_tlsf.h index 58212dbb3c..24768f3055 100644 --- a/components/heap/heap_tlsf.h +++ b/components/heap/heap_tlsf.h @@ -127,6 +127,9 @@ void tlsf_walk_pool(pool_t pool, tlsf_walker walker, void* user); int tlsf_check(tlsf_t tlsf); int tlsf_check_pool(pool_t pool); +/* Used for heap tlsf in ROM IMPL */ +void tlsf_poison_fill_pfunc_set(void *pfunc); + #if defined(__cplusplus) }; #endif diff --git a/components/heap/linker.lf b/components/heap/linker.lf index a2be01e113..31cf88aa9e 100644 --- a/components/heap/linker.lf +++ b/components/heap/linker.lf @@ -1,7 +1,8 @@ [mapping:heap] archive: libheap.a entries: - heap_tlsf (noflash) + if HEAP_HAS_ROM_IMPL = n || HEAP_ROM_IMPL = n: + heap_tlsf (noflash) multi_heap (noflash) if HEAP_POISONING_DISABLED = n: multi_heap_poisoning (noflash) diff --git a/components/heap/multi_heap.c b/components/heap/multi_heap.c index 7ac3bb487b..a4b3997620 100644 --- a/components/heap/multi_heap.c +++ b/components/heap/multi_heap.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,7 +12,7 @@ #include #include #include "heap_tlsf.h" -#include +#include "multi_heap.h" #include "multi_heap_internal.h" /* Note: Keep platform-specific parts in this header, this source @@ -22,7 +22,7 @@ /* Defines compile-time configuration macros */ #include "multi_heap_config.h" -#ifndef MULTI_HEAP_POISONING +#if (!defined MULTI_HEAP_POISONING) && (!defined CONFIG_HEAP_ROM_IMPL) /* if no heap poisoning, public API aliases directly to these implementations */ void *multi_heap_malloc(multi_heap_handle_t heap, size_t size) __attribute__((alias("multi_heap_malloc_impl"))); @@ -77,6 +77,30 @@ typedef struct multi_heap_info { tlsf_t heap_data; } heap_t; +#ifdef CONFIG_HEAP_ROM_IMPL + +void _multi_heap_lock(void *lock) +{ + MULTI_HEAP_LOCK(lock); +} + +void _multi_heap_unlock(void *lock) +{ + MULTI_HEAP_UNLOCK(lock); +} + +multi_heap_os_funcs_t multi_heap_os_funcs = { + .lock = _multi_heap_lock, + .unlock = _multi_heap_unlock, +}; + +void multi_heap_in_rom_init(void) +{ + multi_heap_os_funcs_init(&multi_heap_os_funcs); +} + +#else //#ifndef CONFIG_HEAP_ROM_IMPL + /* Return true if this block is free. */ static inline bool is_free(const block_header_t *block) { @@ -201,7 +225,6 @@ void *multi_heap_malloc_impl(multi_heap_handle_t heap, size_t size) void multi_heap_free_impl(multi_heap_handle_t heap, void *p) { - if (heap == NULL || p == NULL) { return; } @@ -380,3 +403,4 @@ void multi_heap_get_info_impl(multi_heap_handle_t heap, multi_heap_info_t *info) } multi_heap_internal_unlock(heap); } +#endif diff --git a/components/heap/multi_heap_internal.h b/components/heap/multi_heap_internal.h index 5be4dee608..00c1f23e91 100644 --- a/components/heap/multi_heap_internal.h +++ b/components/heap/multi_heap_internal.h @@ -1,18 +1,26 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once +/* Define a structure that contains some function pointers that point to OS-related functions. + An instance of this structure will be provided to the heap in ROM for use if needed. +*/ +typedef struct { + void (*lock)(void *lock); + void (*unlock)(void *lock); +} multi_heap_os_funcs_t; + +/** @brief Initialize structure pointer that points a structure that contains OS-related functions pointers. + * + * @param heap_os_funcs Points to a structure that contains some OS-related function pointers. + * @return None. + * + */ +void multi_heap_os_funcs_init(multi_heap_os_funcs_t *heap_os_funcs); + /* Opaque handle to a heap block */ typedef const struct block_header_t *multi_heap_block_handle_t; diff --git a/components/heap/multi_heap_poisoning.c b/components/heap/multi_heap_poisoning.c index ca27f3f290..31dfc69452 100644 --- a/components/heap/multi_heap_poisoning.c +++ b/components/heap/multi_heap_poisoning.c @@ -1,16 +1,8 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include #include @@ -29,6 +21,8 @@ /* Defines compile-time configuration macros */ #include "multi_heap_config.h" +#include "heap_tlsf.h" + #ifdef MULTI_HEAP_POISONING /* Alias MULTI_HEAP_POISONING_SLOW to SLOW for better readabilty */ @@ -339,6 +333,9 @@ multi_heap_handle_t multi_heap_register(void *start, size_t size) if (start != NULL) { memset(start, FREE_FILL_PATTERN, size); } +#endif +#ifdef CONFIG_HEAP_ROM_IMPL + tlsf_poison_fill_pfunc_set(multi_heap_internal_poison_fill_region); #endif return multi_heap_register_impl(start, size); } diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index b4d095ad1d..f0a7d7fc64 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -946,8 +946,6 @@ components/heap/include/esp_heap_task_info.h components/heap/include/esp_heap_trace.h components/heap/include/heap_memory_layout.h components/heap/multi_heap_config.h -components/heap/multi_heap_internal.h -components/heap/multi_heap_poisoning.c components/heap/test/test_aligned_alloc_caps.c components/heap/test/test_allocator_timings.c components/heap/test/test_diram.c