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.

TMS320F28388D: How to place C++ virtual method table into RAM instead of flash?

Part Number: TMS320F28388D

Hi all,

we are using ARM C++ compiler TI Clang v3.2.0.LTS for the CM core on a TMS28388D.

While doing flash firmware updates, I ran into problems because everything needed for the update procedure must not be located in the flash sectors that have been erased. For most cases this was easy - just define all required functions as ramfunction, i.e. assign to section ".TI.ramfunc" .

But now I ran into a problem with a class containing virtual methods. The method implementations could successfully be defined as ramfunction, but it turned out that the virtual method table is still located in flash, having 0xFFFFFFFF as method pointers after flash erase and causing a crash on a call.

I tried to put "__attribute__((section(...)))" into the class definition, hoping that it would apply to the class as a whole, including the VMT. But that didn't work (compiler error "only applies to functions, global variables, Objective-C methods, and Objective-C properties").

How can I move the VMT to RAM or assign it to a specific RAM section?   From the map file it looks as if the tables are located in the .rodata section. I'm not sure if it is wise to move the whole section to RAM, as apparently it also contains other constants (which preferably(?) should be placed close to the using function - if I'm not mistaken there may be a 4k delta addressing limit).

regards
Chris

  • All of the example code in this post goes inside the SECTIONS directive of the linker command file.

    If it is practical to isolate the code that creates the virtual tables into one file, then you could write something similar to ...

    Fullscreen
    1
    2
    3
    4
    virtual_tables
    {
    file_name.o(.rodata)
    } > RAM
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    This creates an output section named virtual_tables.  It contains all the .rodata input sections from the object file named file_name.o.  

    If that is not practical, then you could write ...

    Fullscreen
    1
    2
    3
    4
    virtual_tables
    {
    *(.rodata._ZTV*)
    } > RAM
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    This creates an output section named virtual_tables.  It contains all of the .rodata input sections, where the subsection name begins with _ZTV.  This is breaking the rules a bit.  The fact that all the virtual table section names begin with .rodata._ZTV is a detail of the compiler implementation that is not considered part of the public interface.  Such a detail is subject to change at any time, with no notice.  That said, the _ZTV part comes from the algorithm used by all Arm compilers to mangle C++ function names, virtual tables, etc.  It has been the same for a long time.  It is reasonable to not expect it to change any time soon.

    Thanks and regards,

    -George

  • Thank you for your quick reply.

    In the meantime I tried putting all of .rodata into RAM. This seems to work, but at the expense of occupying precious RAM with unneeded stuff that could as well stay in flash.
    Your suggestion looks promising, as it may help limiting RAM consumption to a given .o file.

    Are the specifications cumulative? I.e. can I first say "file_name.o(.rodata)" for RAM, and then "*(.rodata)" to put everything else to flash?
    The cmd file primer at software-dl.ti.com/.../sdto_cgt_Linker-Command-File-Primer.html gives an example inside the same section (although that seems redundant to me - first include s/th sepecific, and then everything). Would that notation work across sections?

    Or does the last specification take precedence (first everything to flash, then override specific file to RAM)?

    kind regards
    Chris

  • can I first say "file_name.o(.rodata)" for RAM, and then "*(.rodata)" to put everything else to flash?

    Yes.  You are correct to point out this detail.  The input specification *(.rodata) is "greedy".  When it is seen, it finds all the .rodata input sections that are not part of any other output section.  So the specification file_name.o(.rodata) must appear first.  This is true whether these input specifications are written inside the same output section, or different output sections.

    Thanks and regards,

    -George

  • Works like a charm. Thank you for your quick and concise help. Much appreciated.

    kind regards
    Chris