Skip to content

Commit 1eb2421

Browse files
ESP32: Add menuconfig to use PSRAM for Matter memory allocation (#37482)
* ESP32: Add menuconfig to use PSRAM for Matter memory allocation * Restyled by clang-format * review changes * split to 3 separate files * doc changes * add comment on MemoryInternalCheckPointer --------- Co-authored-by: Restyled.io <commits@restyled.io>
1 parent cf45d5d commit 1eb2421

File tree

8 files changed

+249
-1
lines changed

8 files changed

+249
-1
lines changed

config/esp32/args.gni

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ lwip_platform = "external"
2929
chip_inet_config_enable_tcp_endpoint = false
3030
chip_inet_config_enable_udp_endpoint = true
3131

32+
chip_config_memory_management = "platform"
33+
3234
custom_toolchain = "//third_party/connectedhomeip/config/esp32/toolchain:esp32"
3335

3436
# Avoid constraint forcing for ESP32:

config/esp32/components/chip/CMakeLists.txt

+8
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,14 @@ if(CONFIG_ENABLE_ICD_SERVER)
149149
endif()
150150
endif()
151151

152+
if(CONFIG_CHIP_MEM_ALLOC_MODE_INTERNAL)
153+
chip_gn_arg_append("chip_memory_alloc_mode" "\"internal\"")
154+
elseif(CONFIG_CHIP_MEM_ALLOC_MODE_EXTERNAL)
155+
chip_gn_arg_append("chip_memory_alloc_mode" "\"external\"")
156+
elseif(CONFIG_CHIP_MEM_ALLOC_MODE_DEFAULT)
157+
chip_gn_arg_append("chip_memory_alloc_mode" "\"default\"")
158+
endif()
159+
152160
if(CONFIG_ENABLE_PW_RPC)
153161
string(APPEND chip_gn_args "import(\"//build_overrides/pigweed.gni\")\n")
154162
chip_gn_arg_append("remove_default_configs" "[\"//third_party/connectedhomeip/third_party/pigweed/repo/pw_build:toolchain_cpp_standard\"]")

config/esp32/components/chip/Kconfig

+21
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,27 @@ menu "CHIP Core"
191191
Enable dynamic server to handle a different interaction model dispatch.
192192
Can be implied when users do not want to use the same server clusters.
193193

194+
choice CHIP_MEM_ALLOC_MODE
195+
prompt "Memory allocation strategy"
196+
default CHIP_MEM_ALLOC_MODE_DEFAULT
197+
help
198+
Strategy for Matter memory management
199+
- Internal DRAM memory only
200+
- External SPIRAM memory only
201+
- Either internal or external memory based on default malloc() behavior in ESP-IDF
202+
203+
config CHIP_MEM_ALLOC_MODE_INTERNAL
204+
bool "Internal memory"
205+
206+
config CHIP_MEM_ALLOC_MODE_EXTERNAL
207+
bool "External SPIRAM"
208+
depends on SPIRAM_USE_CAPS_ALLOC || SPIRAM_USE_MALLOC
209+
210+
config CHIP_MEM_ALLOC_MODE_DEFAULT
211+
bool "Default alloc mode"
212+
213+
endchoice # CHIP_MEM_ALLOC_MODE
214+
194215
endmenu # "General Options"
195216

196217
menu "Networking Options"

examples/platform/esp32/common/CommonDeviceCallbacks.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,11 @@ void CommonDeviceCallbacks::DeviceEventCallback(const ChipDeviceEvent * event, i
9595
break;
9696
}
9797

98-
ESP_LOGI(TAG, "Current free heap: %u\n", static_cast<unsigned int>(heap_caps_get_free_size(MALLOC_CAP_8BIT)));
98+
ESP_LOGI(TAG, "Current free heap: Internal: %u/%u External: %u/%u",
99+
static_cast<unsigned int>(heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL)),
100+
static_cast<unsigned int>(heap_caps_get_total_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL)),
101+
static_cast<unsigned int>(heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM)),
102+
static_cast<unsigned int>(heap_caps_get_total_size(MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM)));
99103
}
100104

101105
void CommonDeviceCallbacks::OnInternetConnectivityChange(const ChipDeviceEvent * event)

src/platform/ESP32/BUILD.gn

+12
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import("//build_overrides/chip.gni")
1616

1717
import("${chip_root}/src/inet/inet.gni")
18+
import("${chip_root}/src/lib/core/core.gni")
1819
import("${chip_root}/src/platform/device.gni")
1920

2021
assert(chip_device_platform == "esp32")
@@ -33,6 +34,7 @@ declare_args() {
3334
chip_use_esp32_ecdsa_peripheral = false
3435
chip_enable_ethernet = false
3536
chip_enable_route_hook = false
37+
chip_memory_alloc_mode = "default"
3638
}
3739

3840
defines = [
@@ -81,6 +83,16 @@ static_library("ESP32") {
8183
"${chip_root}/src/platform:platform_base",
8284
]
8385

86+
if (chip_config_memory_management == "platform") {
87+
if (chip_memory_alloc_mode == "internal") {
88+
sources += [ "CHIPMem-PlatformInternal.cpp" ]
89+
} else if (chip_memory_alloc_mode == "external") {
90+
sources += [ "CHIPMem-PlatformExternal.cpp" ]
91+
} else {
92+
sources += [ "CHIPMem-PlatformDefault.cpp" ]
93+
}
94+
}
95+
8496
if (chip_enable_ota_requestor) {
8597
sources += [
8698
"OTAImageProcessorImpl.cpp",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
*
3+
* Copyright (c) 2025 Project CHIP Authors
4+
* All rights reserved.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
#include <lib/support/CHIPMem.h>
20+
#include <platform/CHIPDeviceLayer.h>
21+
22+
#include <esp_heap_caps.h>
23+
#include <stdlib.h>
24+
25+
namespace chip {
26+
namespace Platform {
27+
28+
CHIP_ERROR MemoryAllocatorInit(void * buf, size_t bufSize)
29+
{
30+
return CHIP_NO_ERROR;
31+
}
32+
33+
void MemoryAllocatorShutdown() {}
34+
35+
void * MemoryAlloc(size_t size)
36+
{
37+
return malloc(size);
38+
}
39+
40+
void * MemoryAlloc(size_t size, bool isLongTermAlloc)
41+
{
42+
return malloc(size);
43+
}
44+
45+
void * MemoryCalloc(size_t num, size_t size)
46+
{
47+
return calloc(num, size);
48+
}
49+
50+
void * MemoryRealloc(void * p, size_t size)
51+
{
52+
return realloc(p, size);
53+
}
54+
55+
void MemoryFree(void * p)
56+
{
57+
free(p);
58+
}
59+
60+
bool MemoryInternalCheckPointer(const void * p, size_t min_size)
61+
{
62+
// We don't have a way to know if p is allocated from the heap, just do a null check here.
63+
return (p != nullptr);
64+
}
65+
66+
} // namespace Platform
67+
} // namespace chip
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
*
3+
* Copyright (c) 2025 Project CHIP Authors
4+
* All rights reserved.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
#include <lib/support/CHIPMem.h>
20+
#include <platform/CHIPDeviceLayer.h>
21+
22+
#include <esp_heap_caps.h>
23+
#include <stdlib.h>
24+
25+
namespace chip {
26+
namespace Platform {
27+
28+
CHIP_ERROR MemoryAllocatorInit(void * buf, size_t bufSize)
29+
{
30+
return CHIP_NO_ERROR;
31+
}
32+
33+
void MemoryAllocatorShutdown() {}
34+
35+
void * MemoryAlloc(size_t size)
36+
{
37+
return heap_caps_malloc(size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
38+
}
39+
40+
void * MemoryAlloc(size_t size, bool isLongTermAlloc)
41+
{
42+
return heap_caps_malloc(size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
43+
}
44+
45+
void * MemoryCalloc(size_t num, size_t size)
46+
{
47+
return heap_caps_calloc(num, size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
48+
}
49+
50+
void * MemoryRealloc(void * p, size_t size)
51+
{
52+
return heap_caps_realloc(p, size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
53+
}
54+
55+
void MemoryFree(void * p)
56+
{
57+
heap_caps_free(p);
58+
}
59+
60+
bool MemoryInternalCheckPointer(const void * p, size_t min_size)
61+
{
62+
// We don't have a way to know if p is allocated from the heap, just do a null check here.
63+
return (p != nullptr);
64+
}
65+
66+
} // namespace Platform
67+
} // namespace chip
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
*
3+
* Copyright (c) 2025 Project CHIP Authors
4+
* All rights reserved.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
#include <lib/support/CHIPMem.h>
20+
#include <platform/CHIPDeviceLayer.h>
21+
22+
#include <esp_heap_caps.h>
23+
#include <stdlib.h>
24+
25+
namespace chip {
26+
namespace Platform {
27+
28+
CHIP_ERROR MemoryAllocatorInit(void * buf, size_t bufSize)
29+
{
30+
return CHIP_NO_ERROR;
31+
}
32+
33+
void MemoryAllocatorShutdown() {}
34+
35+
void * MemoryAlloc(size_t size)
36+
{
37+
return heap_caps_malloc(size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
38+
}
39+
40+
void * MemoryAlloc(size_t size, bool isLongTermAlloc)
41+
{
42+
return heap_caps_malloc(size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
43+
}
44+
45+
void * MemoryCalloc(size_t num, size_t size)
46+
{
47+
return heap_caps_calloc(num, size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
48+
}
49+
50+
void * MemoryRealloc(void * p, size_t size)
51+
{
52+
return heap_caps_realloc(p, size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
53+
}
54+
55+
void MemoryFree(void * p)
56+
{
57+
heap_caps_free(p);
58+
}
59+
60+
bool MemoryInternalCheckPointer(const void * p, size_t min_size)
61+
{
62+
// We don't have a way to know if p is allocated from the heap, just do a null check here.
63+
return (p != nullptr);
64+
}
65+
66+
} // namespace Platform
67+
} // namespace chip

0 commit comments

Comments
 (0)