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.

CCSTUDIO: Linker does not place library function into .TI.ramfunc segment

Part Number: CCSTUDIO

I need to have all control functions running from LS ram block, otherwoise the control interrupt will not fit in the control period. I have defined all function to be palced into .TI.ramfunc segment: 

#ifdef RELEASE
#pragma CODE_SECTION(ADC_A1_Interrupt, ".TI.ramfunc");
#pragma CODE_SECTION(USER_Interrupt,   ".TI.ramfunc");
#pragma CODE_SECTION(Polynom,          ".TI.ramfunc");
#pragma CODE_SECTION(DigFilt1,         ".TI.ramfunc");
#pragma CODE_SECTION(VLPI,             ".TI.ramfunc");
#pragma CODE_SECTION(CVLPI,            ".TI.ramfunc");
#pragma CODE_SECTION(Lookup2D1,        ".TI.ramfunc");
#pragma CODE_SECTION(Lookup2D2,        ".TI.ramfunc");
#pragma CODE_SECTION(Limiter2D,        ".TI.ramfunc");
#pragma CODE_SECTION(CSVM,             ".TI.ramfunc");
#pragma CODE_SECTION(DacCalc,          ".TI.ramfunc");
#endif

However I found that not all function from the list above are placed in the RAM memory.
It seems that function from custom control library are not placed into the RAM. Only functions that have source code in the project are.

How do I place library functions into the RAM ?

Gasha

Here is the custom command file (since *.cmd upload is not supported):

MEMORY
{
PAGE 0 :  /* Program Memory */
   RAMM0           : origin = 0x000122, length = 0x0002DE   // .cinit .pinit .switch
/*   RAMLS0        : origin = 0x008000, length = 0x000800
 *   RAMLS1        : origin = 0x008800, length = 0x000800
 *   RAMLS2        : origin = 0x009000, length = 0x000800
 *   RAMLS3        : origin = 0x009800, length = 0x000800
 *   RAMLS4        : origin = 0x00A000, length = 0x000800
 */
   RAMLS01234      : origin = 0x008000, length = 0x002800     // .text
   RAMLS5          : origin = 0x00A800, length = 0x000800     // potentialy used by CLA
   RESET           : origin = 0x3FFFC0, length = 0x000002

#ifdef __TI_COMPILER_VERSION__
   #if __TI_COMPILER_VERSION__ >= 20012000
GROUP {      /* GROUP memory ranges for crc/checksum of entire flash */
   #endif
#endif
   /* Flash sectors */
   /* BEGIN is used for the "boot to Flash" bootloader mode   */
   BEGIN             : origin = 0x080000, length = 0x000002
//   FLASHA            : origin = 0x080002, length = 0x002000  /* on-chip Flash */
//   FLASHB            : origin = 0x082000, length = 0x002000  /* on-chip Flash */
   FLASHAB           : origin = 0x080002, length = 0x003FFE    /* on-chip Flash */
//   FLASHC            : origin = 0x084000, length = 0x002000    /* on-chip Flash */
//   FLASHD            : origin = 0x086000, length = 0x002000    /* on-chip Flash */
//   FLASHE            : origin = 0x088000, length = 0x008000    /* on-chip Flash */
//   FLASHF            : origin = 0x090000, length = 0x008000    /* on-chip Flash */
//   FLASHG            : origin = 0x098000, length = 0x008000    /* on-chip Flash */
//   FLASHH            : origin = 0x0A0000, length = 0x008000    /* on-chip Flash */
//   FLASHI            : origin = 0x0A8000, length = 0x008000    /* on-chip Flash */
//   FLASHJ            : origin = 0x0B0000, length = 0x008000    /* on-chip Flash */
   FLASHCDEFGHIJ     : origin = 0x084000, length = 0x034000    /* on-chip Flash */
   FLASHK            : origin = 0x0B8000, length = 0x002000    /* on-chip Flash */
//   FLASHL            : origin = 0x0BA000, length = 0x002000    /* on-chip Flash */
//   FLASHM            : origin = 0x0BC000, length = 0x002000    /* on-chip Flash */
   FLASHLM            : origin = 0x0BA000, length = 0x004000   /* on-chip Flash, size of RAMLS0124 is 0x2800*/
   FLASHN            : origin = 0x0BE000, length = 0x001FF0    /* on-chip Flash */
   FLASHN_DO_NOT_USE : origin = 0x0BFFF0, length = 0x000010    /* Reserved and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
   
#ifdef __TI_COMPILER_VERSION__
  #if __TI_COMPILER_VERSION__ >= 20012000
}  crc(_ccs_flash_checksum, algorithm=C28_CHECKSUM_16)
  #endif
#endif

PAGE 1 : /* Data Memory */
   BOOT_RSVD       : origin = 0x000002, length = 0x000120
   RAMM1           : origin = 0x000400, length = 0x000400    // .stack
   RAMD0           : origin = 0x00B000, length = 0x000A00    // .const
   RAMD1           : origin = 0x00BA00, length = 0x000600    // .ebss .esysmem

   RAMGS0          : origin = 0x00C000, length = 0x001000
   RAMGS1          : origin = 0x00D000, length = 0x001000
   RAMGS2          : origin = 0x00E000, length = 0x001000
   RAMGS3          : origin = 0x00F000, 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  // Assigned to Core 2
//   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

   CPU2TOCPU1RAM   : origin = 0x03F800, length = 0x000400
   CPU1TOCPU2RAM   : origin = 0x03FC00, length = 0x000400
}

SECTIONS
{
   /* Allocate program areas: */
   .reset         : > RESET,          PAGE = 0, TYPE = DSECT /* not used, */
   codestart      : > BEGIN,          PAGE = 0, ALIGN(4)
   .cinit         : > FLASHAB,        PAGE = 0, ALIGN(4)  /* Initilized global and static variables */
   .pinit         : > FLASHAB,        PAGE = 0, ALIGN(4)  /* Tables of constructor, C++ only, otherwise empty */
   .switch        : > FLASHAB,        PAGE = 0, ALIGN(4)  /* Tables for switch statements */
   .text          : > FLASHCDEFGHIJ,  PAGE = 0, ALIGN(4)  /* Executable code and constants */
    /* Initalized sections go in Flash */
//   .econst        : > FLASHK,    PAGE = 0, ALIGN(4)  /* Constant variables Legacy COFF*/
//                      RUN = RAMD0,
//                      LOAD_START(RamConstLoadStart),
//                      LOAD_SIZE(RamConstLoadSize),
//                      LOAD_END(RamConstLoadEnd),
//                      RUN_START(RamConstRunStart),
//                      RUN_SIZE(RamConstRunSize),
//                      RUN_END(RamConstRunEnd)

#ifdef __TI_COMPILER_VERSION__
   #if __TI_COMPILER_VERSION__ >= 15009000
    .TI.ramfunc : {}  load = FLASHLM,                  /* Executable code that runs from RAM */
                      run = RAMLS01234,
                      LOAD_START(RamFuncsLoadStart),
                      LOAD_SIZE(RamFuncsLoadSize),
                      LOAD_END(RamFuncsLoadEnd),
                      RUN_START(RamFuncsRunStart),
                      RUN_SIZE(RamFuncsRunSize),
                      RUN_END(RamFuncsRunEnd),
                      PAGE = 0, ALIGN(4)
   #else
   ramfuncs :         LOAD = FLASHLM,
                      RUN = RAMLS01234,
                      LOAD_START(RamFuncsLoadStart),
                      LOAD_SIZE(RamFuncsLoadSize),
                      LOAD_END(RamFuncsLoadEnd),
                      RUN_START(RamFuncsRunStart),
                      RUN_SIZE(RamFuncsRunSize),
                      RUN_END(RamFuncsRunEnd),
                      PAGE = 0, ALIGN(4)
   #endif
#endif

   /* Allocate uninitalized data sections: */
   .init_array      : > RAMM0,       PAGE = 0  /* Tables of constructor, C++ only, otherwise empty */
   .stack           : > RAMM1        PAGE = 1  /* Obviusly stack space, size set in project C2000Linker-> Basic Options */
   .bss             : > RAMD1        PAGE = 1  /* Uninitilized global and static variables, WARNING: not initilized to zero */
      {
         start_of_bss = .;
           *(.bss)
         end_of_bss = .;
//         {START(start_of_bss) END(end_of_bss)}
      }
   .sysmem          : > RAMD1,       PAGE = 1  /* Heap space, Memory for malloc type functions */
   .const           : > RAMD0,       PAGE = 1  /* Constant variables */
   .data            : > RAMD0,       PAGE = 1  /* Constant variables */
//   .esysmem       : > RAMD1      PAGE = 1  /* Heap space, Memory for malloc type functions */
//   Filter_RegsFile     : > RAMGS0,      PAGE = 1
   ramgs15        : > RAMGS15,   PAGE = 1

   SHARERAMGS0    : > RAMGS0,    PAGE = 1
   SHARERAMGS1    : > 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
   }

   /* crc/checksum section configured as COPY section to avoid including in executable */
   .TI.memcrc          : type = COPY
}
//===========================================================================
// End of file.
//===========================================================================

 

  • How do I place library functions into the RAM ?

    A #pragma cannot affect a library function, because it is already compiled.  The only way to control allocation of code from a library is in the linker command file.  Please search the article Linker Command File Primer for the sub-part titled Allocate an Input Section from a Library to Different Load and Run Addresses.

    Thanks and regards,

    -George

  • George,


    I am still confused with <ipc.obj> parameter in the example you refred too:

    ipcConst { driverlib.lib<ipc.obj>(.const) }
    LOAD = FLASH5, RUN = RAMLS0,
    LOAD_START(constLoadStart),
    LOAD_SIZE(constLoadSize),
    RUN_START(constRunStart), ALIGN(8)

    The description says following:

    This forms an output section named ipcConst. It contains one input section named .const.
    That input section comes from the object file ipc.obj, which is a member of the library driverlib.lib.

    My library is called "PowerLibraryTi.lib". The library is compiled from one C file called "Func.c".

    I found that in the library project folder "Debug/src", there is a file  "Func.obj". 

    Is this correct considering my custom cmd file above ?

    LibFunc { PowerLibrayTI.lib<Func.obj>(.LibFuncSection) }
    LOAD = FLASHLM, RUN = RAMLS01234,
    LOAD_START(LibFuncSectionStart),
    LOAD_SIZE(LibFuncSectionSize),
    RUN_START(LibFuncSectionStart), ALIGN(8)

    As an alternative approach, i found that if I create Release version of the library, put pragmas for every function
    that exist in the library in the library source "Func.c" which are compiled in RELEASE only, point to release version of the
    library for RELEASE version of the project, it works.

    In the "Func.c" source:

    #ifdef RELEASE
    #pragma CODE_SECTION(DigFilt1,         ".TI.ramfunc");

    . . . 

    #endif

    The problem with these approaches is that I have no choice what stays in the flash and what gets relocated to ram.
    Delfino does not have much ram for zero wait state program execution and sometimes I need to select what library functions I want to be
    relocated to ram (most critical ones) and what functions can stay in flash. Is there a way to do that?

    Thank you.

    Slobodan

  • My library is called "PowerLibraryTi.lib". The library is compiled from one C file called "Func.c".

    While it is possible a library only contains one object file, it is not typical.  Are you sure this is really a library?

    It would easier to make Func.c yet another source file in the project.  Then use #pragma in it just like you do on other source files.

    Thanks and regards,

    -George