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: Custom bootloader can't jump to programmed app main

Part Number: TMS320F28379D

Hello,

I have done a custom bootloader application with the next linker command file (all initialized sections are located into FLASHL sector):

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
   RAMLS03          : origin = 0x008000, length = 0x002000
/*	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              : > FLASHL      PAGE = 0
   .pinit              : > FLASHL,     PAGE = 0
   .text               : >> FLASHL      PAGE = 0
   codestart           : > BEGIN	PAGE = 0
 
#ifdef __TI_COMPILER_VERSION__
    #if __TI_COMPILER_VERSION__ >= 15009000
        GROUP
        {
            .TI.ramfunc
            { -l F021_API_F2837xD_FPU32.lib}
         
        } LOAD = FLASHL,
          RUN  = RAMLS03, 
          LOAD_START(_RamfuncsLoadStart),
          LOAD_SIZE(_RamfuncsLoadSize),
          LOAD_END(_RamfuncsLoadEnd),
          RUN_START(_RamfuncsRunStart),
          RUN_SIZE(_RamfuncsRunSize),
          RUN_END(_RamfuncsRunEnd),
          PAGE = 0    
    #else
        GROUP
        {
            ramfuncs
            { -l F021_API_F2837xD_FPU32.lib}
         
        } LOAD = FLASHL,
          RUN  = RAMLS03, 
          LOAD_START(_RamfuncsLoadStart),
          LOAD_SIZE(_RamfuncsLoadSize),
          LOAD_END(_RamfuncsLoadEnd),
          RUN_START(_RamfuncsRunStart),
          RUN_SIZE(_RamfuncsRunSize),
          RUN_END(_RamfuncsRunEnd),
          PAGE = 0    
    #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             : >> FLASHH       PAGE = 0
   .switch             : > FLASHL      PAGE = 0

   .reset              : > RESET,     PAGE = 0, TYPE = DSECT /* not used, */

   Filter_RegsFile     : > RAMGS0,	   PAGE = 1

   SHARERAMGS0		: > RAMGS0,		PAGE = 1
   SHARERAMGS1		: > RAMGS1,		PAGE = 1

   /* Flash Programming Buffer */
   BufferDataSection : > RAMD1, PAGE = 1, ALIGN(4)   
   
   /* 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
    }  

}

This bootloader application basically gets another application binary. This other application has the next linker command file (all initialized sections located in FLASHB sector):

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 = 0x082000, 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     /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
   RAMGS15          : origin = 0x01B000, length = 0x001000     /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
   RESET           	: origin = 0x3FFFC0, length = 0x000002

   /* Flash sectors */
   FLASHA           : origin = 0x080000, length = 0x002000	/* on-chip Flash */
   FLASHB           : origin = 0x082002, length = 0x001FFE	/* 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     /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
   RAMGS13     : origin = 0x019000, length = 0x001000     /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */

   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      PAGE = 0, ALIGN(4)
   codestart           : > BEGIN       PAGE = 0, ALIGN(4)

   /* Allocate uninitalized data sections: */
   .stack              : > RAMM1        PAGE = 1
   .ebss               : >> RAMLS5 | RAMGS0 | RAMGS1       PAGE = 1
   .esysmem            : > RAMLS5       PAGE = 1

   /* Initalized sections go in Flash */
   .econst             : >> FLASHB      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
   ramgs0           : > RAMGS0,     PAGE = 1
   ramgs1           : > RAMGS1,     PAGE = 1

#ifdef __TI_COMPILER_VERSION__
	#if __TI_COMPILER_VERSION__ >= 15009000
	.TI.ramfunc : {} LOAD = FLASHB,
						 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 = FLASHB,
                         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

   /* 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
    }

   /* The following section definition are for SDFM examples */
   Filter1_RegsFile : > RAMGS1,	PAGE = 1, fill=0x1111
   Filter2_RegsFile : > RAMGS2,	PAGE = 1, fill=0x2222
   Filter3_RegsFile : > RAMGS3,	PAGE = 1, fill=0x3333
   Filter4_RegsFile : > RAMGS4,	PAGE = 1, fill=0x4444
   Difference_RegsFile : >RAMGS5, 	PAGE = 1, fill=0x3333
}

I am working in EMULATE mode (with intentions to work in STANDALONE mode, but for now I need to debug so I think it is better to work in EMULATE mode, with programmer/debugger connected). Then I program (through programmer/debugger) bootloader application and it starts executing. It does the next steps:

- Get the new application binary.

- Erase (through FAPI) FLASHB sector.

- Program (through FAPI) the new application binary starting from address 0x082000 (FLASHB initial address). The new application takes more or less the half of the sector (~4 Kwords).

- Long Branch to new application by executing this line of code:

asm (" LB 0x082000");

THE PROBLEM: once, this assembler line is executed the code jumps to 0x082000 address and from there it jumps to 0x080000 (FLASHA initial address) where codestart section from bootloader applications is located. Then it jumps to RTS and from there it jumps to bootloader application main. So, instead of jumping to new application main, I am jumping AGAIN to bootloader application main.

I think the problem might be how I generate the new application binary. I do it through C2000 hex utility with CCS. The settings I use with this utility are: "--intel --binary". I know there are options like generate a boot table, but this is to use SCI bootloader protocol which is not my intention. I need the binary bytes which must directly be programmed into FLASH and I thought that "--binary" option is the right one. Am I right?

Can anyone help me?

Thanks in advance!

Best regards,

Adria

  • Hello,

    Concerned experts have been notified of this query.

    Note that it is Thanksgiving week in US and most of the TI engineers are away.

    Please expect a delayed response, surely by early next week.

     

    Regards,

    Sudhakar

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

    If a post answers your question, please mark it with the "verify answer" button.

    Other useful links:

    C2000 Getting Started      C2000 Flash Common Issues/FAQs      Emulation FAQ

  • Hi Sudhakar,

    Thanks for letting me know that.

    Best regards,

    Adria

  • Adria

    Binary should be fine. You don't have to specific "-intel". The bootloader application BEGIN will jump to the bootloader application. Your bootloader needs to return the address you should jump to or hard code in your bootloader. If I am not fully understanding your issue, please provide more detail or possibly a flow diagram.

    Best regards
    Chris
  • Hi Christopher,

    I have no problem executing my bootloader application, it successfully does it. The problem comes when I want to, from bootloader code, execute the other application. I am not able to do this through a Long Branch to 0x082000 address, is it the right way to do it? If no, please tell me how to do that?

    Best regards,

    Adria
  • Adria

    Yes, that is the correct way. You should ideally always call the other's code_start (which is what your long branch would do) which branches to the RTS int_00. Each app should have their own code_start location and associated RTS code. This shouldn't be shared.

    Likely not related to the issue, but your bootloader linker is also using FLASHH for econst.

    Best regards
    Chris
  • Hi Christopher,

    Let's summarize what is going on:

    - Power ON

    - Reset vector is fetched.

    - Jump to Boot code.

    - Execute Boot code.

    - Jump to first FLASHA sector address (0x80000).

    - In 0x80000 address, bootloader application codestart is located.

    - Long Branch to RTS.

    - Execute RTS.

    - Jump to bootloader application main in FLASHL sector.

    - In bootloader application main, another application (blink LED) is programmed (through FAPI) in FLASHB (including its corresponding codestart in address 0x82000).

    - From bootloader application, once the other application has been programmed, then Long Branch to this new application codestart:

    asm (" LB 0x082000");

    - At this point, once Long Branch has been executed, please see the screenshot below (take a look at debug view it says "no symbols are defined" but in the disassembly I can see the first 2 words of the other application binary 0x0048 and 0x0000). And that is way I though that maybe I wasn't properly generating the other application (Blink LED) binary. Also, I don't understand why at address 0x82000 there is an absolute path to CodeStartBranch.asm.

    - If I keep executing the code, then next step is a jump to address 0x80000. This address is the codestart of the bootloader application, instead of the Blink LED application, then what happens is a loop of bootloader application. I don't understand why this is happening. Do you know what is going on?

    For your information: I program binary bytes with option "Fapi_AutoEccGeneration".

    Best regards,

    Adria

  • Adria

    Thank you for these good details
    If you just load your application, without the bootloader, and manually move PC address to 0x82000, does the app work correctly? If so, can you do a memory dump comparison to confirm that the app is loaded the same whether through JTAG vs through bootloader?

    If you look at the .MAP file that gets generated (next to our OUT file) for your application, do you see the c_init in the expected memory location?

    For debug, may also be worth changing it so the bootloader and the main app don't share the same RAMs.

    Best regards
    Chris
  • Hi Christopher,

    I already solved it today. The problem was that I was programming the binary into FLASH putting each byte into an uint16 instead of putting 2 bytes in an uint16. I solved this with a little python script which generates the output as it has to be set in c to initialize an array. And that is not all, there was also another problem. As this uC is little endian, in the python script I have also had to revert the order of each 2 bytes pair from the binary array.

    So, now application #2 gets to be executed from application #1. Although I am still facing a problem: when it executes at some point at the beginning it jumps to ESTOP0. I still have to find at what line it happens. I will make you know when I get it.

    And yes, application #2 works successfully if I program it directly (without bootloader) into the uC.

    Best regards,

    Adria

  • Hello,

    It seems that binary option ("--binary") in C2000 Hex utility doesn't generate all words, specifically there are 4 missing. 2 0x0000's right before .text section, and the other 2 0x0000's between .text and .econst sections. Then, as this 4 words are not generated, at some point when linking a function call, an illegal instruction is executed because of the FLASH data shifting.

    This problem doesn't happen if, instead of using "--binary" option, "--array" option is used. This option generates an ASCII file with a const variable initialized with all the data properly set (including the 4 missing words that). It works perfect.

    With this problem, if I want to generate with "--binary" option then once it is programmed into FLASH it will not work. As a temporary solution I can generate in array format and implement a python script which converts the ascii generated file into a binary file.

    Can anyone tell me why those 4 words are missing or confirm that is a bug from C2000 Hex utility?

    PD: if anyone wonders why I want to use "--binary" option when "--array" option works, the answer is that they are for different purposes. I was doing a little example to to program FLASH with a hardcoded binary (which should be done with "--array" option) but in case you want to implement a full bootloader with a communication interface then the right option is "--binary".

    Best regards,

    Adria
  • Adria

    Please create a new post on this topic regarding C2000 Hex Utility.

    Best regards
    Chris
  • Hello,

    New post has been created: e2e.ti.com/.../752721

    Best regards,

    Adria