What is the minimum allowed/recommended value for CONFIG_HEAP_MEM_POOL_SIZE?

Hi,

I am working on application code for the nrf9160. Current NCS version is 1.5.1, although I do not think my ancient NCS version is relevant to this issue.

I have removed all k_malloc statements (and calloc) from my application code. I thought this would allow me to set CONFIG_HEAP_MEM_POOL_SIZE=0 in prj.conf, but setting this gives me linker errors along the line of error: undefined reference to `k_aligned_alloc' when linking the kernel. I assume this is because setting the heap size to 0 removes these function definitions.

Is setting the heap size to zero not supported by NCS? What is a safe lower limit I can set it to? 256? Leave it undefined?

Thank you,
Fridtjof

  • Hi Fridtjof,

    Do you mean CONFIG_HEAP_MEM_POOL_SIZE?

    Several components in an nRF9160 application might require dynamic memory allocation, even if your code does not explicitly call k_malloc, calloc, or similar functions.
    For instance, the modem library (nrf_modem_lib) requires a certain amount of heap memory to function correctly (configured by CONFIG_NRF_MODEM_LIB_HEAP_SIZE).
    Additionally, certain subsystems (boards, drivers, libraries, etc) might use dynamic memory allocation under the hood.

    If you set CONFIG_HEAP_MEM_POOL_SIZE=0, you instruct the kernel not to define the heap memory pool object. This could lead to errors if any part of your application or the underlying system services/libraries/drivers tries to allocate memory from the heap.

    You can see which subsystems are using dynamic memory allocation by looking at which files you get the undefined reference errors from, e.g.:

    /home/marte/zephyr-sdk-0.16.5/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: modules/nrf/lib/lte_link_control/lib..__nrf__lib__lte_link_control.a(lte_lc_helpers.c.obj): in function `parse_ncellmeas_gci':
    /home/marte/ncs/nrf/lib/lte_link_control/lte_lc_helpers.c:1266: undefined reference to `k_calloc'
    /home/marte/zephyr-sdk-0.16.5/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: modules/nrf/lib/nrf_modem_lib/lib..__nrf__lib__nrf_modem_lib.a(nrf91_sockets.c.obj): in function `nrf91_socket_offload_getaddrinfo':
    /home/marte/ncs/nrf/lib/nrf_modem_lib/nrf91_sockets.c:793: undefined reference to `k_malloc'
    /home/marte/zephyr-sdk-0.16.5/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: modules/nrf/lib/nrf_modem_lib/lib..__nrf__lib__nrf_modem_lib.a(nrf91_sockets.c.obj): in function `nrf_to_z_addrinfo':
    /home/marte/ncs/nrf/lib/nrf_modem_lib/nrf91_sockets.c:314: undefined reference to `k_malloc'
    /home/marte/zephyr-sdk-0.16.5/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: /home/marte/ncs/nrf/lib/nrf_modem_lib/nrf91_sockets.c:322: undefined reference to `k_malloc'
    /home/marte/zephyr-sdk-0.16.5/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: modules/nrf/lib/at_cmd_parser/lib..__nrf__lib__at_cmd_parser.a(at_params.c.obj): in function `at_params_list_init':
    /home/marte/ncs/nrf/lib/at_cmd_parser/at_params.c:76: undefined reference to `k_calloc'
    /home/marte/zephyr-sdk-0.16.5/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: modules/nrf/lib/at_cmd_parser/lib..__nrf__lib__at_cmd_parser.a(at_params.c.obj): in function `at_params_string_put':
    /home/marte/ncs/nrf/lib/at_cmd_parser/at_params.c:164: undefined reference to `k_malloc'
    /home/marte/zephyr-sdk-0.16.5/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: modules/nrf/lib/at_cmd_parser/lib..__nrf__lib__at_cmd_parser.a(at_params.c.obj): in function `at_params_array_put':
    /home/marte/ncs/nrf/lib/at_cmd_parser/at_params.c:193: undefined reference to `k_malloc'
    /home/marte/zephyr-sdk-0.16.5/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: modules/nrf/lib/lte_link_control/lib..__nrf__lib__lte_link_control.a(lte_lc.c.obj): in function `at_handler_ncellmeas_gci':
    /home/marte/ncs/nrf/lib/lte_link_control/lte_lc.c:369: undefined reference to `k_calloc'
    /home/marte/zephyr-sdk-0.16.5/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: modules/nrf/lib/lte_link_control/lib..__nrf__lib__lte_link_control.a(lte_lc.c.obj): in function `at_handler_ncellmeas':
    /home/marte/ncs/nrf/lib/lte_link_control/lte_lc.c:427: undefined reference to `k_calloc'

    Here, the lte_link_control, nrf_modem_lib, and at_cmd_parser dynamically allocate memory.

    However, if you do not explicitly allocate memory dynamically in your application, then it should be safe to configure it to be pretty low (or leave it undefined) as long as it is not 0, as, for example, the modem library defines its own heap size with CONFIG_NRF_MODEM_LIB_HEAP_SIZE. I would still strongly recommend testing your application to ensure that there are no unexpected behaviors due to the heap being too low.

    Best regards,
    Marte

  • Hi Marte!

    Yes, I did mean CONFIG_HEAP_MEM_POOL_SIZE Face palm. I will edit the question to improve searchability.

    After doing some searching in the Zephyr documentation, it seems like the behavior of CONFIG_HEAP_MEM_POOL_SIZE changed between Zephyr 2.7.5 and 3.6.0. I was reading the newer documentation, but am probably using the older Zephyr version (so my ancient NCS version was relevant after all). In newer Zephyr versions, it seems like Zephyr will set a higher heap size if submodules need it, even if the user sets CONFIG_HEAP_MEM_POOL_SIZE=0.

    So if I only manage to upgrade I suppose this problem will solve itself.

    Thanks for the help!

Related