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.

Compiler/TMS320F28377D: Cannot specify a RUN placement for an output section within a GROUP.

Part Number: TMS320F28377D

Tool/software: TI C/C++ Compiler

I am trying to use the GROUP directive for the TI linker to specify an order of sections within a memory region. One of the sections in the group will be .TI.ramfunc, the generated output section for functions that have the __attribute__((ramfunc)) applied. This section needs to be loaded at one address in flash, and run from a different address in RAM. I used the guide here to instruct the linker to do this copy for me. http://processors.wiki.ti.com/index.php/Placing_functions_in_RAM

The syntax I am using looks like this:

SECTIONS
{
    GROUP
    {
        .cinit
        .binit
        .pinit
        .text
        .econst
        .switch
        .args
        .TI.ramfunc RUN = GS_RAM, TABLE(BINIT)
    } > FLASH

    /* other sections here */
}

The linker accepts this syntax and generates a binary, but it emits the following warning:

"link.cmd", line 27: warning: placement ignored for ".TI.ramfunc":  object is
   placed as part of "GROUP_1"

When I look at the .map file for the generated binary I see the following entry for the BINIT table:

LINKER GENERATED COPY TABLES

binit @ 00080020 records: 1, size/record: 8, table size: 10
    .TI.ramfunc: copy 4 bytes from load addr=00080110 at page=0 to run addr=00080110 at page=0

This indicates that the warning was accurate; it ignored the RUN placement and just used the LOAD placement of "FLASH" for the group as the RUN placement for .TI.ramfunc as well, but still generated an entry in the copy table to copy this section to itself (which will fail, because it's in flash). The RUN address should be around 0xC000, the start of GS_RAM.

The command I'm using to build a minimal example with this is:

cl2000 main.c -z link.cmd -Iti-cgt-c2000_18.1.3.LTS/lib -m main.map -o main.out

I've attached a zip of main.c, link.cmd, and the output main.map.

ramfunc_group_link.zip

Two questions:

(1) Is this a bug in the linker? Should I be allowed to specify different RUN placements for different members of a group? (It seems like this should be possible, and the fact that it did generate a copy table entry for only this section suggests this should be allowed.)

(2) Given the current behavior of the linker, bug or otherwise, is there a different way to achieve my goal, specifically to order .TI.ramfunc within a group of other sections, while still letting the linker emit a correct copy table entry for it.

  • Just for now, ignore the TABLE operator, and everything related to it.  That is an issue here, but not the main one.

    The main issue is that the GROUP directive does not support giving a RUN allocation to any of its members.  A RUN allocation can only be given to the entire group.

    Christopher Copeland said:
    Is this a bug in the linker?

    No.  The following quote comes from the C2000 assembly tools manual sub-chapter titled Checking the Consistency of Allocators.  

    Run allocations are only allowed for top-level sections, groups, or unions ...

    It is unusual to see so many output sections in the same GROUP.  I want to understand why, because there may be a different way to solve the problem which works better.  Just for now, pretend you know nothing about the linker features and command file syntax.  With that perspective, please describe the overarching problem you want to solve.

    Thanks and regards,

    -George

  • My overall goal is to have a symbol that will be placed at the end of all sections in a given memory region (in this case a memory region that corresponds to all flash banks). This symbol will be referenced by parts of the application, so it should be known to the linker. I don't want to just append something to an output binary, and it also should not be in a fixed location since the overall size of all the sections in the application will change from version to version.

    Thanks for the link to the docs; I think I did encounter that when looking into this problem, though I'm not 100% clear why the limitation exists. I'm not very invested in doing it this way though, so happy to hear of alternatives that will achieve the goal.

  • Christopher Copeland said:
    My overall goal is to have a symbol that will be placed at the end of all sections in a given memory region

    Unfortunately, we don't have a good way to do that.  GROUP is one way to go, but it ends up constraining section placement more than needed.  Here are two alternatives to consider ...

    Alternative one ... A unintended side effect of how the .data section gets initialized is that the .cinit section is almost always placed at the highest address in its memory range.  This behavior is not guaranteed.  But, if you are willing to rely on it, you can write ...

        .cinit > FLASH, END(_symbol_name_here)

    Alternative two ... Pick exactly one section that goes in the FLASH memory range, and apply the high location specifier to it.  Say you pick the .switch section.  Then you could write ...

        .switch > FLASH(HIGH), END(_symbol_name_here)

    The entry CODEGEN-2377 is filed in the SDOWP system to request a feature be added to the linker so creating this symbol is easy.

    Thanks and regards,

    -George

  • Hi George,

    Thanks for the suggestions, I'll take a look. I have to ask though if there is a fundamental limitation preventing RUN placements on individual sections in a group? Given the choice between having that just work and a special feature that solves for my specific case (generating a symbol for the end of a memory region), I'd prefer that GROUP be more flexible. It seems like it has already been made partially general because the TABLE directive can be applied to an individual section within a group, and that RUN not working may be just an oversight, but I don't have enough visibility to say for sure.

    Thanks,

    Chris

  • We have received multiple requests for a symbol that marks the highest address used in a memory range (like FLASH).  So, that is the solution we intend to provide.

    Thanks and regards,

    -George