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.

TMS320C6678: Linking code to internal memory

Part Number: TMS320C6678

I have created a project based on the example code at ipc_3_50_04_08\examples\C6678_bios_elf\ex11_ping.
It is a makefile project and it uses TI-RTOS, RTSC and the platrorm ti.platforms.evm6678.


The file config.bld configures code to be linked into external DDR3 memory:

var SR_0 = {
    name: "SR_0", space: "data", access: "RW",
    base: 0x84000000, len: 0x200000,
    comment: "SR#0 Memory (2 MB)"
};

Build.platformTable["ti.platforms.evm6678:core0"] = {
    externalMemoryMap: [
        [ "CORE0_PROG", {
            name: "CORE0_PROG", space: "code/data", access: "RWX",
            base: 0x80000000, len: 0x1000000,
            comment: "CORE0 Program Memory (16 MB)"
        }],
        [ "SR_0", SR_0 ]
    ],
    codeMemory: "CORE0_PROG",
    dataMemory: "CORE0_PROG",
    stackMemory: "CORE0_PROG"
};

Now I need to link some of the code into internal memory. (For example, DDR3 memory test should be run from internal memory so that it won't trash its own code.)

I have a linker command file that is appended by makefile to the automatically generated linker.cmd file during the build process.
The file contains lines like:

SECTIONS
{
.dsp2hostmailbox > MSMCSRAM
.host2dspmailbox > MSMCSRAM
.tsipData > L2SRAM
...
}

With it, I have been able to link some data segments to required memory areas. But that does not work with code.

What I have tried so far:

 - Use  #pragma CODE_SECTION  in  the C code and add section for that as above.
 - Add the following line in the extra linker command file:  memtest.oe66 > MSMCSRAM.

But these do not work.
The reason may be that the automatically generated linker.cmd file contains a line
  .text: load >> CORE0_PROG 

So all the code is loaded to DDR3 and that can not be changed afterwards in the additional linker command file.
Is there any way to override this?

  • Pauli,

    Let me look at it and get back.

    Regards

    Shankari G

  • Pauli,

    Please have a look at these links below. It might help.

    https://software-dl.ti.com/ccs/esd/documents/sdto_cgt_Linker-Command-File-Primer.html

    ---

    To over-ride the linker.cmd , the following option shall also be used in CCS --- > Help contents of CCS 

    5.1.3. Disabling the Linker (--compile_only Compiler Option)

    You can override the --run_linker option by using the --compile_only compiler option. The -run_linker option's short form is -z and the --compile_only option's short form is -c.

    The --compile_only option is especially helpful if you specify the --run_linker option in the C6X_C_OPTION environment variable and want to selectively disable linking with the --compile_only option on the command line.

    7.3. Invoking the Linker

    • Now you can invoke the linker from the command line; specify the command filename as an input file:

    •    cl6x --run_linker linker.cmd

    ---

    And also, go to the help contents in CCS ---> Search the text --> "linker" ---> Dynamic linking sections...

    ----

    Alternately, in CCS --> project properties, you can remove the linker.cmd, if any, linked to the project

     

    Regards

    Shankari G

  • The problem is that the linker command file (linker.cmd) is generated automatically by RTSC, so I can not change it.


    According to the 'TI Linker Command File Primer', specific object files can be linked to specific memory area if this definition is done BEFORE the line '.text: load >> CORE0_PROG'. But there is no way to do that since the linker.cmd file is generated automatically.


    So I am asking if there is a way to configure this for example with some definitions in the config.bld file.

  • Pauli,

    I am not very sure whether I understood your issue.

    But I have another suggestion for you.

    There is a working IPC example for C6678 in Processor SDK 6.3 -software -package. 

    I have exclusively created an FAQ on how to build the IPC example and run on the C6678 EVM board.

    It is always good to start with something already working.

    Please have a look at this FAQ and the image processing demo example used there and its config.bld etc..

    https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1070386/faq-tms320c6678-how-to-build-and-run-the-ipc-image-processing-demo-on-c6678

    Regards

    Shankari G

  • Thank you for your reply.

    I did look at the example you mentioned, but it is quite complex. And we do not use Ethernet in our project. I have based our project on the IPC ping example, as I mentioned before.

    The issue is that we need to link some of the code into internal memory (either MSMCSRAM or cores internal L2 SRAM). Most of the code is linked into external DDR3 RAM. However, when using RTSC, all the code has to be linked in one place, either DDR3 or internal memory. The only segments that can be defined are code, data and stack.

    In traditional projects, the programmer can configure the segments using linker command file. However, in RTSC projects, the linker.cmd file is generated by the XDC tools. In the IPC example, the makefile generates the libraries and linker command file with the following command:

    %/compiler.opt: %/linker.cmd ;
    %/linker.cmd: Core0.cfg ../shared/config.bld
    @$(ECHO) "#"
    @$(ECHO) "# Making $@ ..."
    $(XDC_INSTALL_DIR)/xs --xdcpath="$(subst +,;,$(PKGPATH));." \
    xdc.tools.configuro -o $(CONFIG) \
    -t ti.targets.elf.C66 \
    -c $(ti.targets.elf.C66) \
    -p ti.platforms.evm6678:core0 \
    -b ../shared/config.bld -r release \
    --cfgArgs "{ \
    procList: \"$(PROCLIST)\", \
    profile: \"$(PROFILE)\" \
    }" Core0.cfg

    The options for this are configured with files Core0.cfg, config.bld and ipc.cfg.xs.

    But there seems to be no options to configure any other segments than code, data and stack. So there is no way to link some of the code into external DDR3 and some of the code into internal SRAM.

  • Pauli,

    Thanks for the detailed explanation.

    Let me have a closer look and get back.

    Regards

    Shankari G

  • Pauli,

    I experimented the same. This is what I did. Please check whether it suffice for you.

    Manually, you can modify the linker.cmd and rebuild. I could change it manually and rebuilt and verified whether that the  changes remained. 

    Steps:

    =====

    Step 1:


    1. Open the linker.cmd in CCS, located at "C:\ti\ipc_3_50_04_08\examples\C6678_bios_elf\ex11_ping\core0\bin\release\configuro" --- > 

    I did some sample modification like below:

    SECTIONS
    {
    /* .text: load >> CORE0_PROG */    /* -------> commented out ----> Please note: CORE0_PROG also points to the DDR3 memory address only in the memory sections above in the same linker.cmd file  .  the CORE0_PROG (RWX) : org = 0x80000000, len = 0x800000

    .text: load >> L2SRAM   /* ---> You can change this to  Internal L2SRAM and rebuild */ 


    .ti.decompress: load > CORE0_PROG
    .stack: load > CORE0_PROG
    GROUP: load > CORE0_PROG
    {
    .bss:
    .neardata:
    .rodata:
    }
    .cinit: load > CORE0_PROG
    .pinit: load >> CORE0_PROG
    .init_array: load > CORE0_PROG
    .const: load >> CORE0_PROG
    .data: load >> CORE0_PROG
    .fardata: load >> CORE0_PROG
    .switch: load >> CORE0_PROG
    .sysmem: load > CORE0_PROG
    .far: load >> CORE0_PROG
    .args: load > CORE0_PROG align = 0x4, fill = 0 {_argsize = 0x64; }
    .cio: load >> CORE0_PROG
    .ti.handler_table: load > CORE0_PROG
    .c6xabi.exidx: load > CORE0_PROG
    .c6xabi.extab: load >> CORE0_PROG
    .vecs: load > CORE0_PROG
    xdc.meta: load > CORE0_PROG, type = COPY

    }

    -------------------

    STEP 2: 

    2. Memory sections in the linker.cmd --- > Can also be modified.

    For example:- To include the MSMC RAM and DDR3

    /* Memory Map 1 - the default */
    MEMORY
    {
    L1PSRAM (RWX) : org = 0x0E00000, len = 0x7FFF
    L1DSRAM (RWX) : org = 0x0F00000, len = 0x7FFF

    L2SRAM (RWX) : org = 0x0800000, len = 0x080000
    MSMCSRAM (RWX) : org = 0xc000000, len = 0x200000
    DDR3 (RWX) : org = 0x80000000,len = 0x10000000
    }

    The below is the existing memory sections in linker.cmd loacted at "C:\ti\ipc_3_50_04_08\examples\C6678_bios_elf\ex11_ping\core0\bin\release\configuro"

    MEMORY
    {
    L2SRAM (RWX) : org = 0x800000, len = 0x80000
    MSMCSRAM (RWX) : org = 0xc000000, len = 0x400000
    CORE0_PROG (RWX) : org = 0x80000000, len = 0x800000
    SR_0 (RW) : org = 0x84000000, len = 0x200000
    }

    STEP3:-  Rebuild

    > gmake install

    STEP 4: Check whether the changes remain same.

    Regards

    Shankari G

  • Unfortunately editing linker.cmd file manually is not an option. We are using Continuous Integration server that builds the SW every time a new commit is pushed to Git, so the build process must be fully automatic.

    Further, I do not want to link all of the code into internal memory,  only those functions that need to be in internal memory. The whole application wouldn't even fit in the internal memory.

    I was hoping that there had been some option to define the segments for example in the file config.bld. But I guess that is not possible.

  • I was hoping that there had been some option to define the segments for example in the file config.bld. But I guess that is not p

    Config.bld is the one which should not be edited manually. But Linker.cmd shall be edited manually and rebuilt.

    After editing - Linker.cmd,when you rebuild, it will not get replaced. The changes will remain there. You could even check and verify as I verified in my above posts.

    Further, I do not want to link all of the code into internal memory,  only those functions that need to be in internal memory. The whole application wouldn't even fit in the internal memory

    You need not link all the code to the internal memory. You can link to the external DDR3 memory.

    I just gave you an example, how to change the memory segments in the Linker.cmd.

    According to your application size and requirement, you can change the memory segments in linker.cmd. That too for every core....

    Regards

    Shankari G

  • Pauli,

    Did you try modifying the linker.cmd and rebuilt?

    Did you notice the changes remains the same without getting replaced?

    Regards

    Shankari G

  • Config.bld is the file that needs to be edited if new memory areas are needed in addition to those specified in platform. That is how the shared region SR_0 was defined in the IPC PING example, see  C:\ti\ipc_3_50_04_08\examples\C6678_bios_elf\ex11_ping\shared\config.bld.

    As I said, manually editing linker.cmd after every software change is not an option.

    Make doesn't know if linker.cmd file has been edited manually or is it generated. In the IPC PING example, linker.cmd file is re-build if Core0.cfg or config.bld has been changed (and ipc.cfg should be listed as prerequisite, too). And also, of course, if  make clean  is executed, since that deletes the whole binary folder, including the configuro folder. And our CI server always does a clean build.

    But then I copied linker.cmd to another directory that is not emptied by make clean. I edited it there, and added a command in the makefile to copy the manually edited linker.cmd to the configuro folder. This works on my computer (except that one has to remember to edit linker.cmd file again if some configuration changes are made). But it is not portable.

    The linker.cmd file contains absolute paths to configuro folder (which is in different place for each developer) and to TI libraries (which may be installed in different places). In addition, some users and the CI server use Linux, where the paths are totally different.

    I had earlier made an extra linker command file that is appended to linker.cmd by the makefile.  It is used to link segments to specified memory areas. But this only works with data segments, not with code segments. Maybe because all code is linked into .text section.

    However, now I found at least a partial solution.

    We have made a custom platform library that is compiled separately and added as a library to the application. If I define a segment (e.g. .platform_memtest) there, it can then be linked to one of the existing memory areas with a definition in the extra linker command file, e.g.

      .platform_memtest  >    MSMCSRAM

    This can not be done for segments defined in the application, and it is not possible to specify start address of the segment. But this may be enough for our purposes.

    -- Pauli