TMS320F28388D: Inquiry regarding memory section placement: Maintaining declaration order for variables in a custom DATA_SECTION

Part Number: TMS320F28388D

To the TI Support Team,

I am currently working on a project involving an external flash to store configurable parameters. To manage these parameters, I am using the #pragma DATA_SECTION directive to place variables into a specific named section (e.g., .TRIMSECTION), which is then mapped to a specific RAM range in my .cmd linker command file.

The Issue: I have noticed that the compiler/linker does not preserve the sequence of variables as they are declared in the .c source file. Instead, it appears to be reordering them based on data type (e.g., grouping uint16_t together before float or uint32_t).

This reordering is problematic because our external flash mapping relies on a consistent memory offset. When new parameters are added, the linker inserts them into the middle of the section based on their type, shifting the addresses of existing parameters and causing data mismatches after firmware updates.

Evidence: As shown in the attached map file screenshots:

  • Case A: Existing parameters like gc_crank_engage_time_cont were followed by battery_voltage_cal_value.

  • Case B: After adding amf_start_type and CB_selection, these were automatically placed at addresses 0x0001B013 and 0x0001B014 (following the other 16-bit/8-bit types), which shifted the subsequent float variables.

Question: Is there a specific compiler flag or linker attribute in the TI ARM/C2000 toolchain that forces the linker to maintain the source declaration order within a named section?

Constraint Note: We are aware that wrapping these parameters in a struct would enforce the order; however, due to strict memory constraints and the overhead involved in our current implementation, we would prefer a linker-level solution that allows us to keep individual variables while guaranteeing their sequence.

Environment:

  • Compiler: ti-cgt-c2000_22.6.1.LTS

  • IDE: Code Composer Studio [CCS]

  • Device: TMS320F28388D

Thank you for your assistance.

IMG-20260226-WA0005.jpg

IMG-20260226-WA0004.jpgScreenshot 2026-02-26 134049.png

  • Hi Ramakrishna, 

    Can you also share me the linker cmd file for reference. I can check how you have mapped these pragma locations to section in the linker cmd file.

    Thanks

    Aswin

  • Please find the attached linker command file (.cmd) for your review. This file contains the memory section definitions and the mapping for the .TRIMSECTION mentioned in my previous post. Due to some issues while inserting .cmd file,I chnaged the extension to .txt and have uploaded it below.

    MEMORY
    {
       /* BEGIN is used for the "boot to Flash" bootloader mode   */
       BEGIN            : origin = 0x080000, length = 0x000002
       BOOT_RSVD        : origin = 0x000002, length = 0x0001AF     /* Part of M0, BOOT rom will use this for stack */
       RAMM0            : origin = 0x0001B1, length = 0x00024F
       RAMM1            : origin = 0x000400, length = 0x0003F8     /* on-chip RAM block M1 */
    //   RAMM1_RSVD       : origin = 0x0007F8, length = 0x000008     /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
       RAMD0            : origin = 0x00C000, length = 0x000800
       RAMD1            : origin = 0x00C800, length = 0x000800
       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
       RAMLS5           : origin = 0x00A800, length = 0x000800
       RAMLS6           : origin = 0x00B000, length = 0x000800
       RAMLS7           : origin = 0x00B800, length = 0x000800
       RAMGS0           : origin = 0x00D000, length = 0x001000
       RAMGS1           : origin = 0x00E000, length = 0x001000
       RAMGS2           : origin = 0x00F000, length = 0x001000
       RAMGS3           : origin = 0x010000, length = 0x001000
       RAMGS4           : origin = 0x011000, length = 0x001000
       RAMGS5           : origin = 0x012000, length = 0x002000
       //RAMGS6           : origin = 0x013000, length = 0x001000
       RAMGS7           : origin = 0x014000, length = 0x001000
       RAMGS8           : origin = 0x015000, length = 0x001000
       RAMGS9           : origin = 0x016000, length = 0x001000
       RAMGS10          : origin = 0x017000, length = 0x001000
       RAMGS11          : origin = 0x018000, length = 0x001000
       RAMGS12          : origin = 0x019000, length = 0x001000
       RAMGS13          : origin = 0x01A000, length = 0x001000
       RAMGS14          : origin = 0x01B000, length = 0x001000
       RAMGS15          : origin = 0x01C000, length = 0x000FF8
    //   RAMGS15_RSVD     : origin = 0x01CFF8, length = 0x000008     /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
    
       /* Flash sectors */
       FLASH0           : origin = 0x080002, length = 0x001FFE  /* on-chip Flash */
       FLASH1           : origin = 0x082000, length = 0x002000  /* on-chip Flash */
       FLASH2           : origin = 0x084000, length = 0x002000  /* on-chip Flash */
       FLASH3           : origin = 0x086000, length = 0x002000  /* on-chip Flash */
       FLASH4           : origin = 0x088000, length = 0x008000  /* on-chip Flash */
       FLASH5           : origin = 0x090000, length = 0x008000  /* on-chip Flash */
       FLASH6           : origin = 0x098000, length = 0x008000  /* on-chip Flash */
       FLASH7           : origin = 0x0A0000, length = 0x008000  /* on-chip Flash */
       FLASH8           : origin = 0x0A8000, length = 0x008000  /* on-chip Flash */
       FLASH9           : origin = 0x0B0000, length = 0x008000  /* on-chip Flash */
       FLASH10          : origin = 0x0B8000, length = 0x002000  /* on-chip Flash */
       FLASH11          : origin = 0x0BA000, length = 0x002000  /* on-chip Flash */
       FLASH12          : origin = 0x0BC000, length = 0x002000  /* on-chip Flash */
       FLASH13          : origin = 0x0BE000, length = 0x001FF0  /* on-chip Flash */
    //   FLASH13_RSVD     : origin = 0x0BFFF0, length = 0x000010  /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
    
       CPU1TOCPU2RAM   : origin = 0x03A000, length = 0x000800
       CPU2TOCPU1RAM   : origin = 0x03B000, length = 0x000800
       CPUTOCMRAM      : origin = 0x039000, length = 0x000800
       CMTOCPURAM      : origin = 0x038000, length = 0x000800
    
       CANA_MSG_RAM     : origin = 0x049000, length = 0x000800
       CANB_MSG_RAM     : origin = 0x04B000, length = 0x000800
    
       RESET            : origin = 0x3FFFC0, length = 0x000002
    }
    
    SECTIONS
    {
       codestart           : > BEGIN, ALIGN(8)
       .text               : >> FLASH1 | FLASH2 | FLASH3 | FLASH4 | FLASH6, ALIGN(8)
       .cinit              : > FLASH7, ALIGN(8)
       .switch             : > FLASH1, ALIGN(8)
       .reset              : > RESET, TYPE = DSECT /* not used, */
       .stack              : > RAMD0
       //.flash_data		   : > RAMGS15, type=NOINIT
    
       .TRIMSECTION : > RAMGS14, ALIGN(8)
       {
    		__TRIMSECTION_start = .;   	   /* start address */
    		*(.TRIMSECTION)
    		__TRIMSECTION_end = .;
       }
       .AUTOTRIMSECTION : > RAMGS15, ALIGN(8)
       {
       		__AUTOTRIMSECTION_start = .;
    	  	*(.AUTOTRIMSECTION)
    	  	__AUTOTRIMSECTION_end = .;
       }
    /*   .MONSECTION : > RAMGS14, ALIGN(8)
       {
          	__MONSECTION_start = .;
          	*(.MONSECTION)
          	__MONSECTION_end = .;
       }*/
    
       isrcodefuncs :
    	{
    	    . = ALIGN(8);
    	    *(isrcodefuncs)
    	    . = ALIGN(8);
    	} > FLASH0
    
    #if defined(__TI_EABI__)
       .init_array      : > FLASH1, ALIGN(8)
       .bss             : >> RAMGS11 | RAMGS12
       .bss:output      : > RAMLS3
       .bss:cio         : > RAMLS5
       .data            : >> RAMGS5 | RAMGS7 | RAMGS8 | RAMGS9
       .sysmem          : > RAMGS10
       /* Initalized sections go in Flash */
       .const           : > FLASH5, ALIGN(8)
    #else
       .pinit           : > FLASH1, ALIGN(8)
       .ebss            : > RAMLS5
       .esysmem         : > RAMLS5
       .cio             : > RAMLS5
       /* Initalized sections go in Flash */
       .econst          : >> FLASH4 | FLASH5, ALIGN(8)
    #endif
    
       ramgs0 : > RAMGS0, type=NOINIT
       ramgs1 : > RAMGS1, type=NOINIT
       
       MSGRAM_CPU1_TO_CPU2 : > CPU1TOCPU2RAM, type=NOINIT
       MSGRAM_CPU2_TO_CPU1 : > CPU2TOCPU1RAM, type=NOINIT
       MSGRAM_CPU_TO_CM    : > CPUTOCMRAM, type=NOINIT
       MSGRAM_CM_TO_CPU    : > CMTOCPURAM, type=NOINIT
    
       /* The following section definition are for SDFM examples */
       Filter_RegsFile  : > RAMGS0
       Filter1_RegsFile : > RAMGS1, fill=0x1111
       Filter2_RegsFile : > RAMGS2, fill=0x2222
       Filter3_RegsFile : > RAMGS3, fill=0x3333
       Filter4_RegsFile : > RAMGS4, fill=0x4444
       Difference_RegsFile : >RAMGS5, fill=0x3333
    
       #if defined(__TI_EABI__)
           .TI.ramfunc : {} LOAD = FLASH3,
                            RUN = RAMLS0 | RAMLS1 | RAMLS2 |RAMLS3,
                            LOAD_START(RamfuncsLoadStart),
                            LOAD_SIZE(RamfuncsLoadSize),
                            LOAD_END(RamfuncsLoadEnd),
                            RUN_START(RamfuncsRunStart),
                            RUN_SIZE(RamfuncsRunSize),
                            RUN_END(RamfuncsRunEnd),
                            ALIGN(8)
       #else
           .TI.ramfunc : {} LOAD = FLASH3,
                            RUN = RAMLS0 | RAMLS1 | RAMLS2 |RAMLS3,
                            LOAD_START(_RamfuncsLoadStart),
                            LOAD_SIZE(_RamfuncsLoadSize),
                            LOAD_END(_RamfuncsLoadEnd),
                            RUN_START(_RamfuncsRunStart),
                            RUN_SIZE(_RamfuncsRunSize),
                            RUN_END(_RamfuncsRunEnd),
                            ALIGN(8)
       #endif
    
    }
    
    /*
    //===========================================================================
    // End of file.
    //===========================================================================
    */
    

  • Let me loop linker experts, i don't see an issue with the linker cmd file.

  • Thank you for looping in an expert. Our development is currently at a standstill due to this blocker, so any assistance in expediting a resolution would be greatly appreciated as we approach our production deadline. We are ready to provide any further logs or files required.

  • Please consider using one of the methods described in the article Methods to Force an Ordering of Global Variables.

    Thanks and regards,

    -George