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.

TMS320F28379D: Load code to FLASH and then Run entire code from RAM.

Part Number: TMS320F28379D


Hi, I am trying to load the entire code to FLASH so that every time a power supply is disconnected, the code can start over. I am using hrpwm and other critical functions, and would like to use the RAM for the execution of various functions. Therefore, a simple option that I would work for me to run the entire code from RAM. Could you please help in resolving this issue and also help me in finding the right reference that I can follow for accomplishing the above? 

I have tried compiling the code with option 2 Release, and it throws lot of errors. So I am simply working with option 1 Debug, excluding "2837xD_RAM_lnk_cpu1.cmd" from the build and instead using this file "2837x_FLASH_lnk_cpu1.cmd" for the build. The latter is also copied below. 

In the main.c file, I am adding these few lines: 

memcpy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);

InitFlash();

Outcome: I have not been able to run the code successfully, which is verified by analyzing PWM pins that do not change state. Also, while the computer is still connected to the DSP while flashing, the code goes into this routine

interrupt void ILLEGAL_ISR(void)
{
    //
    // Insert ISR Code here
    //

    //
    // Next two lines for debug only to halt the processor here
    // Remove after inserting ISR Code
    //
    asm ("      ESTOP0");
    for(;;);
}

"2837xD_RAM_lnk_cpu1.cmd" File is copied below

MEMORY
{
PAGE 0 :  /* Program Memory */
          /* Memory (RAM/FLASH) blocks can be moved to PAGE1 for data allocation */
          /* BEGIN is used for the "boot to Flash" bootloader mode   */

   BEGIN           	: origin = 0x080000, length = 0x000002
   RAMM0           	: origin = 0x000122, length = 0x0002DE
   RAMD0           	: origin = 0x00B000, 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
   RAMGS14          : origin = 0x01A000, length = 0x001000
   RAMGS15          : origin = 0x01B000, length = 0x001000
   RESET           	: origin = 0x3FFFC0, length = 0x000002
   
   /* Flash sectors */
   FLASHA           : origin = 0x080002, length = 0x001FFE	/* on-chip Flash */
   FLASHB           : origin = 0x082000, length = 0x002000	/* 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 */
   FLASHK           : origin = 0x0B8000, length = 0x002000	/* on-chip Flash */
   FLASHL           : origin = 0x0BA000, length = 0x002000	/* on-chip Flash */
   FLASHM           : origin = 0x0BC000, length = 0x002000	/* on-chip Flash */
   FLASHN           : origin = 0x0BE000, length = 0x002000	/* on-chip Flash */   

PAGE 1 : /* Data Memory */
         /* Memory (RAM/FLASH) blocks can be moved to PAGE0 for program allocation */

   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
   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
   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

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


SECTIONS
{
   /* Allocate program areas: */
   .cinit              : > FLASHB      PAGE = 0, ALIGN(4)
   .pinit              : > FLASHB,     PAGE = 0, ALIGN(4)
   .text               : >> FLASHB | FLASHC | FLASHD | FLASHE      PAGE = 0, ALIGN(4)
   codestart           : > BEGIN       PAGE = 0, ALIGN(4)

#ifdef __TI_COMPILER_VERSION__
   #if __TI_COMPILER_VERSION__ >= 15009000
    .TI.ramfunc : {} LOAD = FLASHD,
                         RUN = RAMLS0 | RAMLS1 | RAMLS2 |RAMLS3,
                         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 = FLASHD,
                         RUN = RAMLS0 | RAMLS1 | RAMLS2 |RAMLS3,
                         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: */
   .stack              : > RAMM1        PAGE = 1
   .ebss               : >> RAMLS5 | RAMGS0 | RAMGS1       PAGE = 1
   .esysmem            : > RAMLS5       PAGE = 1

   /* Initalized sections go in Flash */
   .econst             : >> FLASHF | FLASHG | FLASHH      PAGE = 0, ALIGN(4)
   .switch             : > FLASHB      PAGE = 0, ALIGN(4)
   
   .reset              : > RESET,     PAGE = 0, TYPE = DSECT /* not used, */

   Filter_RegsFile     : > RAMGS0,	   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
    }  
    
}

/*
//===========================================================================
// End of file.
//===========================================================================
*/

  • Hello,

    To clarify your goal, you're trying to start the application from Flash and then load specific functions into RAM, correct?

    For the error that you're reaching, are you able to step through the program or set breakpoints to see where the issue is occurring? Have you verified that each function moved to RAM don't branch across RAM units (i.e. a single function does not branch between two different RAMLSx's). Also, have you verified that the program runs fine when just running from Flash or RAM? Are there any errors in doing this?

    Best regards,

    Omer Amir

  • Hello Omer, my program runs fine when running from RAM, but i do get these warnings. 

    My Goal: Have the code available in FLASH and then upon power reset the entire code should run from RAM. I will really appreciate if you could review my code which I cannot share here? Is there any direct link or your email that I can use to share my code with you? 

    My your remaining suggestions: The code breaks once it goes into ADC configurations. There was a delay DELAY_US(1000); used there which is now commented out. The code still does not run with FLASH. 

    Warning while running from RAM

    Description Resource Path Location Type
    #10247-D null: creating output section ".TI.ramfunc" without a SECTIONS specification FlashToRamCode C/C++ Problem
    #10247-D null: creating output section "DcsmZ1OtpFile" without a SECTIONS specification FlashToRamCode C/C++ Problem
    #10247-D null: creating output section "DcsmZ2OtpFile" without a SECTIONS specification FlashToRamCode C/C++ Problem
    #10247-D null: creating output section "EmuKeyVar" without a SECTIONS specification FlashToRamCode C/C++ Problem
    #10373-D null: library "../F2837xD_hrPWM/lib/SFO_v8_fpu_lib_build_c28_driverlib_eabi.lib" contains ELF object files which are incompatible with the TI-COFF output file. Ensure you are using the proper library. FlashToRamCode C/C++ Problem
    #10373-D null: library "../F2837xD_hrPWM/lib/SFO_v8_fpu_lib_build_c28_eabi.lib" contains ELF object files which are incompatible with the TI-COFF output file. Ensure you are using the proper library. FlashToRamCode C/C++ Problem
    #99922 null: C:\Users\RIARBA~1\AppData\Local\Temp\189402: Invalid CIE reference 0xffff0000 for the FDE at offset 0x000021fa in the .debug_frame section() FlashToRamCode C/C++ Problem

  • Hello,

    I've included a basic example of a way to move certain functions from Flash to RAM using the binit section to do this before main is actually called (there is no specific rule that you need to do this, but it saves some time and complexity in the program). This example is made for the F2838x device so you may have to change the names of some memory units, but otherwise it should work the same.

    MEMORY
    {
       /* BEGIN is used for the "boot to SARAM" bootloader mode   */
       BEGIN            : origin = 0x000000, 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 = 0x001000
       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 = 0x080000, length = 0x002000  /* 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 = 0x002000  /* on-chip Flash */
       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
       .binit			: > FLASH3 /* .binit will execute before main because it's in the linker file */
       .text            : >> FLASH1 | FLASH2 | FLASH3 | FLASH4
       .cinit           : > FLASH1
       .switch          : > FLASH1
       .reset           : > RESET, TYPE = DSECT /* not used, */
    
    	//
    	// Copies contents from Flash 3 to RAMLS0 and RAMLS1 (if not enough room
    	// on RAMLS0)
    	//
       .TI.ramfunc : {} LOAD = FLASH3,
                        RUN = RAMLS0 | RAMLS1,
                        table(BINIT),
                        PAGE = 0, ALIGN(4)
    
       .stack           : > RAMM1
    #if defined(__TI_EABI__)
       .bss             : > RAMLS5
       .bss:output      : > RAMGS0
       .init_array      : > RAMGS1
       .const           : >> FLASH5 | FLASH6 | FLASH7
       .data            : > RAMLS5
       .sysmem          : > RAMLS5
    #else
       .pinit           : > FLASH1
       .ebss            : >> RAMLS5 | RAMGS0 | RAMGS1
       .econst          : >> FLASH5 | FLASH6 | FLASH7
       .esysmem         : > RAMLS5
    #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
    }
    
    /*
    //===========================================================================
    // End of file.
    //===========================================================================
    */
    

    In your main code, you will also need to include "#pragma CODE_SECTION(ramCounter, ".TI.ramfunc");" to load the function "ramCounter" into the .TI.ramfunc section of memory. You can change this function with whatever functions you are using. Try to make sure you don't allocate a function in such a way that it will need to jump across RAM boundaries that aren't sequential (you can check the Disassembly view and Memory Browser to confirm this).

    Best regards,

    Omer Amir

  • Thank you Omer for all your help!

    In was able to run from RAM by

    1) including "#pragma CODE_SECTION(ramCounter, ".TI.ramfunc") as suggested above to run functions from RAM

    2) SFO as needed by HrPWM does not have a source file, so its library need to be loaded to RAM for timely execution of control loops. All I had to do was modify the linker file as copied below. You can review .map file ensuring that SFO and functions run from RAM

        .TI.ramfunc : LOAD = FLASHB | FLASHC | FLASHD | FLASHE |FLASHF | FLASHG | FLASHH, //FLASHD,
    					 RUN = RAMLS0 | RAMLS1 | RAMLS2 |RAMLS3,
    					 LOAD_START(_RamfuncsLoadStart),
    					 LOAD_SIZE(_RamfuncsLoadSize),
    					 LOAD_END(_RamfuncsLoadEnd),
    					 RUN_START(_RamfuncsRunStart),
    					 RUN_SIZE(_RamfuncsRunSize),
    					 RUN_END(_RamfuncsRunEnd),
    					 PAGE = 0, ALIGN(4)
    					 {
    					 --library=SFO_v8_fpu_lib_build_c28_coff.lib (.text)
    					 }