Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modify CHIP to support PSRAM platform allocator on ESP32 (CON-1517) #1248

Open
jonsmirl opened this issue Jan 18, 2025 · 6 comments
Open

Modify CHIP to support PSRAM platform allocator on ESP32 (CON-1517) #1248

jonsmirl opened this issue Jan 18, 2025 · 6 comments

Comments

@jonsmirl
Copy link
Contributor

jonsmirl commented Jan 18, 2025

Can you please implement a platform version of this memory code which moves these allocs into PSRAM?

https://github.com/project-chip/connectedhomeip/blob/master/src/lib/support/CHIPMem-Malloc.cpp#L93

All of these are CHIP and they are using internal RAM, and I keep running out of internal RAM over and over and I have 1.8MB of free PSRAM. I tried turning on the menuconfig option which makes malloc use PSRAM, but some buffers are doing DMA. So I would need to track those down and force them back into internal RAM.

It would be a useful exercise to work out the maximal amount of free internal RAM possible for the demos when PSRAM is available. To do that you would force every alloc into PSRAM and then see what breaks (mainly DMA buffers and interrupt code). Then fix up those DMA buffers and interrupt code to use caps alloc from internal RAM.

I (1363) app_main: Alloc 0x3fce7f44 size 1868 caps 808
I (1364) app_main: Alloc 0x3fce9a00 size 4096 caps 804
I (1365) app_main: Alloc 0x3fce8b60 size 1080 caps 808
I (1366) app_main: Alloc 0x3fceaa14 size 1260 caps 808
I (1368) app_main: Alloc 0x3fcebbb8 size 1904 caps 1800
I (1412) app_main: Alloc 0x3fcec0e8 size 6144 caps 804
I (1481) app_main: Alloc 0x3fcf02f0 size 6196 caps 1800
I (1983) app_main: Alloc 0x3fcf1d94 size 4096 caps 804
I (2053) app_main: Alloc 0x3fcf35d8 size 4242 caps 1800
I (2055) app_main: Alloc 0x3fcf46e8 size 4242 caps 1800
I (2057) app_main: Alloc 0x3fcf35d8 size 4242 caps 1800
I (2058) app_main: Alloc 0x3fcf35d8 size 4242 caps 1800
I (2059) app_main: Alloc 0x3fcf35d8 size 4242 caps 1800
I (2060) app_main: Alloc 0x3fcf35d8 size 4242 caps 1800
I (2062) app_main: Alloc 0x3fcf35d8 size 4242 caps 1800
I (2064) app_main: Alloc 0x3fcf35d8 size 4242 caps 1800
I (2065) app_main: Alloc 0x3fcf35d8 size 4242 caps 1800
I (2066) app_main: Alloc 0x3fcf35d8 size 4242 caps 1800
I (2067) app_main: Alloc 0x3fcf35d8 size 4242 caps 1800
I (2069) app_main: Alloc 0x3fcf35d8 size 4242 caps 1800
I (2070) app_main: Alloc 0x3fcf35d8 size 4242 caps 1800
I (2071) app_main: Alloc 0x3fcf35d8 size 4242 caps 1800
I (2072) app_main: Alloc 0x3fcf35d8 size 4242 caps 1800
I (2074) app_main: Alloc 0x3fcf35d8 size 4242 caps 1800
I (2075) app_main: Alloc 0x3fcf35d8 size 4242 caps 1800
I (2076) app_main: Alloc 0x3fcf35d8 size 4242 caps 1800
I (2078) app_main: Alloc 0x3fcf35d8 size 4242 caps 1800
I (2079) app_main: Alloc 0x3fcf35d8 size 4242 caps 1800
I (2080) app_main: Alloc 0x3fcf35d8 size 4242 caps 1800
I (2082) app_main: Alloc 0x3fcf35d8 size 4242 caps 1800
I (2083) app_main: Alloc 0x3fcf35d8 size 4242 caps 1800
I (2084) app_main: Alloc 0x3fcf35d8 size 4242 caps 1800
I (10283) app_main: Alloc 0x3fcf4490 size 5136 caps 1800
I (10287) app_main: Alloc 0x3fcf58b4 size 1264 caps 1800
I (10287) app_main: Alloc 0x3fcf5db8 size 1344 caps 1800
I (10289) app_main: Alloc 0x3fcf64b8 size 4096 caps 804

-- 0x40377a3b: esp_heap_trace_alloc_hook at /home/jonsmirl/l6/main/app_main.cpp:65
0x4037692d: heap_caps_malloc_base at /home/jonsmirl/esp/esp-idf/components/heap/heap_caps_base.c:135 (discriminator 1)
0x40376491: heap_caps_malloc at /home/jonsmirl/esp/esp-idf/components/heap/heap_caps.c:84
0x403764bf: heap_caps_malloc_default at /home/jonsmirl/esp/esp-idf/components/heap/heap_caps.c:110
0x4038966a: _calloc_r at /home/jonsmirl/esp/esp-idf/components/newlib/heap.c:65
0x4038968c: calloc at /home/jonsmirl/esp/esp-idf/components/newlib/heap.c:29 (discriminator 1)
0x420ccc8e: chip::Platform::MemoryCalloc(unsigned int, unsigned int) at /home/jonsmirl/l6/build/esp-idf/chip/../../../../aosp/esp-matter/connectedhomeip/connectedhomeip/config/esp32/third_party/connectedhomeip/src/lib/support/CHIPMem-Malloc.cpp:102
0x420fae4f: chip::Platform::Impl::PlatformMemoryManagement::MemoryCalloc(unsigned int, unsigned int) at /home/jonsmirl/l6/build/esp-idf/chip/../../../../aosp/esp-matter/connectedhomeip/connectedhomeip/config/esp32/third_party/connectedhomeip/src/lib/support/ScopedBuffer.h:123
 (inlined by) chip::Platform::Impl::ScopedMemoryBufferBase<chip::Platform::Impl::PlatformMemoryManagement>::Calloc(unsigned int, unsigned int) at /home/jonsmirl/l6/build/esp-idf/chip/../../../../aosp/esp-matter/connectedhomeip/connectedhomeip/config/esp32/third_party/connectedhomeip/src/lib/support/ScopedBuffer.h:108
0x420fc375: chip::Platform::ScopedMemoryBuffer<unsigned char, chip::Platform::Impl::PlatformMemoryManagement>::Calloc(unsigned int) at /home/jonsmirl/l6/build/esp-idf/chip/../../../../aosp/esp-matter/connectedhomeip/connectedhomeip/config/esp32/third_party/connectedhomeip/src/lib/support/ScopedBuffer.h:159
 (inlined by) chip::app::SimpleSubscriptionResumptionStorage::Load(unsigned short, chip::app::SubscriptionResumptionStorage::SubscriptionInfo&) at /home/jonsmirl/l6/build/esp-idf/chip/../../../../aosp/esp-matter/connectedhomeip/connectedhomeip/config/esp32/third_party/connectedhomeip/src/app/SimpleSubscriptionResumptionStorage.cpp:145
0x420fc7d8: chip::app::SimpleSubscriptionResumptionStorage::SimpleSubscriptionInfoIterator::Next(chip::app::SubscriptionResumptionStorage::SubscriptionInfo&) at /home/jonsmirl/l6/build/esp-idf/chip/../../../../aosp/esp-matter/connectedhomeip/connectedhomeip/config/esp32/third_party/connectedhomeip/src/app/SimpleSubscriptionResumptionStorage.cpp:67
0x420f7339: chip::app::InteractionModelEngine::ResumeSubscriptions() at /home/jonsmirl/l6/build/esp-idf/chip/../../../../aosp/esp-matter/connectedhomeip/connectedhomeip/config/esp32/third_party/connectedhomeip/src/app/InteractionModelEngine.cpp:1916
0x420768a4: chip::Server::ResumeSubscriptions() at /home/jonsmirl/aosp/esp-matter/connectedhomeip/connectedhomeip/src/app/server/Server.cpp:770 (discriminator 1)
0x420768ef: chip::Server::OnPlatformEvent(chip::DeviceLayer::ChipDeviceEvent const&) at /home/jonsmirl/aosp/esp-matter/connectedhomeip/connectedhomeip/src/app/server/Server.cpp:502
0x420768fd: chip::Server::OnPlatformEventWrapper(chip::DeviceLayer::ChipDeviceEvent const*, int) at /home/jonsmirl/aosp/esp-matter/connectedhomeip/connectedhomeip/src/app/server/Server.cpp:535
0x421a7901: chip::DeviceLayer::Internal::GenericPlatformManagerImpl<chip::DeviceLayer::PlatformManagerImpl>::DispatchEventToApplication(chip::DeviceLayer::ChipDeviceEvent const*) at /home/jonsmirl/l6/build/esp-idf/chip/../../../../aosp/esp-matter/connectedhomeip/connectedhomeip/config/esp32/third_party/connectedhomeip/src/include/platform/internal/GenericPlatformManagerImpl.ipp:350
0x420e38f7: chip::DeviceLayer::Internal::GenericPlatformManagerImpl<chip::DeviceLayer::PlatformManagerImpl>::_DispatchEvent(chip::DeviceLayer::ChipDeviceEvent const*) at /home/jonsmirl/l6/build/esp-idf/chip/../../../../aosp/esp-matter/connectedhomeip/connectedhomeip/config/esp32/third_party/connectedhomeip/src/include/platform/internal/GenericPlatformManagerImpl.ipp:315 (discriminator 1)
0x420e3ca9: chip::DeviceLayer::PlatformManager::DispatchEvent(chip::DeviceLayer::ChipDeviceEvent const*) at /home/jonsmirl/l6/build/esp-idf/chip/../../../../aosp/esp-matter/connectedhomeip/connectedhomeip/config/esp32/third_party/connectedhomeip/src/include/platform/PlatformManager.h:503
 (inlined by) chip::DeviceLayer::Internal::GenericPlatformManagerImpl_FreeRTOS<chip::DeviceLayer::PlatformManagerImpl>::_RunEventLoop() at /home/jonsmirl/l6/build/esp-idf/chip/../../../../aosp/esp-matter/connectedhomeip/connectedhomeip/config/esp32/third_party/connectedhomeip/src/include/platform/internal/GenericPlatformManagerImpl_FreeRTOS.ipp:257
0x420e3cf1: chip::DeviceLayer::PlatformManager::RunEventLoop() at /home/jonsmirl/l6/build/esp-idf/chip/../../../../aosp/esp-matter/connectedhomeip/connectedhomeip/config/esp32/third_party/connectedhomeip/src/include/platform/PlatformManager.h:403
 (inlined by) chip::DeviceLayer::Internal::GenericPlatformManagerImpl_FreeRTOS<chip::DeviceLayer::PlatformManagerImpl>::EventLoopTaskMain(void*) at /home/jonsmirl/l6/build/esp-idf/chip/../../../../aosp/esp-matter/connectedhomeip/connectedhomeip/config/esp32/third_party/connectedhomeip/src/include/platform/internal/GenericPlatformManagerImpl_FreeRTOS.ipp:280
0x403847b2: vPortTaskWrapper at /home/jonsmirl/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:134
@github-actions github-actions bot changed the title moving more stuff to PSRAM moving more stuff to PSRAM (CON-1517) Jan 18, 2025
@jonsmirl jonsmirl changed the title moving more stuff to PSRAM (CON-1517) moving more stuff to PSRAM, change CHIP alloc to use PSRAM (CON-1517) Jan 18, 2025
@jonsmirl
Copy link
Contributor Author

jonsmirl commented Jan 19, 2025

This it the CHIP_CONFIG_MEMORY_MGMT_PLATFORM option.

For example STM32 has replaced the memory allocator.
https://github.com/project-chip/connectedhomeip/blob/master/src/platform/stm32/CHIPMem-Platform.cpp#L206

@jonsmirl jonsmirl changed the title moving more stuff to PSRAM, change CHIP alloc to use PSRAM (CON-1517) Modify CHIP to support PSRAM platform allocator on ESP32 (CON-1517) Jan 19, 2025
@jonsmirl
Copy link
Contributor Author

jonsmirl commented Jan 19, 2025

I tracked down that DMA buffer (in a Lua driver) which was preventing me from enabling 'malloc from PSRAM' and I was able to enable it. But it didn't do nearly as much as I though it would, it only recovered around 30KB.

CHIP is still allocaing 40,136 from internal RAM and there should not be a reason for it to allocate anything from internal RAM.
My Lua task is down to 5160 which I should be able to track down and move.
Main is still 99,400. 40,000 of that is blocked by #1249
But that still leaves another 50,000 for me to track down.
wifi is also large at 45,488 and I have it set to use PSRAM for buffers.

Three obvious things to work on:

  1. why didn't setting 'malloc from PSRAM' move 40,136 in CHIP
  2. Get a fix for Modify ESP32 SPI flash driver to be compatible with stacks in PSRAM (CON-1518) #1249
  3. figure out how that last 50,000 in main is avoiding 'malloc from PSRAM'

1 and 3 are likely the same. Maybe setting 'malloc from PSRAM' doesn't move C++ new? Can you ask the IDF team about that?

I (54468728) app_main: Dump #52825 Free internal 39743 biggest block 31724 total 39743 PSRAM free 1409200
Task: CHIP 0x3fce9298 -> MALLOC_CAP_INTERNAL: 40136 MALLOC_CAP_SPIRAM: 21000 Highwater 3240
Task: btController 0x3fceeba4 -> MALLOC_CAP_INTERNAL: 7528 MALLOC_CAP_SPIRAM: 0 Highwater 932
Task: nimble_host 0x3fcc9684 -> MALLOC_CAP_INTERNAL: 36 MALLOC_CAP_SPIRAM: 460 Highwater 2764
Task: Pre-Scheduler allocs 0x0 -> MALLOC_CAP_INTERNAL: 3100 MALLOC_CAP_SPIRAM: 1000 Highwater 0
Task: lua 0x3fca5e24 -> MALLOC_CAP_INTERNAL: 5160 MALLOC_CAP_SPIRAM: 97652 Highwater 25860
Task: ipc0 0x3fcbe798 -> MALLOC_CAP_INTERNAL: 22404 MALLOC_CAP_SPIRAM: 6156 Highwater 776
Task: main 0x3fcc2604 -> MALLOC_CAP_INTERNAL: 99400 MALLOC_CAP_SPIRAM: 407484 Highwater 3660
Task: wifi 0x3fcda458 -> MALLOC_CAP_INTERNAL: 45488 MALLOC_CAP_SPIRAM: 60336 Highwater 2584
Task: ipc1 0x3fcbef14 -> MALLOC_CAP_INTERNAL: 68 MALLOC_CAP_SPIRAM: 0 Highwater 668
Task: sys_evt 0x3fcd6558 -> MALLOC_CAP_INTERNAL: 4956 MALLOC_CAP_SPIRAM: 9140 Highwater 1240
Task: HAL 0x3fca60ec -> MALLOC_CAP_INTERNAL: 176 MALLOC_CAP_SPIRAM: 4564 Highwater 904
Task: tiT 0x3fcd7bb0 -> MALLOC_CAP_INTERNAL: 0 MALLOC_CAP_SPIRAM: 336 Highwater 168
Task: mdns 0x3fccab20 -> MALLOC_CAP_INTERNAL: 0 MALLOC_CAP_SPIRAM: 156 Highwater 1936
Task: httpd 0x3fccbff0 -> MALLOC_CAP_INTERNAL: 88 MALLOC_CAP_SPIRAM: 200 Highwater 2896
Task: mcast 0x3fca6688 -> MALLOC_CAP_INTERNAL: 200 MALLOC_CAP_SPIRAM: 392 Highwater 856
Task: esp_timer 0x3fcc0090 -> MALLOC_CAP_INTERNAL: 0 MALLOC_CAP_SPIRAM: 0 Highwater 3012

@jonsmirl
Copy link
Contributor Author

I tried replacing the new operator, but this has no effect. Maybe I am not doing it right? I put this in a .cpp file and linked it in.

void* operator new(size_t size) {
    void* ptr = heap_caps_malloc(size, MALLOC_CAP_SPIRAM);
    if (!ptr) {
        abort();
    }
    return ptr;
}

void* operator new[](size_t size) {
    void* ptr = heap_caps_malloc(size, MALLOC_CAP_SPIRAM);
    if (!ptr) {
        abort();
    }
    return ptr;
}

void operator delete(void* ptr) noexcept { free(ptr); }

void operator delete(void* ptr, std::size_t) noexcept { free(ptr); }

void operator delete[](void* ptr) noexcept { free(ptr); }

void operator delete[](void* ptr, std::size_t) noexcept { free(ptr); }

@jonsmirl
Copy link
Contributor Author

jonsmirl commented Jan 19, 2025

I went through every allocation over 1KB. 198KB total.

#2 is the lua stack with is impacted by #1249

#14,#15,#16,#52 are FreeRTOS queues which are easily moved.
#5 and #8 are two large event loops which should be looked at 13KB total
I have wifi set to use PSRAM dynamic buffers, but it still allocates a lot of memory

and finally BLE. BLE is using A LOT of memory : 11436 + 6144 + 4096 + 3056 + 1868 + 1260 + 1080 = 28,960
My BLE is also set to use external memory.

I only need BLE in observer role in my code. So my next experiment will be to tell CHIP to shut down BLE and then my code will restart it in observer role.

Of all of these allocations, the only one which is in code I wrote is the LCD DMA buffer, #37.

Image
Image

The task memory display is needs some interpreting:

Task: CHIP 0x3fce934c -> MALLOC_CAP_INTERNAL: 40156 MALLOC_CAP_SPIRAM: 21012 Highwater 3236
Task: btController 0x3fceebcc -> MALLOC_CAP_INTERNAL: 7528 MALLOC_CAP_SPIRAM: 0 Highwater 932
Task: nimble_host 0x3fcc9688 -> MALLOC_CAP_INTERNAL: 36 MALLOC_CAP_SPIRAM: 448 Highwater 2776
Task: mdns 0x3fccab24 -> MALLOC_CAP_INTERNAL: 0 MALLOC_CAP_SPIRAM: 160 Highwater 1708

That says MDNS has no internal memory, but I can see from the allocs that it has 4KB memory, but that memory is assigned to the CHIP task since it was initialized from the CHIP task. With similar logic, it may be that 23KB of the 40KB in CHIP actually belongs to BLE. The BLE task only claims 7580 bytes.

@jonsmirl
Copy link
Contributor Author

I've managed to get 40KB of internal memory free now so my LCD based device is working again.
This is not a critical issue for me now.

@shubhamdp
Copy link
Contributor

@jonsmirl would this #1123 (comment) help? This moves the bss of libesp_matter.a and libCHIP.a to PSRAM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants