Hello Support team,
I have an issue with two simultaneous heaps in my project. I use nrf Connect SDK 3.2.2 with the next configuration options:
Hello Support team,
I have an issue with two simultaneous heaps in my project. I use nrf Connect SDK 3.2.2 with the next configuration options:
Hi Egor,
you’re right — having two heaps is not ideal, and unfortunately there’s no built-in way to truly merge them into one.
Simple approach that works:
Redirect everything to the Zephyr (kernel) heap. heardle game
That means:
malloc, free, calloc, reallocnew / deletek_malloc / k_freeThis way you effectively use one heap only, and you can monitor it with Zephyr APIs.
Also, I’d avoid:
Better set a fixed size or fully redirect allocations, otherwise memory usage is hard to control.
In short:
You can’t truly combine both heaps, but you can force everything to use the kernel heap, which is the cleanest solution.
Hope that helps
Justin,
Thank you for this hints. I managed it with the next changes:
1. Override only C allocation functions malloc, calloc, realloc and free to kernel equivalents. Did several experiments and I see that C++ allocation is done via these C functions
2. Exclude Libc implementation of allocation functions and set heap arena size to 0 using next config:
config MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP bool "Heap (dynamic size)" depends on COMMON_LIBC_MALLOC_ARENA_SIZE > 0 help Use dynamic heap memory allocation through malloc, if there is insufficient heap memory for the allocation then the request will be rejected.
Hi Egor,
Could you try to allocate:
CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=1
instead of leaving it 0 ? (It's just to satisfy the condition, but the actual allocation should go through your overriden method.)
Please try this and let me know how it goes.
-Priyanka
Hi Priyanka,
I tried it. To set any value to CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE I have to enable CONFIG_COMMON_LIBC_MALLOC. Enabling CONFIG_COMMON_LIBC_MALLOC leads to malloc function compilation and I have conflict with my malloc implementation
Hi Egor,
Apologies for the delayed response. I think it would be better then to keep using the stack buffer and increase the MCUmgr thread stack size if needed.
CONFIG_MCUMGR_GRP_SETTINGS_BUFFER_TYPE_STACK=y
CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_STACK_SIZE=<larger value if needed>
If you really need MCUMgr to use heap memory instead, then I think that the Zephyr/MCUmgr would need a small code change so it uses k_malloc() directly, instead of depending on Zephyr’s libc malloc heap. But that means carrying a local patch. So, it might be better to use the stack buffer.
-Priyanka
Hi Priyanka,
Thank you for this answer. I think that the dependency in Kconfig for MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP is not quite correct. It relies on COMMON_LIBC_MALLOC_ARENA_SIZE > 0 condition but in implementation it uses malloc call to allocate the memory and as we see the malloc function does not come from the LibC all the time.
Anyway, any fix for heap allocation in my case needs to carry a local patch for now.
Hi Priyanka,
Thank you for this answer. I think that the dependency in Kconfig for MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP is not quite correct. It relies on COMMON_LIBC_MALLOC_ARENA_SIZE > 0 condition but in implementation it uses malloc call to allocate the memory and as we see the malloc function does not come from the LibC all the time.
Anyway, any fix for heap allocation in my case needs to carry a local patch for now.