diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index 6fc7aaa..e1764a5 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -11,7 +11,7 @@ jobs: matrix: idf_ver: ["release-v5.1", "release-v5.2", "release-v5.3"] idf_target: ["esp32", "esp32s3"] - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 container: espressif/idf:${{ matrix.idf_ver }} steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/check_lib_versions.yml b/.github/workflows/check_lib_versions.yml index 9203bbb..3d87de2 100644 --- a/.github/workflows/check_lib_versions.yml +++ b/.github/workflows/check_lib_versions.yml @@ -8,7 +8,7 @@ jobs: check_lib_versions: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Get latest release info of repository id: last_release uses: InsonusK/get-latest-release@v1.1.0 diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 7111ea9..591d102 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -9,6 +9,6 @@ jobs: pre-commit: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 - - uses: pre-commit/action@v2.0.3 + - uses: actions/checkout@v3 + - uses: actions/setup-python@v5.2.0 + - uses: pre-commit/action@v3.0.1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 88c6ad3..efa6ad8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # ChangeLog +## v0.2.1 - 2025-05-30 + +### Enhancements: + +* feat(memory): add C++ global memory allocation +* feat(repo): support compile on PC + ## v0.2.0 - 2025-02-07 ### Enhancements: diff --git a/CMakeLists.txt b/CMakeLists.txt index 523056e..86ee7c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,14 +1,25 @@ set(SRC_DIR ./src) -file(GLOB_RECURSE SRCS ${SRC_DIR}/*.c) +file(GLOB_RECURSE SRCS_C ${SRC_DIR}/*.c) +file(GLOB_RECURSE SRCS_CPP ${SRC_DIR}/*.cpp) -idf_component_register( - SRCS ${SRCS} - INCLUDE_DIRS ${SRC_DIR} -) +if(ESP_PLATFORM) + idf_component_register( + SRCS ${SRCS_C} ${SRCS_CPP} + INCLUDE_DIRS ${SRC_DIR} + ) +else() + set(COMPONENT_LIB esp-lib-utils) + add_library(${COMPONENT_LIB} STATIC ${SRCS_C} ${SRCS_CPP}) + target_include_directories(${COMPONENT_LIB} PUBLIC ${SRC_DIR}) +endif() target_compile_options(${COMPONENT_LIB} PUBLIC -Wno-missing-field-initializers PRIVATE - $<$:-std=gnu++17> + $<$:-std=gnu++20> ) + +if(NOT ESP_PLATFORM) + target_compile_definitions(${COMPONENT_LIB} PUBLIC ESP_UTILS_KCONFIG_IGNORE) +endif() diff --git a/Kconfig b/Kconfig index e6d61c6..f7b9569 100644 --- a/Kconfig +++ b/Kconfig @@ -1,122 +1,214 @@ menu "ESP Library Utils Configurations" config ESP_UTILS_CONF_FILE_SKIP - bool "Unckeck this to use custom `esp_utils_conf.h`" + bool "Enable to skip `esp_utils_conf.h`" default y - - menu "Check functions" - depends on ESP_UTILS_CONF_FILE_SKIP - choice ESP_UTILS_CONF_CHECK_HANDLE_METHOD - prompt "Select handle method when check failed" - default ESP_UTILS_CHECK_HANDLE_WITH_ERROR_LOG - - config ESP_UTILS_CHECK_HANDLE_WITH_NONE - bool "Do nothing" - - config ESP_UTILS_CHECK_HANDLE_WITH_ERROR_LOG - bool "Print error message" - - config ESP_UTILS_CHECK_HANDLE_WITH_ASSERT - bool "Assert" - endchoice - - config ESP_UTILS_CONF_CHECK_HANDLE_METHOD - int - default 0 if ESP_UTILS_CHECK_HANDLE_WITH_NONE - default 1 if ESP_UTILS_CHECK_HANDLE_WITH_ERROR_LOG - default 2 if ESP_UTILS_CHECK_HANDLE_WITH_ASSERT - endmenu - - menu "Log functions" - depends on ESP_UTILS_CONF_FILE_SKIP - - choice ESP_UTILS_CONF_LOG_LEVEL - prompt "Select global log level" - default ESP_UTILS_CONF_LOG_LEVEL_INFO - - config ESP_UTILS_CONF_LOG_LEVEL_DEBUG - bool "Debug" + help + If want to use `esp_utils_conf.h` to configure the library, uncheck this option. Otherwise, the configurations in sdkconfig will be used. + + if ESP_UTILS_CONF_FILE_SKIP + menu "Check functions" + choice ESP_UTILS_CONF_CHECK_HANDLE_METHOD + prompt "Select handle method when check failed" + default ESP_UTILS_CHECK_HANDLE_WITH_ERROR_LOG + + config ESP_UTILS_CHECK_HANDLE_WITH_NONE + bool "Do nothing" + + config ESP_UTILS_CHECK_HANDLE_WITH_ERROR_LOG + bool "Print error message" + + config ESP_UTILS_CHECK_HANDLE_WITH_ASSERT + bool "Assert" + endchoice + + config ESP_UTILS_CONF_CHECK_HANDLE_METHOD + int + default 0 if ESP_UTILS_CHECK_HANDLE_WITH_NONE + default 1 if ESP_UTILS_CHECK_HANDLE_WITH_ERROR_LOG + default 2 if ESP_UTILS_CHECK_HANDLE_WITH_ASSERT + endmenu + + menu "Log functions" + choice ESP_UTILS_CONF_LOG_LEVEL + prompt "Select global log level" + default ESP_UTILS_CONF_LOG_LEVEL_INFO + + config ESP_UTILS_CONF_LOG_LEVEL_DEBUG + bool "Debug" + help + Extra information which is not necessary for normal use (values, pointers, sizes, etc) + + config ESP_UTILS_CONF_LOG_LEVEL_INFO + bool "Info" + help + Information messages which describe the normal flow of events + + config ESP_UTILS_CONF_LOG_LEVEL_WARNING + bool "Warning" + help + Error conditions from which recovery measures have been taken + + config ESP_UTILS_CONF_LOG_LEVEL_ERROR + bool "Error" + help + Critical errors, software module cannot recover on its own + + config ESP_UTILS_CONF_LOG_LEVEL_NONE + bool "None" + help + No log output + endchoice + + config ESP_UTILS_CONF_LOG_LEVEL + int + default 0 if ESP_UTILS_CONF_LOG_LEVEL_DEBUG + default 1 if ESP_UTILS_CONF_LOG_LEVEL_INFO + default 2 if ESP_UTILS_CONF_LOG_LEVEL_WARNING + default 3 if ESP_UTILS_CONF_LOG_LEVEL_ERROR + default 4 if ESP_UTILS_CONF_LOG_LEVEL_NONE + + config ESP_UTILS_CONF_ENABLE_LOG_TRACE + bool "Enable trace function" + depends on ESP_UTILS_CONF_LOG_LEVEL_DEBUG + default n help - Extra information which is not necessary for normal use (values, pointers, sizes, etc) - - config ESP_UTILS_CONF_LOG_LEVEL_INFO - bool "Info" - help - Information messages which describe the normal flow of events - - config ESP_UTILS_CONF_LOG_LEVEL_WARNING - bool "Warning" - help - Error conditions from which recovery measures have been taken - - config ESP_UTILS_CONF_LOG_LEVEL_ERROR - bool "Error" - help - Critical errors, software module cannot recover on its own - - config ESP_UTILS_CONF_LOG_LEVEL_NONE - bool "None" + If enabled, the driver will print trace log messages when enter/exit functions, useful for debugging + endmenu + + menu "Memory functions" + depends on ESP_UTILS_CONF_FILE_SKIP + + menu "C/C++ general allocator" + config ESP_UTILS_CONF_MEM_GEN_ALLOC_DEFAULT_ENABLE + bool "Default enable allocation" + default y + help + If enabled, the driver will use general memory allocation by default, otherwise, the driver will use + the standard `malloc` and `free` by default + + choice ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_CHOICE + prompt "Select allocation type" + default ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_STDLIB + + config ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_STDLIB + bool "Standard (malloc, free)" + + config ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_ESP + bool "ESP (`heap_caps_malloc`, `heap_caps_free`)" + + config ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_MICROPYTHON + bool "MicroPython (`mp_malloc`, `mp_free`)" + + config ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_CUSTOM + bool "Custom (`ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_NEW` and `ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_DELETE`)" + endchoice + + config ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE + int + default 0 if ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_STDLIB + default 1 if ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_ESP + default 2 if ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_MICROPYTHON + default 3 if ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_CUSTOM + + choice ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_CAPS + prompt "ESP memory caps" + depends on ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_ESP + default ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_CAPS_DEFAULT + + config ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_CAPS_DEFAULT + bool "Default" + + config ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_CAPS_SRAM + bool "Internal RAM (SRAM)" + + config ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_CAPS_PSRAM + bool "External RAM (PSRAM)" + endchoice + + config ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_CAPS + int + default 0 if ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_CAPS_DEFAULT + default 1 if ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_CAPS_SRAM + default 2 if ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_CAPS_PSRAM + + config ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_ALIGN + int "ESP memory alignment (bytes)" + depends on ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_ESP + default 1 + range 1 1024 + + config ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_INCLUDE + string "Custom memory header file" + depends on ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_CUSTOM + default "" + endmenu + + menuconfig ESP_UTILS_CONF_MEM_ENABLE_CXX_GLOB_ALLOC + bool "C++ global allocator" + default n help - No log output - endchoice - - config ESP_UTILS_CONF_LOG_LEVEL - int - default 0 if ESP_UTILS_CONF_LOG_LEVEL_DEBUG - default 1 if ESP_UTILS_CONF_LOG_LEVEL_INFO - default 2 if ESP_UTILS_CONF_LOG_LEVEL_WARNING - default 3 if ESP_UTILS_CONF_LOG_LEVEL_ERROR - default 4 if ESP_UTILS_CONF_LOG_LEVEL_NONE - - config ESP_UTILS_CONF_ENABLE_LOG_TRACE - bool "Enable trace function" - depends on ESP_UTILS_CONF_LOG_LEVEL_DEBUG - default n - help - If enabled, the driver will print trace log messages when enter/exit functions, useful for debugging - endmenu - - menu "Memory functions" - depends on ESP_UTILS_CONF_FILE_SKIP - config ESP_UTILS_CONF_MEM_GEN_ALLOC_DEFAULT_ENABLE - bool "Default enable general memory allocation" - default y - help - If enabled, the driver will use general memory allocation by default, otherwise, the driver will use - `malloc` and `free` by default - - choice ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_CHOICE - prompt "Select general allocation type" - default ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_STDLIB - - config ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_STDLIB - bool "Standard library (malloc, free)" - - config ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_ESP - bool "ESP (heap_caps_malloc, free)" - - config ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_MICROPYTHON - bool "MicroPython (mp_malloc, mp_free)" - - config ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_CUSTOM - bool "Custom (`ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_MALLOC` and `ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_FREE`)" - endchoice - - config ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE - int - default 0 if ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_STDLIB - default 1 if ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_ESP - default 2 if ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_MICROPYTHON - default 3 if ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_CUSTOM - - config ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_ALIGN - int "General esp memory alignment (bytes)" - depends on ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_ESP - default 1 - range 1 1024 - - config ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_INCLUDE - string "General custom memory header file" - depends on ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_CUSTOM - default "stdlib.h" - endmenu + If enabled, the driver will override `new` and `delete` operators to use global memory allocator + + if ESP_UTILS_CONF_MEM_ENABLE_CXX_GLOB_ALLOC + config ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_DEFAULT_ENABLE + bool "Default enable allocation" + default y + help + If enabled, the driver will use global memory allocation by default, otherwise, the driver will use + the standard `new` and `delete` by default. + + choice ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE_CHOICE + prompt "Select allocation type" + default ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE_ESP + + config ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE_ESP + bool "ESP (`heap_caps_malloc`, `heap_caps_free`)" + + config ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE_MICROPYTHON + bool "MicroPython (`mp_malloc`, `mp_free`)" + + config ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE_CUSTOM + bool "Custom (`ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_CUSTOM_NEW` and `ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_CUSTOM_DELETE`)" + endchoice + + config ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE + int + default 1 if ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE_ESP + default 2 if ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE_MICROPYTHON + default 3 if ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE_CUSTOM + + choice ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_ESP_CAPS + prompt "ESP memory caps" + depends on ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE_ESP + default ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_ESP_CAPS_DEFAULT + + config ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_ESP_CAPS_DEFAULT + bool "Default" + + config ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_ESP_CAPS_SRAM + bool "Internal RAM (SRAM)" + + config ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_ESP_CAPS_PSRAM + bool "External RAM (PSRAM)" + endchoice + + config ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_ESP_CAPS + int + default 0 if ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_ESP_CAPS_DEFAULT + default 1 if ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_ESP_CAPS_SRAM + default 2 if ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_ESP_CAPS_PSRAM + + config ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_ESP_ALIGN + int "ESP memory alignment (bytes)" + depends on ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE_ESP + default 1 + range 1 1024 + + config ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_CUSTOM_INCLUDE + string "Custom memory header file" + depends on ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE_CUSTOM + default "" + endif # ESP_UTILS_CONF_MEM_ENABLE_CXX_GLOB_ALLOC + endmenu + endif # ESP_UTILS_CONF_FILE_SKIP endmenu diff --git a/esp_utils_conf.h b/esp_utils_conf.h index 4ecc251..f865cfe 100644 --- a/esp_utils_conf.h +++ b/esp_utils_conf.h @@ -34,10 +34,10 @@ #define ESP_UTILS_CONF_LOG_LEVEL (ESP_UTILS_LOG_LEVEL_INFO) #if ESP_UTILS_CONF_LOG_LEVEL == ESP_UTILS_LOG_LEVEL_DEBUG - /** - * @brief Set to 1 if print trace log messages when enter/exit functions, useful for debugging - */ - #define ESP_UTILS_CONF_ENABLE_LOG_TRACE (0) +/** + * @brief Set to 1 if print trace log messages when enter/exit functions, useful for debugging + */ +# define ESP_UTILS_CONF_ENABLE_LOG_TRACE (0) #endif // ESP_UTILS_CONF_LOG_LEVEL @@ -45,50 +45,97 @@ //////////////////////////////////////////////// Memory Configurations ///////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** - * Default enable memory allocation. - * - * If enabled, the driver will use general memory allocation by default, otherwise, the driver will use `malloc` and - * `free` by default + * C/C++ general memory allocation + */ +/** + * If enabled, the driver will use general memory allocation by default, otherwise, the driver will use + * the standard `malloc` and `free` by default */ #define ESP_UTILS_CONF_MEM_GEN_ALLOC_DEFAULT_ENABLE (1) /** - * General Memory allocation type, choose one of the following: + * C/C++ general memory allocation type, choose one of the following: * - ESP_UTILS_MEM_ALLOC_TYPE_STDLIB: Use the standard library memory allocation functions (malloc, free) * - ESP_UTILS_MEM_ALLOC_TYPE_ESP: Use the ESP-IDF memory allocation functions (heap_caps_aligned_alloc, heap_caps_free) * - ESP_UTILS_MEM_ALLOC_TYPE_MICROPYTHON: Use the MicroPython memory allocation functions (m_malloc, m_free) - * - ESP_UTILS_MEM_ALLOC_TYPE_CUSTOM: Use custom memory allocation functions (ESP_UTILS_MEM_ALLOC_CUSTOM_MALLOC, - * ESP_UTILS_MEM_ALLOC_CUSTOM_FREE) + * - ESP_UTILS_MEM_ALLOC_TYPE_CUSTOM: Use custom memory allocation functions (ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_MALLOC, + * ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_FREE) */ #define ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE (ESP_UTILS_MEM_ALLOC_TYPE_STDLIB) #if ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_ESP - #define ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_ALIGN (1) - #define ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_CAPS (MALLOC_CAP_DEFAULT | MALLOC_CAP_8BIT) +/** + * ESP memory caps, choose one of the following: + * - ESP_UTILS_MEM_ALLOC_ESP_CAPS_DEFAULT: Default + * - ESP_UTILS_MEM_ALLOC_ESP_CAPS_SRAM: Internal RAM (SRAM) + * - ESP_UTILS_MEM_ALLOC_ESP_CAPS_PSRAM: External RAM (PSRAM) + */ +# define ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_CAPS (ESP_UTILS_MEM_ALLOC_ESP_CAPS_DEFAULT) +# define ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_ALIGN (1) #elif ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_CUSTOM - #define ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_INCLUDE "stdlib.h" - #define ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_MALLOC malloc - #define ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_FREE free +# define ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_INCLUDE "esp_heap_caps.h" +# define ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_MALLOC(x) heap_caps_aligned_alloc(1, x, MALLOC_CAP_DEFAULT | MALLOC_CAP_8BIT) +# define ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_FREE(x) heap_caps_free(x) #endif // ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE +/** + * C++ global memory allocation + */ +/** + * If enabled, the driver will override `new` and `delete` operators to use global memory allocator + */ +#define ESP_UTILS_CONF_MEM_ENABLE_CXX_GLOB_ALLOC (0) +#if ESP_UTILS_CONF_MEM_ENABLE_CXX_GLOB_ALLOC +/** + * If enabled, the driver will use global memory allocation by default, otherwise, the driver will use + * the standard `malloc` and `free` by default + */ +#define ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_DEFAULT_ENABLE (1) + +/** + * C++ global memory allocation type, choose one of the following: + * - ESP_UTILS_MEM_ALLOC_TYPE_ESP: Use the ESP-IDF memory allocation functions (heap_caps_aligned_alloc, heap_caps_free) + * - ESP_UTILS_MEM_ALLOC_TYPE_MICROPYTHON: Use the MicroPython memory allocation functions (m_malloc, m_free) + * - ESP_UTILS_MEM_ALLOC_TYPE_CUSTOM: Use custom memory allocation functions (ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_CUSTOM_MALLOC, + * ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_CUSTOM_FREE) + */ +#define ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE (ESP_UTILS_MEM_ALLOC_TYPE_ESP) +#if ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_ESP + +/** + * ESP memory caps, choose one of the following: + * - ESP_UTILS_MEM_ALLOC_ESP_CAPS_DEFAULT: Default + * - ESP_UTILS_MEM_ALLOC_ESP_CAPS_SRAM: Internal RAM (SRAM) + * - ESP_UTILS_MEM_ALLOC_ESP_CAPS_PSRAM: External RAM (PSRAM) + */ +# define ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_ESP_CAPS (ESP_UTILS_MEM_ALLOC_ESP_CAPS_DEFAULT) +# define ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_ESP_ALIGN (1) + +#elif ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_CUSTOM + +# define ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_CUSTOM_INCLUDE "esp_heap_caps.h" +# define ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_CUSTOM_NEW(x) heap_caps_aligned_alloc(1, x, MALLOC_CAP_DEFAULT | MALLOC_CAP_8BIT) +# define ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_CUSTOM_DELETE(x) heap_caps_free(x) + +#endif // ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE + +#endif // ESP_UTILS_CONF_MEM_ENABLE_CXX_GLOB_ALLOC + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////// File Version /////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** - * Do not change the following versions, they are used to check if the configurations in this file are compatible with - * the current version of `esp_utils_conf.h` in the library. The detailed rules are as follows: - * - * 1. If the major version is not consistent, then the configurations in this file are incompatible with the library - * and must be replaced with the file from the library. - * 2. If the minor version is not consistent, this file might be missing some new configurations, which will be set to - * default values. It is recommended to replace it with the file from the library. - * 3. Even if the patch version is not consistent, it will not affect normal functionality. + * Do not change the following versions. These version numbers are used to check compatibility between this + * configuration file and the library. Rules for version numbers: + * 1. Major version mismatch: Configurations are incompatible, must use library version + * 2. Minor version mismatch: May be missing new configurations, recommended to update + * 3. Patch version mismatch: No impact on functionality */ #define ESP_UTILS_CONF_FILE_VERSION_MAJOR 1 -#define ESP_UTILS_CONF_FILE_VERSION_MINOR 2 +#define ESP_UTILS_CONF_FILE_VERSION_MINOR 3 #define ESP_UTILS_CONF_FILE_VERSION_PATCH 0 // *INDENT-ON* diff --git a/idf_component.yml b/idf_component.yml index 6baac30..012811b 100644 --- a/idf_component.yml +++ b/idf_component.yml @@ -1,4 +1,4 @@ -version: "0.2.0" +version: "0.2.1" description: esp-lib-utils is a library designed for ESP SoCs to provide utility functions, including logging, checking, and memory. url: https://github.com/esp-arduino-libs/esp-lib-utils repository: https://github.com/esp-arduino-libs/esp-lib-utils.git diff --git a/library.properties b/library.properties index 3543d42..531513f 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=esp-lib-utils -version=0.2.0 +version=0.2.1 author=espressif maintainer=espressif sentence=esp-lib-utils is a library designed for ESP SoCs to provide utility functions, including logging, checking, and memory. diff --git a/micropython.cmake b/micropython.cmake index 095b41e..c65e4d6 100644 --- a/micropython.cmake +++ b/micropython.cmake @@ -21,8 +21,12 @@ target_include_directories(usermod_esp_lib_utils INTERFACE ${SRC_DIR} ${MPY_DIR} # Add compile options. Since the target is not created by `idf_component_register()`, we need to add the `ESP_PLATFORM` define manually. target_compile_options(usermod_esp_lib_utils INTERFACE - -Wno-missing-field-initializers -DESP_PLATFORM $<$:-std=gnu++17> + -Wno-missing-field-initializers -DESP_PLATFORM ) # Link our INTERFACE library to the usermod target. target_link_libraries(usermod INTERFACE usermod_esp_lib_utils) + +# Include core source components. +include(${MICROPY_DIR}/py/py.cmake) +micropy_gather_target_properties(usermod_esp_lib_utils) diff --git a/src/check/esp_utils_check.h b/src/check/esp_utils_check.h index 86f9325..4580b93 100644 --- a/src/check/esp_utils_check.h +++ b/src/check/esp_utils_check.h @@ -3,7 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#if defined(ESP_PLATFORM) #include "esp_err.h" +#endif #include "esp_utils_conf_internal.h" #include "log/esp_utils_log.h" @@ -91,6 +93,7 @@ } \ } while(0) +#if defined(ESP_PLATFORM) /** * @brief Check if the value is not `ESP_OK`; if not, return the specified value. * @@ -132,6 +135,7 @@ return; \ } \ } while(0) +#endif // ESP_PLATFORM /** * The `try {} catch {}` block is only available in C++ and `CONFIG_COMPILER_CXX_EXCEPTIONS = 1` @@ -281,6 +285,7 @@ } \ } while(0) +#if defined(ESP_PLATFORM) /** * @brief Check if the value is not `ESP_OK`; if not, log an error and return the specified value. * @@ -327,6 +332,7 @@ return; \ } \ } while(0) +#endif // ESP_PLATFORM /** * The `try {} catch {}` block is only available in C++ and `CONFIG_COMPILER_CXX_EXCEPTIONS = 1` @@ -408,6 +414,7 @@ } while (0) #define ESP_UTILS_CHECK_FALSE_EXIT(x, ...) assert(x) +#if defined(ESP_PLATFORM) #define ESP_UTILS_CHECK_ERROR_RETURN(x, ...) assert((x) == ESP_OK) #define ESP_UTILS_CHECK_ERROR_GOTO(x, goto_tag, ...) do { \ assert((x) == ESP_OK); \ @@ -417,6 +424,7 @@ } \ } while (0) #define ESP_UTILS_CHECK_ERROR_EXIT(x, ...) assert((x) == ESP_OK) +#endif // ESP_PLATFORM /** * The `try {} catch {}` block is only available in C++ and `CONFIG_COMPILER_CXX_EXCEPTIONS = 1` diff --git a/src/esp_utils_conf_kconfig.h b/src/esp_utils_conf_kconfig.h index 6858ba0..1149133 100644 --- a/src/esp_utils_conf_kconfig.h +++ b/src/esp_utils_conf_kconfig.h @@ -6,98 +6,157 @@ #pragma once -// *INDENT-OFF* - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////// Check Configurations ///////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #ifndef ESP_UTILS_CONF_CHECK_HANDLE_METHOD - #ifdef CONFIG_ESP_UTILS_CONF_CHECK_HANDLE_METHOD - #define ESP_UTILS_CONF_CHECK_HANDLE_METHOD CONFIG_ESP_UTILS_CONF_CHECK_HANDLE_METHOD - #else - #define ESP_UTILS_CONF_CHECK_HANDLE_METHOD (ESP_UTILS_CHECK_HANDLE_WITH_ERROR_LOG) - #endif +# ifdef CONFIG_ESP_UTILS_CONF_CHECK_HANDLE_METHOD +# define ESP_UTILS_CONF_CHECK_HANDLE_METHOD CONFIG_ESP_UTILS_CONF_CHECK_HANDLE_METHOD +# else +# error "Missing configuration: ESP_UTILS_CONF_CHECK_HANDLE_METHOD" +# endif #endif //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////// LOG Configurations ////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #ifndef ESP_UTILS_CONF_LOG_LEVEL - #ifdef CONFIG_ESP_UTILS_CONF_LOG_LEVEL - #define ESP_UTILS_CONF_LOG_LEVEL CONFIG_ESP_UTILS_CONF_LOG_LEVEL - #else - #define ESP_UTILS_CONF_LOG_LEVEL ESP_UTILS_LOG_LEVEL_INFO - #endif -#endif - -#ifndef ESP_UTILS_CONF_ENABLE_LOG_TRACE - #ifdef CONFIG_ESP_UTILS_CONF_ENABLE_LOG_TRACE - #define ESP_UTILS_CONF_ENABLE_LOG_TRACE CONFIG_ESP_UTILS_CONF_ENABLE_LOG_TRACE - #else - #define ESP_UTILS_CONF_ENABLE_LOG_TRACE 0 - #endif +# ifdef CONFIG_ESP_UTILS_CONF_LOG_LEVEL +# define ESP_UTILS_CONF_LOG_LEVEL CONFIG_ESP_UTILS_CONF_LOG_LEVEL +# else +# error "Missing configuration: ESP_UTILS_CONF_LOG_LEVEL" +# endif #endif -#ifndef ESP_UTILS_CONF_LOG_BUFFER_SIZE - #ifdef CONFIG_ESP_UTILS_CONF_LOG_BUFFER_SIZE - #define ESP_UTILS_CONF_LOG_BUFFER_SIZE CONFIG_ESP_UTILS_CONF_LOG_BUFFER_SIZE - #else - #define ESP_UTILS_CONF_LOG_BUFFER_SIZE (256) - #endif +#if ESP_UTILS_CONF_LOG_LEVEL == ESP_UTILS_LOG_LEVEL_DEBUG +# ifndef ESP_UTILS_CONF_ENABLE_LOG_TRACE +# ifdef CONFIG_ESP_UTILS_CONF_ENABLE_LOG_TRACE +# define ESP_UTILS_CONF_ENABLE_LOG_TRACE CONFIG_ESP_UTILS_CONF_ENABLE_LOG_TRACE +# else +# define ESP_UTILS_CONF_ENABLE_LOG_TRACE 0 +# endif +# endif #endif //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////// Memory Configurations ///////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * C/C++ general allocator + */ #ifndef ESP_UTILS_CONF_MEM_GEN_ALLOC_DEFAULT_ENABLE - #ifdef CONFIG_ESP_UTILS_CONF_MEM_GEN_ALLOC_DEFAULT_ENABLE - #define ESP_UTILS_CONF_MEM_GEN_ALLOC_DEFAULT_ENABLE CONFIG_ESP_UTILS_CONF_MEM_GEN_ALLOC_DEFAULT_ENABLE - #else - #define ESP_UTILS_CONF_MEM_GEN_ALLOC_DEFAULT_ENABLE (0) - #endif +# ifdef CONFIG_ESP_UTILS_CONF_MEM_GEN_ALLOC_DEFAULT_ENABLE +# define ESP_UTILS_CONF_MEM_GEN_ALLOC_DEFAULT_ENABLE CONFIG_ESP_UTILS_CONF_MEM_GEN_ALLOC_DEFAULT_ENABLE +# else +# define ESP_UTILS_CONF_MEM_GEN_ALLOC_DEFAULT_ENABLE (0) +# endif #endif #ifndef ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE - #ifdef CONFIG_ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE - #define ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE CONFIG_ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE - #else - #define ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE (ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_STDLIB) - #endif +# ifdef CONFIG_ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE +# define ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE CONFIG_ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE +# else +# error "Missing configuration: ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE" +# endif #endif #if ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_ESP - #ifndef ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_ALIGN - #ifdef CONFIG_ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_ALIGN - #define ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_ALIGN CONFIG_ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_ALIGN - #else - #error "`ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_ALIGN` must be defined when `ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE` \ - is set to `ESP_UTILS_MEM_ALLOC_TYPE_ESP`" - #endif - #endif - - #ifndef ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_CAPS - #error "`ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_CAPS` must be defined when `ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE` is \ - set to `ESP_UTILS_MEM_ALLOC_TYPE_ESP`" - #endif +# ifndef ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_ALIGN +# ifdef CONFIG_ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_ALIGN +# define ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_ALIGN CONFIG_ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_ALIGN +# else +# error "Missing configuration: ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_ALIGN" +# endif +# endif + +# ifndef ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_CAPS +# ifdef CONFIG_ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_CAPS +# define ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_CAPS CONFIG_ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_CAPS +# else +# error "Missing configuration: ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_CAPS" +# endif +# endif + #elif ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_CUSTOM - #ifndef ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_INCLUDE - #ifdef CONFIG_ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_INCLUDE - #define ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_INCLUDE CONFIG_ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_INCLUDE - #else - #error "`ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_INCLUDE` must be defined when \ - `ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE` is set to `ESP_UTILS_MEM_ALLOC_TYPE_CUSTOM`" - #endif - #endif - - #ifndef ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_MALLOC - #error "`ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_MALLOC` must be defined when `ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE` \ - is set to `ESP_UTILS_MEM_ALLOC_TYPE_CUSTOM`" - #endif - - #ifndef ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_FREE - #error "`ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_FREE` must be defined when `ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE` \ - is set to `ESP_UTILS_MEM_ALLOC_TYPE_CUSTOM`" - #endif + +# ifndef ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_INCLUDE +# ifdef CONFIG_ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_INCLUDE +# define ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_INCLUDE CONFIG_ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_INCLUDE +# else +# error "Missing configuration: ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_INCLUDE" +# endif +# endif + +# ifndef ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_MALLOC +# error "`ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_MALLOC` must be defined when using C/C++ custom general allocator" +# endif + +# ifndef ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_FREE +# error "`ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_FREE` must be defined when using C/C++ custom general allocator" +# endif +#endif + +/** + * C++ global allocator + */ +#ifndef ESP_UTILS_CONF_MEM_ENABLE_CXX_GLOB_ALLOC +# ifdef CONFIG_ESP_UTILS_CONF_MEM_ENABLE_CXX_GLOB_ALLOC +# define ESP_UTILS_CONF_MEM_ENABLE_CXX_GLOB_ALLOC CONFIG_ESP_UTILS_CONF_MEM_ENABLE_CXX_GLOB_ALLOC +# else +# define ESP_UTILS_CONF_MEM_ENABLE_CXX_GLOB_ALLOC (0) +# endif #endif -// *INDENT-ON* +#if ESP_UTILS_CONF_MEM_ENABLE_CXX_GLOB_ALLOC +# ifndef ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_DEFAULT_ENABLE +# ifdef CONFIG_ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_DEFAULT_ENABLE +# define ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_DEFAULT_ENABLE CONFIG_ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_DEFAULT_ENABLE +# else +# define ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_DEFAULT_ENABLE (0) +# endif +# endif + +# ifndef ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE +# ifdef CONFIG_ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE +# define ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE CONFIG_ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE +# else +# error "Missing configuration: ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE" +# endif +# endif + +# if ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_ESP +# ifndef ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_ESP_ALIGN +# ifdef CONFIG_ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_ESP_ALIGN +# define ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_ESP_ALIGN CONFIG_ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_ESP_ALIGN +# else +# error "Missing configuration: ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_ESP_ALIGN" +# endif +# endif + +# ifndef ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_ESP_CAPS +# ifdef CONFIG_ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_ESP_CAPS +# define ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_ESP_CAPS CONFIG_ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_ESP_CAPS +# else +# error "Missing configuration: ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_ESP_CAPS" +# endif +# endif + +# elif ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_CUSTOM + +# ifndef ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_CUSTOM_INCLUDE +# ifdef CONFIG_ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_CUSTOM_INCLUDE +# define ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_CUSTOM_INCLUDE CONFIG_ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_CUSTOM_INCLUDE +# else +# error "Missing configuration: ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_CUSTOM_INCLUDE" +# endif +# endif + +# ifndef ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_CUSTOM_NEW +# error "`ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_CUSTOM_NEW` must be defined when using C++ custom global allocator" +# endif + +# ifndef ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_CUSTOM_DELETE +# error "`ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_CUSTOM_DELETE` must be defined when using C++ custom global allocator" +# endif +# endif +#endif diff --git a/src/esp_utils_types.h b/src/esp_utils_types.h index feadb6b..1ebbf84 100644 --- a/src/esp_utils_types.h +++ b/src/esp_utils_types.h @@ -6,8 +6,6 @@ #pragma once -#include "sdkconfig.h" - /** * @brief Macros for check handle method */ @@ -28,7 +26,14 @@ /** * @brief Macros for memory type */ -#define ESP_UTILS_MEM_ALLOC_TYPE_STDLIB (0) -#define ESP_UTILS_MEM_ALLOC_TYPE_ESP (1) -#define ESP_UTILS_MEM_ALLOC_TYPE_MICROPYTHON (2) -#define ESP_UTILS_MEM_ALLOC_TYPE_CUSTOM (3) +#define ESP_UTILS_MEM_ALLOC_TYPE_STDLIB (0) +#define ESP_UTILS_MEM_ALLOC_TYPE_ESP (1) +#define ESP_UTILS_MEM_ALLOC_TYPE_MICROPYTHON (2) +#define ESP_UTILS_MEM_ALLOC_TYPE_CUSTOM (3) + +/** + * @brief Macros for ESP memory caps + */ +#define ESP_UTILS_MEM_ALLOC_ESP_CAPS_DEFAULT (0) +#define ESP_UTILS_MEM_ALLOC_ESP_CAPS_SRAM (1) +#define ESP_UTILS_MEM_ALLOC_ESP_CAPS_PSRAM (2) diff --git a/src/esp_utils_versions.h b/src/esp_utils_versions.h index 24d8dcc..aaf197a 100644 --- a/src/esp_utils_versions.h +++ b/src/esp_utils_versions.h @@ -8,9 +8,9 @@ /* Library Version */ #define ESP_UTILS_VERSION_MAJOR 0 #define ESP_UTILS_VERSION_MINOR 2 -#define ESP_UTILS_VERSION_PATCH 0 +#define ESP_UTILS_VERSION_PATCH 1 /* File `esp_utils_conf.h` */ #define ESP_UTILS_CONF_VERSION_MAJOR 1 -#define ESP_UTILS_CONF_VERSION_MINOR 2 +#define ESP_UTILS_CONF_VERSION_MINOR 3 #define ESP_UTILS_CONF_VERSION_PATCH 0 diff --git a/src/log/esp_utils_log.h b/src/log/esp_utils_log.h index 4e9573b..6737b95 100644 --- a/src/log/esp_utils_log.h +++ b/src/log/esp_utils_log.h @@ -5,104 +5,14 @@ */ #pragma once +#include +#include #include "esp_utils_conf_internal.h" #ifndef ESP_UTILS_LOG_TAG #define ESP_UTILS_LOG_TAG "Utils" #endif -// #include -// #include -// #include -// #include -// #include - -// extern "C" const char *esp_utils_log_extract_file_name(const char *file_path); - -// namespace esp_utils { - -// /** -// * Class to handle logging -// */ -// class Log { -// public: -// // Singleton pattern: Get the unique instance of the class -// static Log &getInstance() -// { -// static Log instance; -// return instance; -// } - -// // Templates and conditional compilation: Filter logs by different levels -// template -// void print(const char *file, int line, const char *func, const char *format, ...) -// { -// // Logs below the global level will not be compiled -// if constexpr (level >= ESP_UTILS_CONF_LOG_LEVEL) { -// // Mutex to avoid interleaved log messages -// std::lock_guard lock(_mutex); -// // Use variadic arguments for formatted output -// va_list args; -// va_start(args, format); -// vsnprintf(_buffer, sizeof(_buffer), format, args); -// va_end(args); -// // Output log message -// printf( -// "[%c][%s][%s:%04d](%s): %s\n", logLevelToChar(level), ESP_UTILS_LOG_TAG, -// esp_utils_log_extract_file_name(file), line, func, _buffer -// ); -// } -// } - -// private: -// Log() = default; - -// // Convert log level to string -// static constexpr char logLevelToChar(int level) -// { -// switch (level) { -// case ESP_UTILS_LOG_LEVEL_DEBUG: return 'D'; -// case ESP_UTILS_LOG_LEVEL_INFO: return 'I'; -// case ESP_UTILS_LOG_LEVEL_WARNING: return 'W'; -// case ESP_UTILS_LOG_LEVEL_ERROR: return 'E'; -// default: break; -// } -// return ' '; -// } - -// char _buffer[ESP_UTILS_CONF_LOG_BUFFER_SIZE]; -// std::mutex _mutex; -// }; - -// } // namespace esp_utils - -/** - * Macros to simplify logging calls - */ -/* -#define ESP_UTILS_LOGD(format, ...) \ - esp_utils::Log::getInstance().print(__FILE__, __LINE__, __func__, format, ##__VA_ARGS__) -#define ESP_UTILS_LOGI(format, ...) \ - esp_utils::Log::getInstance().print(__FILE__, __LINE__, __func__, format, ##__VA_ARGS__) -#define ESP_UTILS_LOGW(format, ...) \ - esp_utils::Log::getInstance().print(__FILE__, __LINE__, __func__, format, ##__VA_ARGS__) -#define ESP_UTILS_LOGE(format, ...) \ - esp_utils::Log::getInstance().print(__FILE__, __LINE__, __func__, format, ##__VA_ARGS__) -*/ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -const char *esp_utils_log_extract_file_name(const char *file_path); - -#ifdef __cplusplus -} -#endif - #define ESP_UTILS_IMPL_LOGD(format, ...) printf("[D][" ESP_UTILS_LOG_TAG "][%s:%04d](%s): " format "\n", \ esp_utils_log_extract_file_name(__FILE__), __LINE__, __func__, ##__VA_ARGS__) #define ESP_UTILS_IMPL_LOGI(format, ...) printf("[I][" ESP_UTILS_LOG_TAG "][%s:%04d](%s): " format "\n", \ @@ -136,18 +46,28 @@ const char *esp_utils_log_extract_file_name(const char *file_path); * Micros to log trace of function calls */ #if ESP_UTILS_CONF_ENABLE_LOG_TRACE -#define ESP_UTILS_LOG_TRACE_ENTER() ESP_UTILS_LOGD("Enter") -#define ESP_UTILS_LOG_TRACE_EXIT() ESP_UTILS_LOGD("Exit") +# define ESP_UTILS_LOG_TRACE_ENTER() ESP_UTILS_LOGD("Enter") +# define ESP_UTILS_LOG_TRACE_EXIT() ESP_UTILS_LOGD("Exit") #else -#define ESP_UTILS_LOG_TRACE_ENTER() -#define ESP_UTILS_LOG_TRACE_EXIT() +# define ESP_UTILS_LOG_TRACE_ENTER() +# define ESP_UTILS_LOG_TRACE_EXIT() #endif #ifdef __cplusplus -#if ESP_UTILS_CONF_ENABLE_LOG_TRACE -#define ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS() ESP_UTILS_LOGD("(@%p) Enter", this) -#define ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS() ESP_UTILS_LOGD("(@%p) Exit", this) -#else -#define ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS() -#define ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS() +# if ESP_UTILS_CONF_ENABLE_LOG_TRACE +# define ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS() ESP_UTILS_LOGD("(@%p) Enter", this) +# define ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS() ESP_UTILS_LOGD("(@%p) Exit", this) +# else +# define ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS() +# define ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS() +# endif +#endif + +#ifdef __cplusplus +extern "C" { #endif + +const char *esp_utils_log_extract_file_name(const char *file_path); + +#ifdef __cplusplus +} #endif diff --git a/src/log/esp_utils_log_disable.h b/src/log/esp_utils_log_disable.h new file mode 100644 index 0000000..0bfefff --- /dev/null +++ b/src/log/esp_utils_log_disable.h @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +/** + * Disable logging tag + */ +#undef ESP_UTILS_LOG_TAG + +/** + * Disable logging macros + */ +#undef ESP_UTILS_LOGD +#undef ESP_UTILS_LOGI +#undef ESP_UTILS_LOGW +#undef ESP_UTILS_LOGE + +/** + * Disable logging trace macros + */ +#undef ESP_UTILS_LOG_TRACE_ENTER +#undef ESP_UTILS_LOG_TRACE_EXIT +#undef ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS +#undef ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS diff --git a/src/memory/allocation/esp_utils_mem_esp.h b/src/memory/allocation/esp_utils_mem_esp.h new file mode 100644 index 0000000..adc8041 --- /dev/null +++ b/src/memory/allocation/esp_utils_mem_esp.h @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#if defined(ESP_PLATFORM) + +#include "esp_heap_caps.h" + +#if ESP_UTILS_MEM_ALLOC_ESP_CAPS == ESP_UTILS_MEM_ALLOC_ESP_CAPS_DEFAULT +# define MEM_CAPS MALLOC_CAP_DEFAULT +#elif ESP_UTILS_MEM_ALLOC_ESP_CAPS == ESP_UTILS_MEM_ALLOC_ESP_CAPS_SRAM +# define MEM_CAPS MALLOC_CAP_INTERNAL +#elif ESP_UTILS_MEM_ALLOC_ESP_CAPS == ESP_UTILS_MEM_ALLOC_ESP_CAPS_PSRAM +# define MEM_CAPS MALLOC_CAP_SPIRAM +#else +# error "Invalid ESP memory caps" +#endif + +#if !defined(ESP_UTILS_MEM_ALLOC_ESP_ALIGN) +# error "Invalid ESP memory alignment" +#endif + +#define MALLOC(x) heap_caps_aligned_alloc(ESP_UTILS_MEM_ALLOC_ESP_ALIGN, x, MEM_CAPS) +#define FREE(x) heap_caps_free(x) + +#endif // ESP_PLATFORM diff --git a/src/memory/allocation/esp_utils_mem_mpy.h b/src/memory/allocation/esp_utils_mem_mpy.h new file mode 100644 index 0000000..1b48039 --- /dev/null +++ b/src/memory/allocation/esp_utils_mem_mpy.h @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "py/mpconfig.h" +#include "py/misc.h" +#include "py/gc.h" + +#define MALLOC(x) gc_malloc(x) +#define FREE(x) gc_free(x) diff --git a/src/memory/allocation/esp_utils_mem_std.h b/src/memory/allocation/esp_utils_mem_std.h new file mode 100644 index 0000000..b108acc --- /dev/null +++ b/src/memory/allocation/esp_utils_mem_std.h @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include + +#define MALLOC(x) malloc(x) +#define FREE(x) free(x) diff --git a/src/memory/esp_utils_mem.c b/src/memory/esp_utils_mem.c index 1edab70..0f0735b 100644 --- a/src/memory/esp_utils_mem.c +++ b/src/memory/esp_utils_mem.c @@ -1,120 +1,19 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ -#include -#include -#include +#if defined(ESP_PLATFORM) + #include "esp_heap_caps.h" -#include "esp_utils_conf_internal.h" #include "check/esp_utils_check.h" #include "log/esp_utils_log.h" -#if ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_ESP -#include "esp_heap_caps.h" -#elif ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_CUSTOM -#include ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_INCLUDE -#elif ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_MICROPYTHON -#include -#include -#include -#endif // ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE +#include "esp_utils_mem.h" #define PRINT_INFO_BUFFER_SIZE 256 -static bool is_alloc_enabled = ESP_UTILS_CONF_MEM_GEN_ALLOC_DEFAULT_ENABLE; - -void esp_utils_mem_gen_enable_alloc(bool enable) -{ - is_alloc_enabled = enable; -} - -bool esp_utils_mem_check_alloc_enabled(void) -{ - return is_alloc_enabled; -} - -void *esp_utils_mem_gen_malloc(size_t size) -{ - ESP_UTILS_LOG_TRACE_ENTER(); - - void *p = NULL; - - if (!is_alloc_enabled) { - p = malloc(size); - goto end; - } - -#if ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_STDLIB - p = malloc(size); -#elif ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_ESP - p = heap_caps_aligned_alloc(ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_ALIGN, size, ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_CAPS); -#elif ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_CUSTOM - p = ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_MALLOC(size); -#elif ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_MICROPYTHON -#if MICROPY_MALLOC_USES_ALLOCATED_SIZE - p = gc_alloc(size, true); -#else - p = m_malloc(size); -#endif // MICROPY_MALLOC_USES_ALLOCATED_SIZE -#endif // ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE - -end: - ESP_UTILS_LOGD("Malloc @%p: %d", p, (int)size); - - ESP_UTILS_LOG_TRACE_EXIT(); - - return p; -} - -void esp_utils_mem_gen_free(void *p) -{ - ESP_UTILS_LOG_TRACE_ENTER(); - - ESP_UTILS_LOGD("Free @%p", p); - - if (!is_alloc_enabled) { - free(p); - goto end; - } - -#if ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_STDLIB - free(p); -#elif ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_ESP - heap_caps_free(p); -#elif ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_CUSTOM - ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_FREE(p); -#elif ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_MICROPYTHON -#if MICROPY_MALLOC_USES_ALLOCATED_SIZE - gc_free(p); -#else - m_free(p); -#endif // MICROPY_MALLOC_USES_ALLOCATED_SIZE -#endif // ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE - -end: - ESP_UTILS_LOG_TRACE_EXIT(); -} - -void *esp_utils_mem_gen_calloc(size_t n, size_t size) -{ - ESP_UTILS_LOG_TRACE_ENTER(); - - size_t total_size = (size_t)n * size; - void *p = esp_utils_mem_gen_malloc(total_size); - if (p != NULL) { - memset(p, 0, total_size); - } - - ESP_UTILS_LOG_TRACE_EXIT(); - - return p; -} - bool esp_utils_mem_print_info(void) { - ESP_UTILS_LOG_TRACE_ENTER(); - char *buffer = esp_utils_mem_gen_calloc(1, PRINT_INFO_BUFFER_SIZE); ESP_UTILS_CHECK_NULL_RETURN(buffer, false, "Allocate buffer failed"); @@ -133,7 +32,7 @@ bool esp_utils_mem_print_info(void) esp_utils_mem_gen_free(buffer); - ESP_UTILS_LOG_TRACE_EXIT(); - return true; } + +#endif // ESP_PLATFORM diff --git a/src/memory/esp_utils_mem.h b/src/memory/esp_utils_mem.h index 9a60b73..e5ea74f 100644 --- a/src/memory/esp_utils_mem.h +++ b/src/memory/esp_utils_mem.h @@ -7,97 +7,29 @@ #include #include -#include "sdkconfig.h" -#include "esp_utils_conf_internal.h" - +#include "esp_utils_mem_general.h" +#include "esp_utils_mem_cxx_global.h" #ifdef __cplusplus +#include "esp_utils_mem_cxx_general.hpp" + extern "C" { #endif -void esp_utils_mem_gen_enable_alloc(bool enable); -void *esp_utils_mem_gen_malloc(size_t size); -void esp_utils_mem_gen_free(void *p); -void *esp_utils_mem_gen_calloc(size_t n, size_t size); +#if defined(ESP_PLATFORM) + +/** + * @brief Print memory information to the console + * + * This function prints the current memory usage information including: + * - SRAM: Biggest free block, total free size, and total size + * - PSRAM: Biggest free block, total free size, and total size + * + * @return true if the memory information was successfully printed, false otherwise + */ bool esp_utils_mem_print_info(void); -#ifdef __cplusplus -} -#endif +#endif // ESP_PLATFORM #ifdef __cplusplus - -#include -#include -#include -#include - -namespace esp_utils { - -template -struct GeneralMemoryAllocator { - using value_type = T; - - GeneralMemoryAllocator() = default; - - template - GeneralMemoryAllocator(const GeneralMemoryAllocator &) {} - - bool operator!=(const GeneralMemoryAllocator &other) const - { - return false; - } - - T *allocate(std::size_t n) - { - if (n == 0) { - return nullptr; - } - void *ptr = esp_utils_mem_gen_malloc(n * sizeof(T)); - if (ptr == nullptr) { -#if CONFIG_COMPILER_CXX_EXCEPTIONS - throw std::bad_alloc(); -#else - abort(); -#endif // CONFIG_COMPILER_CXX_EXCEPTIONS - } - return static_cast(ptr); - } - - void deallocate(T *p, std::size_t n) - { - esp_utils_mem_gen_free(p); - } - - template - void construct(U *p, Args &&... args) - { - new (p) U(std::forward(args)...); - } - - template - void destroy(U *p) - { - p->~U(); - } - - template - struct rebind { - using other = GeneralMemoryAllocator; - }; -}; - -template -bool operator==(const GeneralMemoryAllocator &, const GeneralMemoryAllocator &) -{ - return true; -} - -template -bool operator!=(const GeneralMemoryAllocator &, const GeneralMemoryAllocator &) -{ - return false; } - -} // namespace esp_utils - -#endif // __cplusplus +#endif diff --git a/src/memory/esp_utils_mem_cxx_general.hpp b/src/memory/esp_utils_mem_cxx_general.hpp new file mode 100644 index 0000000..6b89485 --- /dev/null +++ b/src/memory/esp_utils_mem_cxx_general.hpp @@ -0,0 +1,80 @@ +/* + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include +#include +#include "esp_utils_conf_internal.h" +#include "esp_utils_mem_general.h" + +namespace esp_utils { + +template +struct GeneralMemoryAllocator { + using value_type = T; + + GeneralMemoryAllocator() = default; + + template + GeneralMemoryAllocator(const GeneralMemoryAllocator &) {} + + bool operator!=(const GeneralMemoryAllocator &other) const + { + return false; + } + + T *allocate(std::size_t n) + { + if (n == 0) { + return nullptr; + } + void *ptr = esp_utils_mem_gen_malloc(n * sizeof(T)); +#if !defined(ESP_PLATFORM) || CONFIG_COMPILER_CXX_EXCEPTIONS + if (ptr == nullptr) { + throw std::bad_alloc(); + } +#endif + return static_cast(ptr); + } + + void deallocate(T *p, std::size_t n) + { + esp_utils_mem_gen_free(p); + } + + template + void construct(U *p, Args &&... args) + { + new (p) U(std::forward(args)...); + } + + template + void destroy(U *p) + { + p->~U(); + } + + template + struct rebind { + using other = GeneralMemoryAllocator; + }; +}; + +template +bool operator==(const GeneralMemoryAllocator &, const GeneralMemoryAllocator &) +{ + return true; +} + +template +bool operator!=(const GeneralMemoryAllocator &, const GeneralMemoryAllocator &) +{ + return false; +} + +} // namespace esp_utils diff --git a/src/memory/esp_utils_mem_cxx_global.cpp b/src/memory/esp_utils_mem_cxx_global.cpp new file mode 100644 index 0000000..72dadf1 --- /dev/null +++ b/src/memory/esp_utils_mem_cxx_global.cpp @@ -0,0 +1,114 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "esp_utils_conf_internal.h" +#if ESP_UTILS_CONF_MEM_ENABLE_CXX_GLOB_ALLOC +#include +#include +#if ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_ESP +# define ESP_UTILS_MEM_ALLOC_ESP_ALIGN ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_ESP_ALIGN +# define ESP_UTILS_MEM_ALLOC_ESP_CAPS ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_ESP_CAPS +# include "allocation/esp_utils_mem_esp.h" +#elif ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_CUSTOM +# include ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_CUSTOM_INCLUDE +# define MALLOC(x) ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_CUSTOM_NEW(x) +# define FREE(x) ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_CUSTOM_DELETE(x) +#elif ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_MICROPYTHON +# include "allocation/esp_utils_mem_mpy.h" +#endif // ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE + +static std::atomic is_alloc_enabled = ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_DEFAULT_ENABLE; + +void *operator new (std::size_t size) +{ + void *ptr = NULL; + + if (!is_alloc_enabled) { + ptr = ::malloc(size); + goto end; + } + + ptr = MALLOC(size); +#if !defined(ESP_PLATFORM) || CONFIG_COMPILER_CXX_EXCEPTIONS + if (!ptr) { + throw std::bad_alloc(); + } +#endif + +end: + return ptr; +} + +void *operator new[](std::size_t size) +{ + void *ptr = NULL; + + if (!is_alloc_enabled) { + ptr = ::malloc(size); + goto end; + } + + ptr = MALLOC(size); +#if !defined(ESP_PLATFORM) || CONFIG_COMPILER_CXX_EXCEPTIONS + if (!ptr) { + throw std::bad_alloc(); + } +#endif + +end: + return ptr; +} + +void operator delete (void *ptr) noexcept +{ + if (!is_alloc_enabled) { + ::free(ptr); + return; + } + + FREE(ptr); +} + +void operator delete[](void *ptr) noexcept +{ + if (!is_alloc_enabled) { + ::free(ptr); + return; + } + + FREE(ptr); +} + +void operator delete (void *ptr, std::size_t size) noexcept +{ + if (!is_alloc_enabled) { + ::free(ptr); + return; + } + + FREE(ptr); +} + +void operator delete[](void *ptr, std::size_t size) noexcept +{ + if (!is_alloc_enabled) { + ::free(ptr); + return; + } + + FREE(ptr); +} + +void esp_utils_mem_cxx_glob_enable_alloc(bool enable) +{ + is_alloc_enabled = enable; +} + +bool esp_utils_mem_cxx_glob_check_alloc_enabled(void) +{ + return is_alloc_enabled; +} + +#endif // ESP_UTILS_CONF_MEM_ENABLE_CXX_GLOB_ALLOC diff --git a/src/memory/esp_utils_mem_cxx_global.h b/src/memory/esp_utils_mem_cxx_global.h new file mode 100644 index 0000000..aa96952 --- /dev/null +++ b/src/memory/esp_utils_mem_cxx_global.h @@ -0,0 +1,35 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "esp_utils_conf_internal.h" + +#if ESP_UTILS_CONF_MEM_ENABLE_CXX_GLOB_ALLOC + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enable or disable the global C++ memory allocator + * + * @param[in] enable true to enable, false to disable + */ +void esp_utils_mem_cxx_glob_enable_alloc(bool enable); + +/** + * @brief Check if the global C++ memory allocator is enabled + * + * @return true if enabled, false otherwise + */ +bool esp_utils_mem_cxx_glob_check_alloc_enabled(void); + +#ifdef __cplusplus +} +#endif + +#endif // ESP_UTILS_CONF_MEM_ENABLE_CXX_GLOB_ALLOC diff --git a/src/memory/esp_utils_mem_general.c b/src/memory/esp_utils_mem_general.c new file mode 100644 index 0000000..3786103 --- /dev/null +++ b/src/memory/esp_utils_mem_general.c @@ -0,0 +1,68 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include "esp_utils_conf_internal.h" +#if ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_STD +# include "allocation/esp_utils_mem_std.h" +#elif ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_ESP +# define ESP_UTILS_MEM_ALLOC_ESP_ALIGN ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_ALIGN +# define ESP_UTILS_MEM_ALLOC_ESP_CAPS ESP_UTILS_CONF_MEM_GEN_ALLOC_ESP_CAPS +# include "allocation/esp_utils_mem_esp.h" +#elif ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_CUSTOM +# include ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_INCLUDE +# define MALLOC(x) ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_MALLOC(x) +# define FREE(x) ESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_FREE(x) +#elif ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE == ESP_UTILS_MEM_ALLOC_TYPE_MICROPYTHON +# include "allocation/esp_utils_mem_mpy.h" +#endif + +static bool is_alloc_enabled = ESP_UTILS_CONF_MEM_GEN_ALLOC_DEFAULT_ENABLE; + +void esp_utils_mem_gen_enable_alloc(bool enable) +{ + is_alloc_enabled = enable; +} + +bool esp_utils_mem_gen_check_alloc_enabled(void) +{ + return is_alloc_enabled; +} + +void *esp_utils_mem_gen_malloc(size_t size) +{ + void *p = NULL; + + if (!is_alloc_enabled) { + p = malloc(size); + goto end; + } + + p = MALLOC(size); + +end: + return p; +} + +void esp_utils_mem_gen_free(void *p) +{ + if (!is_alloc_enabled) { + free(p); + return; + } + FREE(p); +} + +void *esp_utils_mem_gen_calloc(size_t n, size_t size) +{ + size_t total_size = (size_t)n * size; + void *p = esp_utils_mem_gen_malloc(total_size); + if (p != NULL) { + memset(p, 0, total_size); + } + return p; +} diff --git a/src/memory/esp_utils_mem_general.h b/src/memory/esp_utils_mem_general.h new file mode 100644 index 0000000..1137e26 --- /dev/null +++ b/src/memory/esp_utils_mem_general.h @@ -0,0 +1,56 @@ +/* + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enable or disable the general memory allocator + * + * @param[in] enable true to enable, false to disable + */ +void esp_utils_mem_gen_enable_alloc(bool enable); + +/** + * @brief Check if the general memory allocator is enabled + * + * @param[in] size Size parameter (used for compatibility with allocation functions) + * @return void* Pointer to indicate allocation status + */ +void *esp_utils_mem_gen_check_alloc_enabled(size_t size); + +/** + * @brief Allocate memory using the general memory allocator + * + * @param[in] size Size of memory to allocate in bytes + * @return void* Pointer to allocated memory or NULL if allocation fails + */ +void *esp_utils_mem_gen_malloc(size_t size); + +/** + * @brief Free memory allocated by the general memory allocator + * + * @param[in] p Pointer to memory to free + */ +void esp_utils_mem_gen_free(void *p); + +/** + * @brief Allocate and zero-initialize memory using the general memory allocator + * + * @param[in] n Number of elements to allocate + * @param[in] size Size of each element in bytes + * @return void* Pointer to allocated memory or NULL if allocation fails + */ +void *esp_utils_mem_gen_calloc(size_t n, size_t size); + +#ifdef __cplusplus +} +#endif diff --git a/test_apps/main/CMakeLists.txt b/test_apps/main/CMakeLists.txt index c669e28..5c0482c 100644 --- a/test_apps/main/CMakeLists.txt +++ b/test_apps/main/CMakeLists.txt @@ -3,41 +3,59 @@ idf_component_register( WHOLE_ARCHIVE ) -idf_build_get_property(build_components BUILD_COMPONENTS) -foreach(COMPONENT ${build_components}) - if(COMPONENT MATCHES "esp-lib-utils" OR COMPONENT MATCHES "espressif__esp-lib-utils") - set(TARGET_COMPONENT ${COMPONENT}) - break() - endif() -endforeach() - -if(TARGET_COMPONENT STREQUAL "") - message(FATAL_ERROR "Component 'esp-lib-utils' not found.") -else() - idf_component_get_property(ESP_LIB_UTILS_LIB ${TARGET_COMPONENT} COMPONENT_LIB) +# Function to get component library +function(get_component_library component_name output_var) + # Get the exact component name + idf_build_get_property(build_components BUILD_COMPONENTS) set(TARGET_COMPONENT "") -endif() + foreach(COMPONENT ${build_components}) + if(COMPONENT MATCHES "${component_name}" OR COMPONENT MATCHES "espressif__${component_name}") + set(TARGET_COMPONENT ${COMPONENT}) + break() + endif() + endforeach() -if(CONFIG_ESP_UTILS_CONF_MEM_GENERAL_ALLOC_TYPE_ESP) + # Get the component library + if(TARGET_COMPONENT STREQUAL "") + message(FATAL_ERROR "Component '${component_name}' not found.") + else() + idf_component_get_property(COMPONENT_LIB ${TARGET_COMPONENT} COMPONENT_LIB) + set(${output_var} ${COMPONENT_LIB} PARENT_SCOPE) + endif() +endfunction() + +get_component_library("esp-lib-utils" ESP_LIB_UTILS_LIB) +if(CONFIG_ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_CUSTOM) + target_compile_options( + ${ESP_LIB_UTILS_LIB} + PUBLIC + "-DESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_INCLUDE=\"esp_heap_caps.h\"" + ) target_compile_options( ${ESP_LIB_UTILS_LIB} PUBLIC - "-DESP_UTILS_CONF_MEM_GENERAL_ALLOC_ESP_CAPS=(MALLOC_CAP_DEFAULT | MALLOC_CAP_8BIT)" + "-DESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_MALLOC(x)=heap_caps_aligned_alloc(1, x, MALLOC_CAP_DEFAULT | MALLOC_CAP_8BIT)" ) -elseif(CONFIG_ESP_UTILS_CONF_MEM_GENERAL_ALLOC_TYPE_CUSTOM) target_compile_options( ${ESP_LIB_UTILS_LIB} PUBLIC - "-DESP_UTILS_CONF_MEM_GENERAL_ALLOC_CUSTOM_INCLUDE=\"esp_heap_caps.h\"" + "-DESP_UTILS_CONF_MEM_GEN_ALLOC_CUSTOM_FREE(x)=heap_caps_free(x)" + ) +endif() +if(CONFIG_ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE_CUSTOM) + target_compile_options( + ${ESP_LIB_UTILS_LIB} + PUBLIC + "-DESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_CUSTOM_INCLUDE=\"esp_heap_caps.h\"" ) target_compile_options( ${ESP_LIB_UTILS_LIB} PUBLIC - "-DESP_UTILS_CONF_MEM_GENERAL_ALLOC_CUSTOM_MALLOC(x)=heap_caps_aligned_alloc(1, x, MALLOC_CAP_DEFAULT | MALLOC_CAP_8BIT)" + "-DESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_CUSTOM_NEW(x)=heap_caps_aligned_alloc(1, x, MALLOC_CAP_DEFAULT | MALLOC_CAP_8BIT)" ) target_compile_options( ${ESP_LIB_UTILS_LIB} PUBLIC - "-DESP_UTILS_CONF_MEM_GENERAL_ALLOC_CUSTOM_FREE(x)=heap_caps_free(x)" + "-DESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_CUSTOM_DELETE(x)=heap_caps_free(x)" ) endif() diff --git a/test_apps/main/test_on_cpp.cpp b/test_apps/main/test_on_cpp.cpp index c84c6e2..1222350 100644 --- a/test_apps/main/test_on_cpp.cpp +++ b/test_apps/main/test_on_cpp.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 */ @@ -9,6 +9,8 @@ #include "esp_lib_utils.h" #include "esp_utils_helpers.h" +using namespace std; + TEST_CASE("Test log functions on cpp", "[utils][log][CPP]") { ESP_UTILS_LOG_TRACE_ENTER(); @@ -24,13 +26,13 @@ TEST_CASE("Test log functions on cpp", "[utils][log][CPP]") #define MALLOC_GOOD_SIZE (1 * 1024) #define MALLOC_BAD_SIZE (1 * 1024 * 1024) -template -std::shared_ptr make_shared(Args &&... args) -{ - return std::allocate_shared>( - esp_utils::GeneralMemoryAllocator(), std::forward(args)... - ); -} +// template +// std::shared_ptr make_shared(Args &&... args) +// { +// return std::allocate_shared>( +// esp_utils::GeneralMemoryAllocator(), std::forward(args)... +// ); +// } template class TestClass { diff --git a/test_apps/sdkconfig.ci.mem_custom b/test_apps/sdkconfig.ci.mem_custom index bcf1aa8..ae2c512 100644 --- a/test_apps/sdkconfig.ci.mem_custom +++ b/test_apps/sdkconfig.ci.mem_custom @@ -1 +1,2 @@ -CONFIG_ESP_UTILS_CONF_MEM_GENERAL_ALLOC_TYPE_CUSTOM=y +CONFIG_ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_CUSTOM=y +CONFIG_ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE_CUSTOM=y diff --git a/test_apps/sdkconfig.ci.mem_esp b/test_apps/sdkconfig.ci.mem_esp index 5369f52..a1f15a8 100644 --- a/test_apps/sdkconfig.ci.mem_esp +++ b/test_apps/sdkconfig.ci.mem_esp @@ -1 +1,2 @@ -CONFIG_ESP_UTILS_CONF_MEM_GENERAL_ALLOC_TYPE_ESP=y +CONFIG_ESP_UTILS_CONF_MEM_GEN_ALLOC_TYPE_ESP=y +CONFIG_ESP_UTILS_CONF_MEM_CXX_GLOB_ALLOC_TYPE_ESP=y diff --git a/test_apps/sdkconfig.defaults b/test_apps/sdkconfig.defaults index 0495c8f..14d24f8 100644 --- a/test_apps/sdkconfig.defaults +++ b/test_apps/sdkconfig.defaults @@ -1,3 +1,4 @@ CONFIG_ESP_TASK_WDT_EN=n CONFIG_FREERTOS_HZ=1000 CONFIG_COMPILER_CXX_EXCEPTIONS=y +CONFIG_ESP_UTILS_CONF_MEM_ENABLE_CXX_GLOB_ALLOC=y