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/TMS320F28379D: Linker Command File for new SFRA

Part Number: TMS320F28379D
Other Parts Discussed in Thread: SFRA, C2000WARE, CONTROLSUITE

Tool/software: TI C/C++ Compiler

I am updating a project developed in ControlSuite v160 to the latest C2000Ware and C2000Ware_DigitalPower_SDK_3_00_00_00.  Part of the updates is changing the SFRA from V1_10_00_00 to V1_40_00_00.  A lot changes between those versions and a lot of things broke.  I've managed to fix all the things that were preventing the project from building, but I am unclear about how to configure the linker cmd file.  I get a "no matching section" warning that I don't understand.

The SFRA User's Guide (SPRUIK4A–September 2018–Revised June 2019) has this example code for the cmd file:

ramfuncs : LOAD = FLASHD,
RUN = RAML0L1,
LOAD_START(_RamfuncsLoadStart),
LOAD_END(_RamfuncsLoadEnd),
RUN_START(_RamfuncsRunStart),
PAGE = 0
{
--library=sfra_f32_coff.lib<SFRA_F32_inject.obj>
--library=sfra_f32_coff.lib<SFRA_F32_collect.obj>
}
….
SFRA_F32_Data : > dataRAM1, PAGE = 1

I am running from RAM, so I don't think most of this applies.  This is what I came up with, modeled on the old command file 2837xS_RAM_DP_BoosterPack.CMD from ControlSuite project Buck_VMC_F2837xS. 

MEMORY
{
...
RAMLS1_LS2 : origin = 0x008800, length = 0x001000
// RAMLS3 : origin = 0x009800, length = 0x000800
RAMLS4 : origin = 0x00A000, length = 0x000800

...

}
SECTIONS
{

...

def __TI_COMPILER_VERSION__
#if __TI_COMPILER_VERSION__ >= 15009000
.TI.ramfunc : >> RAMLS1_LS2 | RAMLS4, PAGE = 0
{
--library=sfra_f32_coff.lib<SFRA_F32_inject.obj>     // *** LINE 72 ***
--library=sfra_f32_coff.lib<SFRA_F32_collect.obj>   // *** LINE 73 ***
}
#else
ramfuncs : >> RAMLS1_LS2 | RAMLS4, PAGE = 0
{
--library=sfra_f32_coff.lib<SFRA_F32_inject.obj>
--library=sfra_f32_coff.lib<SFRA_F32_collect.obj> }
}
#endif
#endif


//
// OLD SFRA section from F2837xS_RAM_DP_BoosterPack.CMD in project Buck_VMC_F2837xS
// ramfuncs : >> RAMLS1_LS2 | RAMLS4, PAGE = 0
// {
// --library=SFRA_F_Lib.lib<SFRA_F_INJECT.obj>
// --library=SFRA_F_Lib.lib<SFRA_F_COLLECT.obj>
// }

...

}

The linker completes but I get two warnings I don't understand:

<Linking>
"../2837x_RAM_lnk_cpu1-local.cmd", line 72: warning: no matching section
"../2837x_RAM_lnk_cpu1.cmd-local", line 73: warning: no matching section

These warnings refer to these two lines as shown above:

--library=sfra_f32_coff.lib<SFRA_F32_inject.obj>     // *** LINE 72 ***
--library=sfra_f32_coff.lib<SFRA_F32_collect.obj>   // *** LINE 73 ***

What is the meaning of "no matching section"?

  • Ciaran,

    Have you actually called an API function?  If you don't call a function in the library, nothing from the library gets pulled into the project and hence you get the no matching section warning.

    Maybe in your executable(.out) there are no direct references to that library allocated into that section, so the linker may remove it leaving the section empty. Look at the executable map file to see if the SFRA are linked.

    Regards,

    Ozino

  • Ozino,

    In the main code I have all the SFRA functions, particularly these:

    Duty1A = SFRA_F32_inject(Duty1ASetSlewed);
    //
    // Update PWM value
    //
    PWMDRV_1ch_F_C(EPwm6Regs, PWM_PERIOD, Duty1A); // in C:\ti\controlSUITE\libs\app_libs\digital_power\f28x7x_v1.0\C_macros
    SFRA_F32_collect(&Duty1A,&Adc_Vout1_b);

    I've attached the .cmd and the .map file.  I've changed the blocks around.  

    The SFRA_F32_inject.obj and SFRA_F32_collect.obj show up in the .map file, but not where I expected.  They are in the .text section:

    .text      0    00008000    00002a70  

    ...

    0000a874 00000064 sfra_f32_coff.lib : sfra_f32_collect.obj (.text)

    ...

    0000a9cd 00000026 sfra_f32_coff.lib : sfra_f32_inject.obj (.text)

    If I comment out the directives for the SFRA_F32 object modules as follows:

    .TI.ramfunc : > RAMLS1, PAGE = 0

    // {
    // --library=sfra_f32_coff.lib<SFRA_F32_inject.obj>
    // --library=sfra_f32_coff.lib<SFRA_F32_collect.obj>
    // }

    then it links without warnings, and SFRA_F32_inject.obj and SFRA_F32_collect.obj are in the same addresses in the .text section.

    I have no idea why the object files are allocated to the memory in this way.  I just copied it from the original F2837xS_RAM_DP_BoosterPack.CMD in the Buck_VMC_F2837xS project and updated the .obj file names.  The original looks like this:

    // OLD SFRA:
    ramfuncs : >> RAMLS1_LS2 | RAMLS4, PAGE = 0
    {
    --library=SFRA_F_Lib.lib<SFRA_F_INJECT.obj>
    --library=SFRA_F_Lib.lib<SFRA_F_COLLECT.obj>
    }

    Thanks,

    Ciaran

  • I get an error when I try to attach files, so no .cmd or .map files attached.

  • Try to rename the file extension of the 2 files and reupload.

    Also, I would reference the linker cmd files provided in the DP SDK solutions. You can pay particular attention to gridconnectedinvlclfltr_flash_cpu1.cmd for more information. 

  • Active_Load_CPU1_2a.map.txt

    // Modifications based on F2837xS_RAM_DP_BoosterPack.CMD in project Buck_VMC_F2837xS
    MEMORY
    {
    PAGE 0 :
      /* BEGIN is used for the "boot to SARAM" bootloader mode   */
    
       BEGIN           	: origin = 0x000000, length = 0x000002
       RAMM0           	: origin = 0x000122, length = 0x0002DE
       RAMLS0          	: origin = 0x008000, length = 0x003000
       RAMLS1      		: origin = 0x00B000, length = 0x000800
       RAMD0           	: origin = 0x00B800, length = 0x000800
       RESET           	: origin = 0x3FFFC0, length = 0x000002
    
    PAGE 1 :
    
       BOOT_RSVD       : origin = 0x000002, length = 0x000120     /* Part of M0, BOOT rom will use this for stack */
       RAMM1           : origin = 0x000400, length = 0x000400     /* on-chip RAM block M1 */
       RAMD1           : origin = 0x00B800, length = 0x000800
    
       RAMLS5      : origin = 0x00A800, length = 0x000800
    
       RAMGS0      : origin = 0x00C000, length = 0x001000
       RAMGS1      : origin = 0x00D000, length = 0x001000
       RAMGS4      : origin = 0x010000, length = 0x001000
       RAMGS5      : origin = 0x011000, length = 0x001000
       RAMGS6      : origin = 0x012000, length = 0x001000
       RAMGS7      : origin = 0x013000, length = 0x001000
       RAMGS8      : origin = 0x014000, length = 0x001000
       RAMGS9      : origin = 0x015000, length = 0x001000
       RAMGS10     : origin = 0x016000, length = 0x001000
       RAMGS11     : origin = 0x017000, length = 0x001000
       RAMGS12     : origin = 0x018000, length = 0x001000
       RAMGS13     : origin = 0x019000, length = 0x001000
       RAMGS14     : origin = 0x01A000, length = 0x001000
       RAMGS15     : origin = 0x01B000, length = 0x001000
    
       dataRAM     : origin = 0x09800, length = 0x000800		 /* on-chip RAM block LS3 */
    
       IQTABLES    : origin = 0x00E000, length = 0x000B50    /* IQ Math Tables in part of RAMGS2 */
       IQTABLES2   : origin = 0x00EB50, length = 0x00008C    /* IQ Math Tables in part of RAMGS2 */
       IQTABLES3   : origin = 0x00EBDC, length = 0x0000AA	 /* IQ Math Tables in part of RAMGS2 */
       IQMATH      : origin = 0x00EC86, length = 0x000afa	 /* IQ Math functions in part of RAMGS2 and RAMGS3 */
    //   FPUTABLES   : origin = 0x00F780, length = 0x0006A0	 /* FPU Tables in part of RAMGS2 and RAMGS3 */
       FPUTABLES   : origin = 0x00F780, length = 0x00075C	 /* FPU Tables in part of RAMGS2 and RAMGS3 */
    
       CPU2TOCPU1RAM   : origin = 0x03F800, length = 0x000400
       CPU1TOCPU2RAM   : origin = 0x03FC00, length = 0x000400
    }
    
    /* Allocate sections to memory blocks.
       Note:
             codestart user defined section in DSP28_CodeStartBranch.asm used to redirect code
                       execution when booting to flash
             ramfuncs  user defined section to store functions that will be copied from Flash into RAM
    */
    SECTIONS
    {
       /* Allocate program areas: */
       .cinit           : > RAMM0,     PAGE = 0
       .pinit           : > RAMM0,     PAGE = 0
       .text            : > RAMLS0,   PAGE = 0
       codestart        : > BEGIN       PAGE = 0
    
        .TI.ramfunc : > RAMLS1,   PAGE = 0
    //   {
    //						--library=sfra_f32_coff.lib<SFRA_F32_inject.obj>
    //						--library=sfra_f32_coff.lib<SFRA_F32_collect.obj>
    //	}
    
    //	OLD SFRA:
    //   ramfuncs         : >> RAMLS1_LS2 | RAMLS4,   PAGE = 0
    //   {
    //      					--library=SFRA_F_Lib.lib<SFRA_F_INJECT.obj>
    //   						--library=SFRA_F_Lib.lib<SFRA_F_COLLECT.obj>
    //	}
    
       /* Allocate uninitalized data sections: */
       .stack           : > RAMM1        PAGE = 1
       .ebss            : >> RAMLS5 | RAMGS0 | RAMGS1       PAGE = 1
       .esysmem         : > RAMLS5       PAGE = 1
    
       /* Initalized sections go in Flash */
       .econst          : > RAMLS5,    PAGE = 1
       .switch          : > RAMM0,     PAGE = 0
    
       .reset           : > RESET,     PAGE = 0, TYPE = DSECT /* not used, */
    
       IQmath           : > IQMATH,     PAGE = 1
       IQmathTables     : > IQTABLES,   PAGE = 1
       FPUmathTables	: > FPUTABLES, 	PAGE = 1
    
    //SECTIONS
    //{
    //   codestart        : > BEGIN,     PAGE = 0
    
    //#ifdef __TI_COMPILER_VERSION__
    //   #if __TI_COMPILER_VERSION__ >= 15009000
    //    .TI.ramfunc : {} > RAMM0,      PAGE = 0
    //   #else
    //   ramfuncs         : > RAMM0      PAGE = 0
    //   #endif
    //#endif
    
    //   .text            : >>RAMM0 | RAMD0 |  RAMLS0 | RAMLS1 | RAMLS2 | RAMLS3 | RAMLS4,   PAGE = 0
    //   .cinit           : > RAMM0,     PAGE = 0
    //   .pinit           : > RAMM0,     PAGE = 0
    //   .switch          : > RAMM0,     PAGE = 0
    //   .reset           : > RESET,     PAGE = 0, TYPE = DSECT
    
    //   .stack           : > RAMM1,     PAGE = 1
    //   .ebss            : > RAMLS5,    PAGE = 1
    //   .econst          : > RAMLS5,    PAGE = 1
    //   .esysmem         : > RAMLS5,    PAGE = 1
    //   Filter_RegsFile  : > RAMGS0,	   PAGE = 1
    
    //   ramgs0           : > RAMGS0,    PAGE = 1
    //   ramgs1           : > RAMGS1,    PAGE = 1
       
       // The following section definitions are required when using the IPC API Drivers
        GROUP : > CPU1TOCPU2RAM, PAGE = 1 
        {
            PUTBUFFER 
            PUTWRITEIDX 
            GETREADIDX 
        }
        
        GROUP : > CPU2TOCPU1RAM, PAGE = 1
        {
            GETBUFFER :    TYPE = DSECT
            GETWRITEIDX :  TYPE = DSECT
            PUTREADIDX :   TYPE = DSECT
        }  
    	
    }
    
    SECTIONS
    {
    	/*************       DPLIB Sections C28x      ************************/
    	/* ADCADRV_1ch section */
    	ADCADRV_1ch_Section				: > dataRAM				PAGE = 1
    
    	/* ADCDRV_4ch section */
    	ADCDRV_4ch_Section				: > dataRAM				PAGE = 1
    
    	/* CNTL_2P2Z section */
    	CNTL_2P2Z_Section				: > dataRAM				PAGE = 1
    	CNTL_2P2Z_InternalData			: > dataRAM				PAGE = 1
    	CNTL_2P2Z_Coef					: > dataRAM				PAGE = 1
    
    	/* CNTL_3P3Z section */
    	CNTL_3P3Z_Section				: > dataRAM				PAGE = 1
    	CNTL_3P3Z_InternalData			: > dataRAM				PAGE = 1
    	CNTL_3P3Z_Coef					: > dataRAM				PAGE = 1
    
    	/* DACDRV_RAMP section */
    	DACDRV_RAMP_Section				: > dataRAM				PAGE = 1
    
    	/*DLOG_1CH section */
    	DLOG_1ch_Section				: > dataRAM				PAGE = 1
    	DLOG_BUFF						: > dataRAM				PAGE = 1
    
    	/*MATH_EMAVG section */
    	MATH_EMAVG_Section				: > dataRAM				PAGE = 1
    
    	/*PFC_ICMD section*/
    	PFC_ICMD_Section				: > dataRAM				PAGE = 1
    
    	/*PFC_INVSQR section*/
    	PFC_INVSQR_Section				: > dataRAM				PAGE = 1
    
    	/* PWMDRV_1ch driver section */
    	PWMDRV_1ch_Section				: > dataRAM				PAGE = 1
    
    	/* PWMDRV_1chHiRes driver section */
    	PWMDRV_1chHiRes_Section			: > dataRAM				PAGE = 1
    
    	/* PWMDRV_PFC2PhiL driver section */
    	PWMDRV_PFC2PhiL_Section			: > dataRAM				PAGE = 1
    
     	/* PWMDRV_PSFB driver section */
    	PWMDRV_PSFB_Section				: > dataRAM				PAGE = 1
    
    	/* PWMDRV_DualUpDwnCnt driver section */
    	PWMDRV_DualUpDwnCnt_Section		: > dataRAM				PAGE = 1
    
    	/* PWMDRV_ComplPairDB driver section */
    	PWMDRV_ComplPairDB_Section		: > dataRAM				PAGE = 1
    
    	/* ZeroNet_Section  */
    	ZeroNet_Section					: > dataRAM				PAGE = 1
    
    	/* SFRA Data  */
    //	SFRA_F32_Data					: > dataRAM, ALIGN = 64, PAGE = 1
    	SFRA_F32_Data 					: > dataRAM, PAGE = 1
    
    }
    
    
    
    
    /*
    //===========================================================================
    // End of file.
    //===========================================================================
    */
    

  • >> Also, I would reference the linker cmd files provided in the DP SDK solutions. You can pay particular attention to gridconnectedinvlclfltr_flash_cpu1.cmd for more information. 

    That example is a flash cmd file.  It has this:

    GROUP
    {
        .TI.ramfunc
        {
         -l sfra_f32_tmu_eabi.lib
        }
        dclfuncs
    }
    LOAD = FLASHD,
    RUN = RAMLS0LS1LS2LS3LS4,
    LOAD_START(RamfuncsLoadStart),
    LOAD_SIZE(RamfuncsLoadSize),
    LOAD_END(RamfuncsLoadEnd),
    RUN_START(RamfuncsRunStart),
    RUN_SIZE(RamfuncsRunSize),
    RUN_END(RamfuncsRunEnd),
    PAGE = 0, ALIGN(4)

    This seems to be a set of instructions for loading this code from FLASH to RAM and running it there.

    Question:  Do I need any of this .TI.ramfunc stuff if I am compiling to run from RAM instead of FLASH?

  • Hi,

    TI thinks this is resolved, but I don't!  Any other advice to give?

    - The library has direct references in the code

    - The compiled object code is being placed in .text section instead of .TI.ramfunc

    - I still have a question whether .TI.ramfunc is needed for a RAM build.

    - I still have the warnings from the linker

    - This warning does not appear to cause a problem but it reveals a lack of understanding on my part that I would like to clear up.

    Thanks,

    Ciaran

  • Ciaran Brennan said:

    >> Also, I would reference the linker cmd files provided in the DP SDK solutions. You can pay particular attention to gridconnectedinvlclfltr_flash_cpu1.cmd for more information. 

    That example is a flash cmd file.  It has this:

    GROUP
    {
        .TI.ramfunc
        {
         -l sfra_f32_tmu_eabi.lib
        }
        dclfuncs
    }
    LOAD = FLASHD,
    RUN = RAMLS0LS1LS2LS3LS4,
    LOAD_START(RamfuncsLoadStart),
    LOAD_SIZE(RamfuncsLoadSize),
    LOAD_END(RamfuncsLoadEnd),
    RUN_START(RamfuncsRunStart),
    RUN_SIZE(RamfuncsRunSize),
    RUN_END(RamfuncsRunEnd),
    PAGE = 0, ALIGN(4)

    This seems to be a set of instructions for loading this code from FLASH to RAM and running it there.

    Question:  Do I need any of this .TI.ramfunc stuff if I am compiling to run from RAM instead of FLASH?

    No you don't need to specify the details listed there for the RAM builds. But the .TI.ramfunc attribute is needed regardless. You can find sample linker command files for the F2837x device in C2000Ware device_support.

  • Yes, the .TI.ramfunc attribute is needed. Can you try to link the entire SFRA library to the .TI.ramfunc attribute, instead of specific functions in the lib, and see if that fixes your issue. Something similar to below.

       GROUP: > RAMLS01234      PAGE = 0
       {
    	   .TI.ramfunc
    	   {
    	   	-l SFRA_FTMU_Lib.lib
    	   }
       }

    For more information on .TI.ramfunc you can reference section 2.3.4 of http://www.ti.com/lit/ug/spru514r/spru514r.pdf 

  • Ozino,

    Thanks for the reply.  I tried this and it worked.  No linker warning, and the map file shows the sfra objects resident in the .Ti.ramfunc section.

    It looks like this for the F28379D:

    GROUP: > RAMD0      PAGE = 0
    {
        .TI.ramfunc
        {
         -l sfra_f32_coff.lib
        }
    }

    I also want to point out that since I asked this question I've simply been using this in my .cmd file:

        .TI.ramfunc : > RAMD0,   PAGE = 0

    This also works and returns no warning, however the SFRA function loads into the .text section instead of the .TI.ramfuncs section.  This may make a difference when loading into FLASH but it doesn't seem to make a difference for a RAM-only build.

  • Ciaran,

    Glad to hear you figured how to set up your linker file. You are correct in your second observation. Thanks for sharing the feedback.

    Regards,

    Ozino