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.

Dynamic section sizing at link time

I am trying to allocate space for a heap structure that is to be used by user-managed dynamic memory allocation (as opposed to compiler-managed) .  I would like for this structure to take up the rest of remaining RAM, no matter what it may be.  I want this structure to be resized accordingly as my codebase changes and global variables may come and go through different firmware revisions.  

Does anyone have an idea for the "right" way to do this?

My idea right now is to have a section for this structure in the linker command file that places it at _STACK_END, effectively at the beginning (LBA) of the remaining space.  However, I'm having a hard time figuring out how to make the size of this section available at runtime.

Any help would be appreciated.

Thanks,

Mateja

  • Any takers? I would very much appreciate someone's ideas on this. Thanks! Mateja
  • There is no built-in feature of the linker for a dynamically sized section.  This is a cool idea, and I've been thinking about it ...

    -George

     

  • If it's not a built-in feature, then there's a workaround, it's just a matter of finding it. Where there's a will, there's a way, I'm going to keep digging on this one. Mateja
  • I found one way to create a "section" where the size is whatever is left of a given memory range.  I use quotes to indicate an ordinary section is not created.

    Here is a linker command file ...

    #define MEM_START 0x200
    #define MEM_LEN   0xFDE0
    myheap_end = MEM_START + MEM_LEN;
    
    /* SPECIFY THE SYSTEM MEMORY MAP */
    
    MEMORY
    {
        SFR(R)           : origin = 0x0000, length = 0x0010
        PERIPHERALS_8BIT : origin = 0x0010, length = 0x00F0
        PERIPHERALS_16BIT: origin = 0x0100, length = 0x0100
        MEM(RW)          : origin = MEM_START, length = MEM_LEN
        VECTORS(R)       : origin = 0xFFE0, length = 0x001E
        RESET            : origin = 0xFFFE, length = 0x0002
    }
    
    /* SPECIFY THE SECTIONS ALLOCATION INTO MEMORY */
    
    SECTIONS
    {
        .intvecs : {} > VECTORS          /* INTERRUPT VECTORS                 */
        GROUP {
          .bss                           /* GLOBAL & STATIC VARS              */
          .sysmem                        /* DYNAMIC MEMORY ALLOCATION AREA    */
          .stack                         /* SOFTWARE SYSTEM STACK             */
    
          .text                          /* CODE                              */
          .cinit                         /* INITIALIZATION TABLES             */
          .const                         /* CONSTANT DATA                     */
          .cio                           /* C I/O BUFFER                      */
    
          .pinit                         /* C++ CONSTRUCTOR TABLES            */
        } > MEM, END(myheap_start)
        .reset   : > RESET
    }
    

    All of the interesting stuff is in red.  And here is some example C code ...

    #include <stdio.h>
    
    extern unsigned myheap_start, myheap_end;
    
    main()
    {
        unsigned myheap_length;
        myheap_length = (unsigned) &myheap_end - (unsigned) &myheap_start;
    
        printf("myheap_start:  %x\n", &myheap_start);
        printf("myheap_end:    %x\n", &myheap_end);
        printf("myheap_length: %x\n", myheap_length);
    }
    

    The net effect is that whatever part of the MEM memory range that is not used is left to a "section" that is starts at myheap_start, ends at myheap_end, and has length myheap_length.  The #define's allow you to define the start and length of MEM in single spot, then use it as needed.  The purpose of the GROUP is so you can use the END operator to mark the end of the group, which is the same as the start of the custom heap.  An unnecessary side effect is that everything in the GROUP will be allocated to memory in that exact order.  But all other methods I can think of for developing the heap start address have even worse problems.

    Thanks and regards,

    -George

     

  • George, Thanks for the follow-up, I'll give it a try and will post back. Mateja