From 796be200e2fec5fa919409aa6f2004d94ec89789 Mon Sep 17 00:00:00 2001 From: WanqQixiang Date: Mon, 15 Jan 2024 15:31:18 +0800 Subject: [PATCH] ESP32: Add menuconfig to use PSRAM for Matter memory allocation --- config/esp32/args.gni | 3 + config/esp32/components/chip/Kconfig | 21 +++ .../esp32/common/CommonDeviceCallbacks.cpp | 7 +- src/platform/ESP32/BUILD.gn | 5 + src/platform/ESP32/CHIPMem-Platform.cpp | 143 ++++++++++++++++++ 5 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 src/platform/ESP32/CHIPMem-Platform.cpp diff --git a/config/esp32/args.gni b/config/esp32/args.gni index f818a37f258e49..e52423f288c9d5 100644 --- a/config/esp32/args.gni +++ b/config/esp32/args.gni @@ -29,6 +29,9 @@ lwip_platform = "external" chip_inet_config_enable_tcp_endpoint = false chip_inet_config_enable_udp_endpoint = true +#Use platform memory management +chip_config_memory_management = "platform" + custom_toolchain = "//third_party/connectedhomeip/config/esp32/toolchain:esp32" # Avoid constraint forcing for ESP32: diff --git a/config/esp32/components/chip/Kconfig b/config/esp32/components/chip/Kconfig index f8885b77e9739f..78e3a210894173 100644 --- a/config/esp32/components/chip/Kconfig +++ b/config/esp32/components/chip/Kconfig @@ -191,6 +191,27 @@ menu "CHIP Core" Enable dynamic server to handle a different interaction model dispatch. Can be implied when users do not want to use the same server clusters. + choice CHIP_MEM_ALLOC_MODE + prompt "Memory allocation strategy" + default CHIP_MEM_ALLOC_MODE_DEFAULT + help + Strategy for Matter memory management + - Internal DRAM memory only + - External SPIRAM memory only + - Either internal or external memory based on default malloc() behavior in ESP-IDF + + config CHIP_MEM_ALLOC_MODE_INTERNAL + bool "Internal memory" + + config CHIP_MEM_ALLOC_MODE_EXTERNAL + bool "External SPIRAM" + depends on SPIRAM_USE_CAPS_ALLOC || SPIRAM_USE_MALLOC + + config CHIP_MEM_ALLOC_MODE_DEFAULT + bool "Default alloc mode" + + endchoice # CHIP_MEM_ALLOC_MODE + endmenu # "General Options" menu "Networking Options" diff --git a/examples/platform/esp32/common/CommonDeviceCallbacks.cpp b/examples/platform/esp32/common/CommonDeviceCallbacks.cpp index 2dfcffef3dece8..4581b576500df8 100644 --- a/examples/platform/esp32/common/CommonDeviceCallbacks.cpp +++ b/examples/platform/esp32/common/CommonDeviceCallbacks.cpp @@ -95,7 +95,12 @@ void CommonDeviceCallbacks::DeviceEventCallback(const ChipDeviceEvent * event, i break; } - ESP_LOGI(TAG, "Current free heap: %u\n", static_cast(heap_caps_get_free_size(MALLOC_CAP_8BIT))); + ESP_LOGI(TAG, "Current free heap: Internal: %u/%u External: %u/%u", + static_cast(heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL)), + static_cast(heap_caps_get_total_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL)), + static_cast(heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM)), + static_cast(heap_caps_get_total_size(MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM))); + } void CommonDeviceCallbacks::OnInternetConnectivityChange(const ChipDeviceEvent * event) diff --git a/src/platform/ESP32/BUILD.gn b/src/platform/ESP32/BUILD.gn index 77cbc94bb43650..aa4f7eb41118f0 100644 --- a/src/platform/ESP32/BUILD.gn +++ b/src/platform/ESP32/BUILD.gn @@ -15,6 +15,7 @@ import("//build_overrides/chip.gni") import("${chip_root}/src/inet/inet.gni") +import("${chip_root}/src/lib/core/core.gni") import("${chip_root}/src/platform/device.gni") assert(chip_device_platform == "esp32") @@ -81,6 +82,10 @@ static_library("ESP32") { "${chip_root}/src/platform:platform_base", ] + if (chip_config_memory_management == "platform") { + sources += [ "CHIPMem-Platform.cpp" ] + } + if (chip_enable_ota_requestor) { sources += [ "OTAImageProcessorImpl.cpp", diff --git a/src/platform/ESP32/CHIPMem-Platform.cpp b/src/platform/ESP32/CHIPMem-Platform.cpp new file mode 100644 index 00000000000000..f155d9f7415a55 --- /dev/null +++ b/src/platform/ESP32/CHIPMem-Platform.cpp @@ -0,0 +1,143 @@ +/* + * + * Copyright (c) 2025 Project CHIP Authors + * All rights reserved. + * + * 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. + */ + +/** + * @file + * This file implements heap memory allocation APIs for CHIP. These functions are platform + * specific and might be C Standard Library heap functions re-direction in most of cases. + * + */ + +#include +#include + +#include +#include +#include +#include +#include + + +namespace chip { +namespace Platform { + +#define VERIFY_INITIALIZED() VerifyInitialized(__func__) + +static std::atomic_int memoryInitialized{ 0 }; + +static void VerifyInitialized(const char * func) +{ + if (!memoryInitialized) + { + ChipLogError(DeviceLayer, "ABORT: chip::Platform::%s() called before chip::Platform::MemoryInit()", func); + abort(); + } +} + +CHIP_ERROR MemoryAllocatorInit(void * buf, size_t bufSize) +{ + if (memoryInitialized++ > 0) + { + ChipLogError(DeviceLayer, "ABORT: chip::Platform::MemoryInit() called twice."); + abort(); + } + + return CHIP_NO_ERROR; +} + +void MemoryAllocatorShutdown() +{ + if (--memoryInitialized < 0) + { + ChipLogError(DeviceLayer, "ABORT: chip::Platform::MemoryShutdown() called twice."); + abort(); + } +} + +void * MemoryAlloc(size_t size) +{ + void * ptr; + VERIFY_INITIALIZED(); +#ifdef CONFIG_CHIP_MEM_ALLOC_MODE_INTERNAL + ptr = heap_caps_malloc(size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); +#elif defined(CONFIG_CHIP_MEM_ALLOC_MODE_EXTERNAL) + ptr = heap_caps_malloc(size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); +#else + ptr = malloc(size); +#endif + return ptr; +} + +void * MemoryAlloc(size_t size, bool isLongTermAlloc) +{ + void * ptr; + VERIFY_INITIALIZED(); +#ifdef CONFIG_CHIP_MEM_ALLOC_MODE_INTERNAL + ptr = heap_caps_malloc(size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); +#elif defined(CONFIG_CHIP_MEM_ALLOC_MODE_EXTERNAL) + ptr = heap_caps_malloc(size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); +#else + ptr = malloc(size); +#endif + return ptr; +} + +void * MemoryCalloc(size_t num, size_t size) +{ + void * ptr; + VERIFY_INITIALIZED(); +#ifdef CONFIG_CHIP_MEM_ALLOC_MODE_INTERNAL + ptr = heap_caps_calloc(num, size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); +#elif defined(CONFIG_CHIP_MEM_ALLOC_MODE_EXTERNAL) + ptr = heap_caps_calloc(num, size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); +#else + ptr = calloc(num, size); +#endif + return ptr; +} + +void * MemoryRealloc(void * p, size_t size) +{ + VERIFY_INITIALIZED(); +#ifdef CONFIG_CHIP_MEM_ALLOC_MODE_INTERNAL + p = heap_caps_realloc(p, size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); +#elif defined(CONFIG_CHIP_MEM_ALLOC_MODE_EXTERNAL) + p = heap_caps_realloc(p, size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); +#else + p = realloc(p, size); +#endif + return p; +} + +void MemoryFree(void * p) +{ + VERIFY_INITIALIZED(); +#ifdef CONFIG_MATTER_MEM_ALLOC_MODE_DEFAULT + free(p); +#else + heap_caps_free(p); +#endif +} + +bool MemoryInternalCheckPointer(const void * p, size_t min_size) +{ + return (p != nullptr); +} + +} // namespace Platform +} // namespace chip