This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

PROCESSOR-SDK-AM64X: providing a "minimal" heap-implementation

Part Number: PROCESSOR-SDK-AM64X
Other Parts Discussed in Thread: SYSBIOS

Hello,

since we once started working with the TIRTOS we used a functionality called "MinHeap" which provides a heap which will just allocate every object after another and without the possibility to free anything (throws an assert in case of free()-call).

So this was the solution needed for our environment since we will only allocate memory at startup but will never free it. It saves additional memory created for the information of the allocated memory-areas, which can be much when we use a lot of small allocations and it will also speed up the allocation process.

So the wish exists that the AM64 (and AM24)- SDK povide such functionality. Since I understood that currently the built-in compiler-solution is used, this generates a lot of overhead, we do not need. In fact a simple implementation like provided with the heap_1.c in freeRTOS will be good enough for our purposes.

In a first step we also can just simply overwrite the global malloc-functionality and so on (which I guess will then also work for "new" in C++), but of course for maintainability a native vendor-support of your side would be appreciated.

Regards,

Felix

  • Hi Felix,

    I gather you were formerly using SYS-BIOS HeapMin (docs in <BIOS>/docs/cdoc/xdc/runtime/HeapMin.html). This is a growth only heap (no free allowed) which is fast, deterministic, and has no internal fragmentation.

    Did you see the documentation for FreeRTOS heaps here?

    As you mention, it seems heap_1.c has similar functionality to HeapMin: "Linear heap allocation, free not allowed. Typically used when true dynamic alloc is prohibited."

    I see heap_1.c is included in the MCU+ SDK installation here: <SDK>/source/kernel/freertos/FreeRTOS-Kernel/portable/MemMang/heap_1.c.

    I see heap_3.c is located in the R5F kernel make file: <SDK>/source/kernel/freertos/makefile.am64x.r5f.ti-arm-clang.

    I haven't tried this, but can you try replacing heap_3.c (the default) with heap1_c?

    Regards,
    Frank

  • Exactly. we used this implementataion with SYSBIOS.

    Yes we tried the heap_1.c. It does work but it is no general allocation, it is only used for the dynamic allocation of OS-objects. We need a more generic appraoch but of course the heap_1.c can also be used to overwrite malloc as well.

    regards,

    Felix

  • Hi Felix,

    I see the Default Heap is used by FreeRTOS when objects (e.g. Task, Queue, etc.) are created using the dynamic allocation APIs. If static allocation APIs are used instead of the dynamic allocation APIs, then the default heap isn't used. Please see: https://www.freertos.org/Static_Vs_Dynamic_Memory_Allocation.html

    MCU+SDK uses heap_3.c for the Default Heap (which uses compiler malloc()), but heap_1.c can be used instead of heap_3.c. I think all that should be required is to rebuild the kernel with heap_3.c replaced by heap_1.c.

    The Default Heap seems similar to the SYSBIOS System Heap.

    I assume you were using HeapMin for user defined application heaps. MCU+ SDK supports user defined heaps using the HeapP as described here: https://software-dl.ti.com/mcu-plus-sdk/esd/AM64X/08_01_00_36/exports/docs/api_guide_am64x/KERNEL_FREERTOS_IMPORTANT_GUIDELINES_PAGE.html#autotoc_md338

    HeapP is implemented in the following files:

    ./source/kernel/freertos/dpl/common/HeapP_freertos.c
    ./source/kernel/nortos/dpl/common/HeapP_internal.c

    The header for HeapP_internal.c includes the following comment:

    /*
     * A sample implementation of heap based on heap_4.c from FreeRTOS 
     * 
    

    I don't see the compiler malloc used in this this implementation, which makes sense if it's based on heap_4.c.

    It appears like what you need is an alternate implementation for HeapP based on heap_1.c instead of heap_4.c. Then you'd be able to replace the HeapMin API functions in your code with HeapP API functions. Does this make sense?
           

  • Hi Frank,

    Yes we thought about the static allocation but this won't solve memory allocation made by normal malloc and "new" and so on.
    And yes, like I said heap_1.c is possible. we tried this. But it wont solve the user-allocations.

    We are currently not using any old SYSBIOS-functions, it was just a comparison how the heap could be configured and we used this functionality. But all our code is done with malloc and mostly new.

    HeapP does provide user-heaps, but they are not hidden behind standard malloc and new. We just wanted to write portable code and so we need to use the c/c++-standard functionality. As far as I remember in SYSBIOS the Heap was configured by XDCTools and was then automatically used when new or malloc was called, if I'm right or wasn't that the case? That's more the way we searched for a solution. But yes an implementation of HeapP with heap_1.c would at least be the behaviour we would expect of the heap.

    In any currently possible case it seems we need to overwrite malloc and new manually anyways.

  • Hi Felix,

    We are currently not using any old SYSBIOS-functions,
    As far as I remember in SYSBIOS the Heap was configured by XDCTools and was then automatically used when new or malloc was called, if I'm right or wasn't that the case?

    Yes, I misunderstood. You must have been configuring SYSBIOS as described in Bios_User_Guide.pdf, Section 7.7.2 & 7.7.5. In this case, malloc would use HeapMin.

    So my understanding is you want to use malloc (and possibly C++ new) with heap_1.c.

    I consulted on this with an expert on our software development team, and was provided with the code in the attached file. I updated the FreeRTOS kernel to use heap_1.c, integrated the code into hello_world_am64x-evm_r5fss0-0_freertos_ti-arm-clang, and added a call to "malloc" in the application. This works as desired, and the malloc call now executes pvPortMalloc() in heap_1.c.

    Are you ok to integrate this code in the application, or do you want this implemented in SDK libraries?

    Do you need all the RTS memory functionality using heap_1.c? The attached code includes additional functions which are currently compiled out. We can investigate into how to implement these functions using heap_1.c if required.

    Regards,
    Frank

    #include "FreeRTOS.h"
    #include <kernel/freertos/FreeRTOS-Kernel/include/portable.h>
    
    /*
    *  ======== malloc ========
    */
    void __attribute__((used)) *malloc(size_t size)
    {
        return pvPortMalloc(size);
    }
    
    /*
    *  ======== free ========
    */
    void __attribute__((used)) free(void *ptr)
    {
         vPortFree(ptr);
    }
    
    #if 0 // I believe the following should also be implemented using heap_1.c if we want to support all rts memory allocation functionality. Let me know which of these are required and I can check how to implement with heap_1.c
    /*
    *  ======== memalign ========
    *  mirrors the memalign() function from the TI run-time library
    */
    void ____attribute____ ((used)) *memalign(size_t alignment, size_t size)
    {
        
    }
    
    /*
    *  ======== calloc ========
    */
    void ____attribute____ ((used)) *calloc(size_t nmemb, size_t size)
    {
        
    }
    
    
    /*
    *  ======== realloc ========
    */
    void ____attribute____ ((used)) *realloc(void *ptr, size_t size)
    {
        
    }
    
    /*
    *  ======== aligned_alloc ========
    */
    void ____attribute____ ((used)) *aligned_alloc(size_t alignment, size_t size)
    {
        
    }
    #endif