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.

linker overlay with different section sizes



I am using the dm6435 and switching the allocation of L1D memory between 100% cache (48k SRAM, 32k cache) and 100% SRAM (80k SRAM, no cache).  I want to split this memory region into 3 pieces: 1) a small piece of the memory that is always sram where I will allocate the .bss & .stack sections, a2)  piece that is the remaining section of the 48k SRAM , and 3) a piece that is the remaining section of the 80k SRAM.  The last 2 pieces overlay each other.  Then I want to declare a data overlay using one of these last 2 sections, i.e. modules A & B both reuse the same section of piece 2, and modules C & D reuse the same section of piece 3.  How would I go about this organization in the linker command files?  I'm fine with the application being responsible for knowing which cache configuration it is using for which module.


Thanks for any insight.

  • First to set some expectations ... This is more complex than most linker questions.  It may take a few iterations before we hit on the solution that works best for you.

    Here is a first attempt.  Define a single memory range for the entire 80K.  I'll call it SRAM80K.  The line in the MEMORY directive will look something like this ...

        SRAM80K: origin = 0x00f04000, length = 0x0001c000  /* 80K */
    

    Then, in the SECTIONS directive, you will have something like this ...

        GROUP {
            .stack
            .bss
            UNION {
                os_sram48k_cache32k {  /* This runs when SRAM = 48K, CACHE = 32K */
                    module A sections here
                    module B sections here
                    . += 0x8000;   /* 32K hole to avoid cache */
                }
                os_sram80k_cache0k {  /* This runs when SRAM = 80K, CACHE = 0K  */
                    module C sections here
                    module D sections here
                }
            }
        } > SRAM80K
    

    Replace "module A sections here" with whatever you write now to list the input sections from module A.  The name "os_sram48K_cache32k" means the output section formed to run when memory is in that configuration.  The UNION means those two output sections will overlay each other in memory.  It is up to your application code to handle the runtime management details of that overlay.  It sounds like you have already have ideas on how to do that.  The GROUP means the .stack and .bss sections will go into that memory range first, followed by the UNION/overlay.  

    Try that out and let us know how it goes.

    Thanks and regards,

    -George

     

  • Looks like this will work, but I'm running into some detail problems.

    In module A, I want to put 2 big buffers into the os_sram48k_cache32k section, and all other data & text into their default sections.  In the past, I have done the following:

    #pragma DATA_SECTION(bufferA, ".fast_mem")

    Uint32 bufferA[HISTOGRAM_NUM_ENTRIES];

     

    Then in my linker command file sections area, I would have

    .fast_mem > L1D_SRAM

    where L1D_SRAM was defined in the MEMORY area.

     

    So now in my lcf, I have:

    SECTIONS

    {

    GROUP {

    .stack

    .bss

    UNION {

    L1D_FULL_CACHE {

    }

    L1D_FULL_SRAM {

    .moduleA_fastmem

    }

    ...

    When I build, the linker gives me an error saying "cannot find file "moduleA_fastmem".  I tried it without the ".", same result.  

    How do I resolve this?

    As an aside, SRAM80K: origin = 0x00f04000, length = 0x0001c000 /* 80K */          length should be 0x00014000 for 80kB

  • When you write 

    .fast_mem > L1D_SRAM

    This is really short-hand for  ...

    .fast_mem { *(.fast_mem) } > L1D_SRAM

    That means create an output section named .fast_mem.  It is composed of all the input sections named .fast_mem.  Then place that output section in L1D_SRAM.  You are trying to do the equivalent of this ...

    .fast_mem { .fast_mem } > L1D_SRAM   // doesn't work!

    So, try this instead ...

        L1D_FULL_SRAM {
            *(.fast_mem)
        }
    

    If you want to specify the input section from only a single file write ...

        L1D_FULL_SRAM {
            moduleA.obj(.fast_mem)
        }
    

    Thanks and regards,

    -George

     

     

  • We are making progress.  I am now getting a linker failed to allocate error, because what I really wanted was for modules A & B to each have access to the entire portion of L1D_FULL_CACHE besides the reserved 32k, and C & D to each have access to all of the L1D_FULL_SRAM space.  The linker is trying to allocate modules A, B, & 32k of cache into L1D and failing.  

    I tried to add another nested union statement to express this to the linker, but I don't quite grok the syntax and I'm getting errors.  I think I'll be on my merry way after this iteration.

    edit:

    I tried the following:

    SECTIONS

    {

    GROUP {

    .stack

    .bss

    UNION(L1D_FLEX) {

    GROUP(L1D_FULL_CACHE) { // 80k with 32k of cache

    UNION(L1D_FULL_CACHE_SRAM_PIECE) {

    *(.modASRAM)

    *(.modBSRAM)

    }

    . += 0x8000; // 32kB worth of cache here

    }

    UNION(L1D_FULL_SRAM) { // 80k with 0k of cache

    *(.modCSRAM)

    *(.modDSRAM)

    }

    }

    }

    } > L1D

     

    Now the linker complains that it was expecting section type instead of ".modASRAM".  I'm only putting uninitialized data arrays into this section, what should I pick?

  • A UNION is not limited to two members.  I think you want this ...

        GROUP {
            .stack
            .bss
            UNION {
                modA_sram48k_cache32k {  /* This runs when SRAM = 48K, CACHE = 32K */
                    module A sections here
                    . += 0x8000;   /* 32K hole to avoid cache */
                }
                modB_sram48k_cache32k {  /* This runs when SRAM = 48K, CACHE = 32K */
                    module B sections here
                    . += 0x8000;   /* 32K hole to avoid cache */
                }
                modC_sram80k_cache0k {  /* This runs when SRAM = 80K, CACHE = 0K  */
                    module C sections here
                }
                modD_sram80k_cache0k {  /* This runs when SRAM = 80K, CACHE = 0K  */
                    module D sections here
                }
            }
        } > SRAM80K
    

    Thanks and regards,

    -George

     

     

  • This links successfully and does what I asked.  Thanks for the assistance.