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.

control of linker placement for switch/const sections



I've got a few switch statements that I would like to group with a speed critical section of code for cache performance reasons.  My processor is a dm6435.  My current linker command file contains the following excerpt:

    .FAST_CODE_SECTION > DDR2 align 0x8000 // want fast code aligned on 32kB cache boundary
     {
         rts64plus.lib<divi.obj>
        rts64plus.lib<divu.obj>
        rts64plus.lib<strasg.obj>
        bsl_minimum.lib<dm6435_reduced.obj>
        IQmath_c64xPlus.lib
     }
    .cinit       > DDR2
    .const       > DDR2
    .far         > DDR2
    .cio         > DDR2
    .switch      > DDR2

 

Currently, I manually assign function calls to the FAST_CODE_SECTION using the CODE_SECTION pragma.

I'd like a way to include the .switch & .const sections in the .FAST_CODE_SECTION.  It would be even better if I had control of this on a module by module basis.  Can anyone give an example of how to accomplish this?

 

EDIT: maybe I need to make sure this will do what I want.  I was originally assuming that the const & switch sections would be a program memory fetch and would blow L1P cache if they were not aligned with the currently executing code, but I am now thinking this is a dangerous assumption to make.  Are accesses of the .const & switch sections treated as program or data?  If one or both are data, I suppose I would want to locate them in L1SRAM instead of the aligned section where I put all my critical code (.txt).

  • The items in .const and .switch are accessed as data.  Accesses to those sections thus have no impact on program cache.  They impact data cache instead.  

    Note this syntax ...

    MattLipsey said:
             rts64plus.lib<divi.obj>

    can possibly cause problems.  That says to place every input section from divi.obj into FAST_CODE_SECTION.  I doubt you mean that.  You probably want

    rts64plus.lib<divi.obj>(.text)

    which says to place only the .text section (i.e. the code) from divi.obj into FAST_CODE_SECTION.  

    You are getting away with this minor error because divi.obj only contains .text.  You will not be so lucky in the future.

    For similar reasons, you probably ought to make this change as well.

    IQmath_c64xPlus.lib(.text)

    That refers to all of the code from that library, and not any of the other sections.

    Thanks and regards,

    -George

     

     

  • Thanks for the pointers on the .text section, I made that change.  I now want to throw the .const section from a specific file and the .switch section from another specific file into L1D_SRAM.  You may recall helping me create an overlapped memory space in L1D.  Now can I toss these new sections(>?) into the GROUP, and if so, what is the format for doing so?  Say I have a file dar.c and I want to put the .switch from that into the GROUP.

    Sorry for the questions, but I couldn't find documentation for how to get this specific with the linker.  Most of the docs are on a fairly general level, but I know there are a LOT of docs and I may have missed something.  If you have the relevant document I'd love to take a look at it.

        GROUP(L1D_SRAM_ALL) {
            .stack
            .bss
            UNION (L1D_FLEX) {
                sectionA_fullcacheshared {
                    *(.sectionASRAM)
                    . += 0x8000;    // 32kB worth of cache here
                }
                sectionB_fullcacheshared {
                    *(.sectionBSRAM)
                    . += 0x8000;    // 32kB worth of cache here
                }
                sectionC_fullcacheshared {
                    *(.sectionCSRAM)
                    . += 0x8000;    // 32kB worth of cache here
                }
                sectionD_fullsramshared {
                    *(.sectionDSRAM)
                }
            }
        } > L1D

  • So while I am waiting for a definitive answer, I have been trying various things to solve this issue.

    I tried to add a new .FAST_DATA section in my linker command file with the lines

        GROUP(L1D_SRAM_ALL) {
            .stack
            .bss
            .QUICK_DATA {systemComm.obj (.switch)}

             ...

    I get an error " cannot find file "systemComm.obj" " even though that file is built and in my /debug folder.

     

    These two sections are (currently) small enough that I think I can just toss ALL the switch/const values in L1DSRAM.  I tried:

        GROUP(L1D_SRAM_ALL) {
            .stack
            .bss
            .switch
            .const
            UNION (L1D_FLEX) { ...

    But got a linker warning: "object containing initialized overlays requires explicit LOAD placement for  each initialized member"

    As well as a warning "LOAD placement required for initialized object ".switch"" and similar for the .const lines

    Not sure what I need to do about this.

  • MattLipsey said:
    Now can I toss these new sections(>?) into the GROUP, and if so, what is the format for doing so?  Say I have a file dar.c and I want to put the .switch from that into the GROUP.

    You can put them in the group.  It would look something like ...

        GROUP {
            .stack    // existing stuff 
            ...
            for_switch { dar.obj(.switch) }   // new
            ...
            UNION {   // existing stuff
    

    Thanks and regards,

    -George

     

  • MattLipsey said:
    I get an error " cannot find file "systemComm.obj" " even though that file is built and in my /debug folder.

    Try this instead

          .QUICK_DATA { .\debug\systemComm.obj(.switch) }
    

    MattLipsey said:

    But got a linker warning: "object containing initialized overlays requires explicit LOAD placement for  each initialized member"

    As well as a warning "LOAD placement required for initialized object ".switch"" and similar for the .const lines

    I can't explain this.  It should work.  Those are the messages I expect you would get if you had placed any .switch or .const inside the UNION.  But you didn't.  I'll have to get back to you.

    Thanks and regards,

    -George

     

     

  • George,

    I tried your latest suggestion with the new path values, and I now get a

    object containing initialized overlays requires explicit LOAD placement for
       each initialized member

    error.  Any ideas on how to deal with this?

  • George,

    Thanks for the help in investigating this problem.  For what it's worth, here is my relevant info:

    CCS Version 3.3.82.13

    ID 5.98.0.393

    Code Gen v6.1.9

    linker command file contents after your .text suggestions:

    // link.cmd

    --heap_size=0x2000000    // 32 MB
    --stack_size=0x2400    // 9k

    MEMORY
    {
        IRAM        : origin = 0x10800000,  len = 0x20000        // 128 kB    (100% L2 cache)
        CACHE_L1P    : origin = 0x10e08000,  len = 0x8000        // 32 kB
        L1D            : origin = 0x10f04000,    len = 0x14000        // 80 kB
        FLASH        : origin = 0x42000000,  len = 0x01000000    // 16 MB addressable
        DDR2        : origin = 0x80000000,  len = 0x0ffffff0    // 256 MB - 16
        VERSION_BLOCK    : origin = 0x8ffffff0,  len = 0x02            // 2 bytes
    }

    SECTIONS
    {
        /*
            L1D contains stack & bss sections.  Remaining memory can be configured to be
            100% cache (32kB cache) or 100% sram (0 cache).  This memory is treated as a
            shared scratchpad overlay.  Application is responsible for ensuring correct cache
            handling.
        */

        GROUP(L1D_SRAM_ALL) {
            .stack
            .bss
    //        for_switch { .\debug\systemComm.obj(.switch) }
            UNION (L1D_FLEX) {
                maintMode_fullcacheshared {
                    *(.maintModeSRAM)
                    . += 0x8000;    // 32kB worth of cache here
                }
                findImageRefPoints_fullcacheshared {
                    *(.findImageRefPointsSRAM)
                    . += 0x8000;    // 32kB worth of cache here
                }
                paintFrameInCanvas_fullcacheshared {
                    *(.paintFrameInCanvasSRAM)
                    . += 0x8000;    // 32kB worth of cache here
                }
                detect_fullsramshared {
                    *(.detectSRAM)
                }
            }
        } > L1D

        .sysmem        > DDR2
        .vectors     > DDR2 align 0x400    // interrupt table must be 1024 byte aligned
        .text        > DDR2
        .FAST_CODE_SECTION > DDR2 align 0x8000 // want fast code aligned on 32kB cache boundary
         {
    //         rts64plus.lib<divi.obj>(.text)
    //        rts64plus.lib<divu.obj>(.text)
    //        rts64plus.lib<strasg.obj>(.text)
            rts64plus.lib(.text)
            bsl_minimum.lib<dm6435_reduced.obj>(.text)
            IQmath_c64xPlus.lib(.text)
         }
        .VERSION_SECTION > VERSION_BLOCK
        .cinit       > DDR2
        .const       > DDR2
        .far         > DDR2
        .cio         > DDR2
        .switch      > DDR2
    }

  • Matt,

    Unfortunately, you have tripped across a linker bug.  I have submitted SDSCM00037756 into SDOWP.  Feel free to track it with the link in my sig below.

    As for a workaround ...  Would you be able to split up the GROUP and UNION like this

        GROUP(L1D_SRAM_ALL) {
            .stack
            .bss
            for_switch { .\debug\systemComm.obj(.switch) }
        } > L1D
    
            UNION (L1D_FLEX) {
                maintMode_fullcacheshared {
                    *(.maintModeSRAM)
                    . += 0x8000;    // 32kB worth of cache here
                }
                findImageRefPoints_fullcacheshared {
                    *(.findImageRefPointsSRAM)
                    . += 0x8000;    // 32kB worth of cache here
                }
                paintFrameInCanvas_fullcacheshared {
                    *(.paintFrameInCanvasSRAM)
                    . += 0x8000;    // 32kB worth of cache here
                }
                detect_fullsramshared {
                    *(.detectSRAM)
                }
            } > L1D

    Note this means you can no longer guarantee that the UNION goes into L1D last.  It might be allocated at a lower address than the GROUP.  I can't remember the details of your original system.  Is this OK?

    Thanks and regards,

    -George

     

  • George,

    Actually, I do need to guarantee that the UNION is in the upper part of L1D because it is designed to be used in a system that switches between full cache and full sram, and I have to make sure that the 32kB spacers for cache are at the upper end of L1D.  I tried adding a (HIGH) specifier after the "} > L1D"  for the union and that seems to do the trick.  For now I will just be vigilant and check the map file after builds to make sure this continues to do what I need.  Thanks for your assistance in troubleshooting this issue.