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.

TMS320F280039C: Customer SPI bootloader

Part Number: TMS320F280039C
Other Parts Discussed in Thread: C2000WARE

Tool/software:

Hello,

I have been going through the other threads on this topic and I am still not quite understanding some things.

I am wanting to create a custom SPI bootloader for the 280039C. I want this custom SPI bootloader to be in the first FLASH sector right after the 

BEGIN            : origin = 0x00080000, length = 0x00000002

/* Flash sectors */
/* BANK 0 */
SPI_BOOT_LOADER : origin = 0x080002, length = 0x000FFE

I am using the Boot ROM code found at: C:\ti\c2000\C2000Ware_5_02_00_00\libraries\boot_rom\f28003x as a starting point for the bootloader.

I am trying to understand the sequence of how this would all work. I stepped through an existing C2000Ware project.

In the linker.cmd file you have the following section at the beginning of the FLASH

BEGIN            : origin = 0x00080000, length = 0x00000002

SECTIONS

{

   codestart        : > BEGIN, ALIGN(8)

Looking at this location in a downloaded application you see the following:

where there is an OP code for a jump to 0x8324D which is where  f28003x_codestartbranch.asm resides.

                  0008324d    00000008     f28003x_codestartbranch.obj (.text)

where it has the following code:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
WD_DISABLE .set 1 ;set to 1 to disable WD, else set to 0
.ref _c_int00
.global code_start
***********************************************************************
* Function: codestart section
*
* Description: Branch to code starting point
***********************************************************************
.sect "codestart"
.retain
code_start:
.if WD_DISABLE == 1
LB wd_disable ;Branch to watchdog disable code
.else
LB _c_int00 ;Branch to start of boot._asm in RTS library
.endif
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

QUESTION: So having the following in the linker.cmd file -  codestart  : > BEGIN, ALIGN(8) - and code_start in f28003x_codestartbranch.asm (see code above) puts the address of f28003x_codestartbranch.asm at BEGIN 0x80000? Not quite sure how this works?

From here it branches to  LB _c_int00         ;Branch to start of boot._asm in RTS library in boot28.asm. This initializes a bunch of things before jumping to main:

Fullscreen
1
LCR __args_main ; execute main()
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

QUESTION: I am not sure what I need to do to upon power up jump to the custom bootloader code at 0x080002?

QUESTION It looks like the f28003x_codestartbranch.asm and boot28.asm are needed in the bootup sequence? If the answer is yes, they currently reside in .text section outside of my SPI_BOOT_LOADER section. How would I move them into my SPI_BOOT_LOADER section?

Thank you for any help,

Brent

  

  • Hi Brent,

    Will be able to see to your question within the next day or two.

    Thanks and regards,

    Charles

  • Hello,

    Just following up on this.

    I figured out how to put the f28003x_codestartbranch.asm and boot28.asm code in my dedicated SPI flash bootloader section:

        .sect ".spi_bootloader"

    I had a few more questions. I am trying to understand the flow of things. Upon bootup I believe you have the following:

    1. Address of codestartf28003x_codestartbranch.asm is at codestart        : > BEGIN, ALIGN(8) which is the beginning of FLASH. It contains the address of f28003x_codestartbranch.asm
    1. Execution then jump to this location and starts executing f28003x_codestartbranch.asm which basically disables the watchdog and jumps to _c_int00
    2. _c_int00 is found in boot28.asm where it does a number of things
      1. Initialize the Stack Pointer
      2. Copy Initialization Data from Flash to RAM - copies the initialization data from the .cinit section in flash memory to the corresponding locations in the .data section in RAM.
      3. Calls __args_main
    3. __args_main calls the applications main()

    QUESTION: Is my understanding correct?

    If so, I am trying to understand how a custom SPI bootloader fits into all of this. I currently have put f28003x_codestartbranch.asm, boot28.asm, and args_main.c into my SPI BOOTLOADER FLASH section and in args_main.c it jumps to my SPI bootloader function to starts its execution. After it is complete it would jump to the entry point for the application.

    QUESTION: Is this the correct flow?

    One issue I am not sure about is I do not think in the linker command file I would want the .cinit section in my SPI BOOTLOADER FLASH section. I think if I did then any time, I updated the application with additional initialized global variable this would increase the footprint in the SPI FLASH section. I would think I would not want to call _cinit00 until after the SPI bootloader was done.

    QUESTION: Is my understanding correct?

    I did see this post where he creates a _c_int00 asm function that doesn't contain cinit routine and the standard _c_int00 is called at the end of bootloader function.

    Bootloader and cinit Section - C2000 microcontrollers forum - C2000Tm︎ microcontrollers - TI E2E support forums

    QUESTION: Is this the best way to do it?

    QUESTION: Where should the .TI.ramfunc  be located? In the SPI FLASH section? 

    I have been moving the bootloader code into the SPI BOOTLOADER FLASH section using #pragma.

    I see the generated .map file this for the .cinit section where SpiBootloaderRAM is a SPI bootloader RAM section for some uninitialized global variables.

    QUESTION: If the .cinit is in the application FLASH space not the SPI BOOTLOADER FLASH section will this be an issue with my uninitialized global variables in the SPI bootloader RAM section? I do see it has zero_init.

     

    .cinit     0    000800e8    00000028    

                      000800e8    0000000b     (.cinit..data.load) [load image, compression = lzss]

                      000800f3    00000001     --HOLE-- [fill = 0]

                      000800f4    00000006     (__TI_handler_table)

                      000800fa    00000004     (.cinit..SpiBootloaderRAM.load) [load image, compression = zero_init]

                      000800fe    00000004     (.cinit..bss.load) [load image, compression = zero_init]

                      00080102    00000002     --HOLE-- [fill = 0]

                      00080104    0000000c     (__TI_cinit_table)

     

    I also see the following in the application part of FLASH even though currently the project is just the SPI Bootloader.

    QUESTION: I am not sure how to move these to the SPI FLASH section or if I even need to?

     

    0     00080008  __TI_decompress_lzss            

    0     00080036  __TI_auto_init_nobinit_nopinit  

    0     00080061  C$$EXIT                         

    0     00080061  abort                           

    0     00080063  exit                            

    0     0008008a  memcpy                          

    0     000800c1  __TI_zero_init_nomemset         

    0     000800ce  _register_unlock                

    0     000800d2  _register_lock                  

    0     000800d6  _nop                            

    0     000800d7  __TI_decompress_none            

    0     000800df  _system_pre_init                

    0     000800e1  _system_post_cinit              

    0     000800f4  __TI_Handler_Table_Base         

    0     000800fa  __TI_Handler_Table_Limit        

    0     00080104  __TI_CINIT_Base                 

    0     00080110  __TI_CINIT_Limit                

    0     00080110  __TI_CINIT_Warm      

    Thanks for your help,

    Brent

  • Ok thanks I'll look over this.

  • Hello Charles,

    I have followed the advice here:

    https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/638390/tms320f28069-how-to-config-setup-custom-bootloader

    I have created a separate project for the custom SPI bootloader. Per the above suggestion I Included the rts library and cinit function into the bootloader. The booloader resides in the first section of FLASH after the BEGIN section at 0x80000 and is separate from the application FLASH.

    At power up the f28003x_codestartbranch.asm function is called (address at 0x80000). This disables the watchdog and calls the bootloader’s cinit() in boot28.asm which sets up the C environment – stack pointer initialization, copying data from FLASH to RAM, etc. At the end it calls __args_main which calls the bootloader’s main() which start executing.

    The bootloader is able to read in an application (led_blink in place of a flash kernel), write it to RAM, and jump to entry point of the RAM application where it starts executing.

    So, I believe this is working as expected?

    I then created a custom SPI flash kernel (used SCI one as a starting point) that runs out of RAM and is used to write the application to FLASH. I again used the led blink application that was built to run out of FLASH. The flash kernel is able to read the led application over the SPI and write the application to FLASH where it like the bootloader jumps to the address located at the applications BEGIN section (codestart) which like the bootloader is f28003x_codestartbranch.asm which also disables the watchdog and calls cinit() in boot28.asm which calls __args_main() which calls the led blink main and starts executing.

    So, I think the custom SPI flash kernel is working as expected?

    My question is getting the SPI bootloader and application to work together and not step on each other?

    Upon power up I want the SPI bootloader to execute first and based on a GPIO input will either run the bootloader code or jump to the application code for execution.

    I do not think BOTH the bootloader and application can have a -    codestart        : > BEGIN, ALIGN(8)?

    If they both had this I am not sure how it is determined what f28003x_codestartbranch.asm => cinit() => __args_main() => main() to run at power up?

    So do I only have codestart        : > BEGIN, ALIGN(8) defined for the bootloader?

    From the bootloader do I jump to the applications cinit() which would initialize stuff for the application => __arg_main() => application main()?

    Can you help me understand this?

    Thanks for your help,

    Brent

  • Hi Brent,

    >So I believe this is working as expected?

    Yes this flow is correct if the kernel stored in flash and written to RAM also writes to RAM instead of FLASH.

    >So, I think the custom SPI flash kernel is working as expected?

    Yes this flow is correct, great that it is working.

    >I do not think BOTH the bootloader and application can have a -    codestart        : > BEGIN, ALIGN(8)?

    Yes, both the bootloader and application can have codestart : > BEGIN, ALIGN(8) section. An example of this is the SCI Flash kernel for F28003x devices in the BANK0_LDFU build configuration.

    >If they both had this I am not sure how it is determined what f28003x_codestartbranch.asm => cinit() => __args_main() => main() to run at power up?

    At power up if in the Flash boot mode, the flash bootloader will look to start at 0x80000. As an example in the SCI Flash kernel for F28003x device, the BANK0_LDFU build configuration does not rely on the f28003x_codestartbranch.asm file to begin it's operation. 

    >So do I only have codestart        : > BEGIN, ALIGN(8) defined for the bootloader?

    You need to have it defined for both bootloader and application.

    >From the bootloader do I jump to the applications cinit() which would initialize stuff for the application => __arg_main() => application main()?

    You need to branch to the entry address for the application from the bootloader. The application's codestart section will handle the correct memory location placement and re-direction (entry address branch = > codestart => c_int00 =>application main).

    Thanks and regards,

    Charles 

  • Thank you for the information.