3 years, 11 months ago.

Heap not fully used on multiple STM platforms. (+/- 3.7K not used)

I'm working on a project where I want to use a RTOS on a STM platform. At the moment I'm using a STML072Z LORAWAN discovery kit from ST and ARM_GCC compiler

I had some issue with the memory already, so I started to take a look at the memory usage of the device. So I found this post about debugging stack and heap problems.

https://developer.mbed.org/blog/entry/Tracing-stack-and-heap-overflow-errors/

Heap debugging code

#include "mbed.h"
#include "mbed_memory_status.h"

int main() {
    print_all_thread_info();
    print_heap_and_isr_stack_info();

    size_t malloc_size = 16 * 1024;

    while (true) {
        wait(0.2);

        // fill up the memory
        void* ptr = malloc(malloc_size);
        printf("Allocated %d bytes (success %d)\r\n", malloc_size, ptr != NULL);
        if (ptr == NULL) {
            malloc_size /= 2;
            print_heap_and_isr_stack_info();
        }

        // and then allocate an object on the heap
        DigitalOut* led = new DigitalOut(LED1);
    }
}

When I run this code I get some strange results. The program runs out of memory (expected), but when you look at the usage of the heap, there is almost 4k of heap not used.

I tested this on multiple platforms like STM nucleo-L073RZ and STM nucleo-F411RE and had the same result.

At the last print of the heap size you can see that the heap is not fully used but the error Operator new out of memory appears.

output std lib

--Output with "default_lib": "std" in targets.json--


stack ( start: 200020A8 end: 200023C8 size: 00000320 used: 00000070 ) thread ( id: 200023D4 entry: 08001659 )
stack ( start: 20000B30 end: 20001B30 size: 00001000 used: 000000D8 ) thread ( id: 20002414 entry: 08000C41 )
stack ( start: 20001E00 end: 20002000 size: 00000200 used: 00000040 ) thread ( id: 200025EC entry: 08000C8D )
heap ( start: 200026C0 end: 20004E40 size: 00002780 used: 00000000 )  alloc ( ok: 00000000  fail: 00000000 )
isr_stack ( start: 20004E40 end: 20005000 size: 000001C0 used: 000001C0 )

Allocated 16384 bytes (success 0)
heap ( start: 200026C0 end: 20004E40 size: 00002780 used: 00000400 )  alloc ( ok: 00000001  fail: 00000001 )
isr_stack ( start: 20004E40 end: 20005000 size: 000001C0 used: 000001C0 )

Allocated 8192 bytes (success 0)
heap ( start: 200026C0 end: 20004E40 size: 00002780 used: 00000414 )  alloc ( ok: 00000002  fail: 00000002 )
isr_stack ( start: 20004E40 end: 20005000 size: 000001C0 used: 000001C0 )

Allocated 4096 bytes (success 0)
heap ( start: 200026C0 end: 20004E40 size: 00002780 used: 00000428 )  alloc ( ok: 00000003  fail: 00000003 )
isr_stack ( start: 20004E40 end: 20005000 size: 000001C0 used: 000001C0 )

Allocated 2048 bytes (success 1)
Allocated 2048 bytes (success 1)
Allocated 2048 bytes (success 0)
heap ( start: 200026C0 end: 20004E40 size: 00002780 used: 00001464 )  alloc ( ok: 00000008  fail: 00000004 )
isr_stack ( start: 20004E40 end: 20005000 size: 000001C0 used: 000001C0 )

Allocated 1024 bytes (success 1)
Allocated 1024 bytes (success 0)
heap ( start: 200026C0 end: 20004E40 size: 00002780 used: 0000188C )  alloc ( ok: 0000000B  fail: 00000005 )
isr_stack ( start: 20004E40 end: 20005000 size: 000001C0 used: 000001C0 )

Operator new out of memory

After some time we changed in tagets.json file the lib from STD to SMALL. With this change the heap is used fully as expected.

output smal lib

--Output with "default_lib": "small" in targets.json--

stack ( start: 200002F8 end: 200012F8 size: 00001000 used: 000000D8 ) thread ( id: 2000183C entry: 08000C25 )
stack ( start: 200015A0 end: 200017A0 size: 00000200 used: 00000040 ) thread ( id: 200018D4 entry: 08000C71 )
heap ( start: 200019A8 end: 20004E40 size: 00003498 used: 00000000 )  alloc ( ok: 00000000  fail: 00000000 )
isr_stack ( start: 20004E40 end: 20005000 size: 000001C0 used: 000001C0 )

Allocated 16384 bytes (success 0)
heap ( start: 200019A8 end: 20004E40 size: 00003498 used: 000005AC )  alloc ( ok: 00000002  fail: 00000001 )
isr_stack ( start: 20004E40 end: 20005000 size: 000001C0 used: 000001C0 )

Allocated 8192 bytes (success 1)
Allocated 8192 bytes (success 0)
heap ( start: 200019A8 end: 20004E40 size: 00003498 used: 000025D4 )  alloc ( ok: 00000005  fail: 00000002 )
isr_stack ( start: 20004E40 end: 20005000 size: 000001C0 used: 000001C0 )

Allocated 4096 bytes (success 0)
heap ( start: 200019A8 end: 20004E40 size: 00003498 used: 000025E8 )  alloc ( ok: 00000006  fail: 00000003 )
isr_stack ( start: 20004E40 end: 20005000 size: 000001C0 used: 000001C0 )

Allocated 2048 bytes (success 1)
Allocated 2048 bytes (success 0)
heap ( start: 200019A8 end: 20004E40 size: 00003498 used: 00002E10 )  alloc ( ok: 00000009  fail: 00000004 )
isr_stack ( start: 20004E40 end: 20005000 size: 000001C0 used: 000001C0 )

Allocated 1024 bytes (success 1)
Allocated 1024 bytes (success 0)
heap ( start: 200019A8 end: 20004E40 size: 00003498 used: 00003238 )  alloc ( ok: 0000000C  fail: 00000005 )
isr_stack ( start: 20004E40 end: 20005000 size: 000001C0 used: 000001C0 )

Allocated 512 bytes (success 0)
heap ( start: 200019A8 end: 20004E40 size: 00003498 used: 0000324C )  alloc ( ok: 0000000D  fail: 00000006 )
isr_stack ( start: 20004E40 end: 20005000 size: 000001C0 used: 000001C0 )

Allocated 256 bytes (success 1)
Allocated 256 bytes (success 0)
heap ( start: 200019A8 end: 20004E40 size: 00003498 used: 00003374 )  alloc ( ok: 00000010  fail: 00000007 )
isr_stack ( start: 20004E40 end: 20005000 size: 000001C0 used: 000001C0 )

Operator new out of memory

Can anybody give an explanation why the heap cannot be fully allocated when using default lib STD? Thank you very much.

Be the first to answer this question.