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: Bootloader - How to jump to user application

Part Number: TMS320F280039C

Hello, 

I have several questions about the bootloader example "flash_kernel_ex3_sci_flash_kernel". I have been using this as a reference for creating a bootloader for my own application. I was able to understand erasing, programming and verifying sections of the flash. However, when jumping to the user application this is where I am confused. 

It looks like "flash_kernel_ex3_codestartbranch" causes a watchdog failure to reset the MCU and then boots up at location _c_int00. 

Questions - 

1 - Where is _c_int00 defined? I want my user application to match another microcontroller also used in my application. I'm trying not to change my master controller code that interfaces with this microcontoller and I want to only change the microcontroller code. I want my user application to be defined to start at 0xA000. How do I define flash_kernel_ex3_codestartbranch.asm to jump there? 


2 - In my user application, how would I define the code to start at 0xA000? Do I change BEGIN below to 0xA000?

3 - In "flash_kernel_ex3_codestartbranch.asm" what is the EntryAddr and how would I define it in such a way to jump to 0xA000 if the programming succeeded and 0x0000 (where I want the bootloader to live) if the programming failed? I see EntryAddr in the code and I assume it's being defined from the data read on SCI but I cannot see what the data coming over SCI is. I want to just set EntryAddr to either jump to restart bootloader at 0x0000 or jump to user application at 0xA000. 

Thanks for the help!

  • Hello, 

    Where is _c_int00 defined?

    You can see c_int00 defined in boot28.asm in your CCS installation, the path is : ccs{version number}\ccs\tools\compiler\t{compiler version}\lib\src

    In my user application, how would I define the code to start at 0xA000? Do I change BEGIN below to 0xA000?

    The application's codestart section would need to be mapped to 0xA000 under the SECTIONS portion of the linker command file. You do not need to change the BEGIN section. You can create a section from 0xA000 to 0xA002 in MEMORY and map the codestart section under SECTIONS to the area you just defined. 

    How do I define flash_kernel_ex3_codestartbranch.asm to jump there? 

    The entry address for the application is passed into the flash kernel. You would not need to change the codestartbranch.asm file, you can change the entry address by changing where codestart is mapped as mentioned above. 

    In "flash_kernel_ex3_codestartbranch.asm" what is the EntryAddr and how would I define it in such a way to jump to 0xA000 if the programming succeeded and 0x0000 (where I want the bootloader to live) if the programming failed?

    The EntryAddr is the entry address of the firmware you are writing in to Flash. It is passed out of the main function of the flash kernel. You can check the return status of the firmware update program and update the Entry Address in the main function accordingly. 

    Thanks

    Anu

  • Thank Anu, just sharing what I did for you to confirm I understood you correctly, and correct me if I did not understand you. 

    Mapping user application to 0xA000: 

    1 - Defined new section CODESTART for section 0xA000 to 0xA002 - do I need to change RAMM0 / RAMM1 to be mapped based on CODESTART as I did below? 

    Do I need to change BOOTROM / SECURE_ROM to where the bootloader lives 0x0000-0xA000? 

    2 - EntryAddr 

    So I understand this - if I return EntryAddr from main() = 0xA000 the bootloader will then jump to 0xA000 once the reset by watchdog is caused. If I return 0x0000, the bootloader will then jump back to 0x0000?

    How is LRETR in codestartbranch.asm linked to the variable returned from main? 

  • Derek, 

    I will get back to you in a day. 

    Thanks

    Anu

  • Derek, 

    1. You do not need to remap the BOOT RSVD section, RAMM0 or RAMM1. The CODESTART section looks fine but this address is mapped to RAM, not Flash. You do not need to change the BOOTROM/SECURE ROM mapping. Which linker command file are you using? The sections origins and lengths look incorrect. The application is supposed to be in Flash, correct? In this case, please use the 28003x_generic_flash_lnk.cmd as a base to make the changes needed. You can refer to the blinky example's flash linker command file to see how an application should be mapped to Flash.

    2. The value of EntryAddr is passed to the ExitBoot function in the codestartbranch file. Once the ExitBoot function has finished executing, it will jump to the EntryAddr. If the device is reset, the boor flow will check the boot pins to see which boot mode is selected and jump to the correct entry point based on that. To check the usage of LRETR, please check https://www.ti.com/lit/ug/spru430f/spru430f.pdf

    Thanks

    Anu

  • Hey Anu, 

    Point 1 - Mem mapping:

    I started with this file - 28003x_generic_flash_lnk.cmd. But got the below errors "10099-D program will not fit into available memory"

    Therefore, I changed the length of the RAM sections and the compile error went away. 

    How should I fix errors "10099-D program will not fit into available memory" and whatshould I change CODESTART  to? I see the FLASH_BANK0_SEC0 - is this what CODESTART should be equal to? 0x100000? 

    If I change CODESTART to be equal to FLASH_BANK0_SEC0? How will I get rid of compile errors "10099-D program will not fit into available memory"  associated with RAM? I fixed these by increasing the RAM section lengths as below: 


    Point 2 - EntryAddr

    I don't see a function ExitBoot in the demo "flash_kernel_ex3_sci_flash_kernel". I see EntryAddr returned by main and that is all. Where is function ExitBoot?

     

  • Also the link shared about LRETR does not work.

  • Derek, 

    Please take a look at the following link: https://software-dl.ti.com/ccs/esd/documents/sdto_cgt_Linker-Command-File-Primer.html

    When one block of memory is not enough to hold a section, you can combine blocks under the SECTIONS area to solve the error. You could try to combine sections of RAM and Flash, but you cannot change them such that the addresses are not mapped to the correct memory. Please take a look at section 7.3 in the F28003x datasheet to see the memory map for your device: https://www.ti.com/lit/ds/symlink/tms320f280039c.pdf?ts=1652979606932&ref_url=https%253A%252F%252Fwww.ti.com%252Fproduct%252FTMS320F280039C%253FkeyMatch%253DF28003X 

    You can map the Codestart to the start of Flash, which would be 0x80000. You can make the section start at 0x80000 with a length of 2, and modify Flash Bank 0 Sector 0 to start at 0x80002 and have a length of 0xFFE. 

    The ExitBoot function is in flash_kernel_ex3_codestartbanch.asm in the folder for the flash kernel example. This link should work for LRETR: https://www.ti.com/lit/ug/spru430f/spru430f.pdf?ts=1652979879411&ref_url=https%253A%252F%252Fwww.google.com%252F 

    Thanks

    Anu

  • Hey Anu,

    Thanks for your help! I am sharing what I did:

    1 - I started over with the 28003x_generic_ram_lnk from an example

    2 - Mapped codestart to start of flash

    3 - I had errors below - 

    Therefore, I combined sections as below. 

    .text says that it is executable code. The executable code will be in flash so should i map this to flash like below? I mapped .text to all of FLASH_BANK0 and FLASH_BANK1_SEC0 and FLASH_BANK1_SEC1. 

    .cinit did not fit in RAMM0 so I moved it to RAMLS0. Is this ok?

    .bss has size 0x1e62 why can I not fit this into 2 flash sectors of length 0x1000? It seems like it's letting me split up .bss 2, 3, 4 between sectors but .bss 1 has size 5,623 and the maximum memory block / RAM block is size 4096 besides SECURE_ROM and BOOTROM. Is there a way to split .bss1 of size 5623 between 2 blocks?

    It does not look like it is possible? Does it mean I have to modify that code so that the size of .bss1 is less than 4096? That is unfortunate because I'm trying to use the same core libraries between all microcontrollers. The code is written in an object oriented way with some large structures. I guess I need to reduce the size of some of the structures so that they can go into separate bss / .const pages? No structure function or array can be greater than 4096 in size?

    Why are so many things in const1? How do I move some of these things to another const page? Will things automatically move once I fix size of some of the bigger functions / structures?

    4 - For the bootloader - where will this be stored? My application is in FlashBank0, should the bootloader be in FlashBank0, and my application be in flashbank1? For my application, code start is 0x080000. But for bootloader, what should be code start? Should it be 0x080000 and then for my application, codestart should be 0x090000?

    5 - I see the ExitBoot function now in flash_kernel_ex3_codestartbranch.asm. It still is not clear to me how LRETR jumps to the EntryAddr returned by main.c? Since my application is being loaded to 0x080000 I would want to return 0x080000 as the EntryAddr in main.c and LRETR will jump there?

  • Derek, 

    I will talk to the linker command file expert and get back to you in a couple of days. 

    Thanks

    Anu

  • Hey Anu, any feedback from the linker command file expert? 

    Thanks!

  • Derek, 

    The executable code will be in flash so should i map this to flash like below? I mapped .text to all of FLASH_BANK0 and FLASH_BANK1_SEC0 and FLASH_BANK1_SEC1. 

    This is fine, if you need less sections you can remove the Flash Bank 1 sections. 

    .cinit did not fit in RAMM0 so I moved it to RAMLS0. Is this ok?

    You should move .cinit to Flash -- all initialized sections should be placed in Flash. You can look at the table in the linker command file primer to see which sections are initialized. 

    .bss has size 0x1e62 why can I not fit this into 2 flash sectors of length 0x1000? It seems like it's letting me split up .bss 2, 3, 4 between sectors but .bss 1 has size 5,623 and the maximum memory block / RAM block is size 4096 besides SECURE_ROM and BOOTROM. Is there a way to split .bss1 of size 5623 between 2 blocks?

    It does not look like it is possible? Does it mean I have to modify that code so that the size of .bss1 is less than 4096? That is unfortunate because I'm trying to use the same core libraries between all microcontrollers. The code is written in an object oriented way with some large structures. I guess I need to reduce the size of some of the structures so that they can go into separate bss / .const pages? No structure function or array can be greater than 4096 in size?

    Which sectors are you using for .bss? You can move them to RAM as .bss is not an initialized section, and try combining sections to see if this solves your size issue. 

    Why are so many things in const1? How do I move some of these things to another const page? Will things automatically move once I fix size of some of the bigger functions / structures?

    The size of const depends on your application, you can try combining more sectors for this as well. 

    4 - For the bootloader - where will this be stored? My application is in FlashBank0, should the bootloader be in FlashBank0, and my application be in flashbank1? For my application, code start is 0x080000. But for bootloader, what should be code start? Should it be 0x080000 and then for my application, codestart should be 0x090000?

    This is up to you. It sounds like Banks 0 and 1 are being used by the application, do you have Bank 2 free to put the bootloader into? The flash kernel example has a few different configurations for you to consider - the bootloader can be placed in RAM and be written in using the SCI ROM bootloader, or can be written into Flash as shown in the LFU configurations. The bootloaders written into Flash would operate on applications written in other banks - for example the bootloader in Bank 0 would operate on Bank 1/2, the bootloader in Bank 1 would operate on Bank 0/2 and Bank 2's bootloader operates on Bank 0/1. 

    5 - I see the ExitBoot function now in flash_kernel_ex3_codestartbranch.asm. It still is not clear to me how LRETR jumps to the EntryAddr returned by main.c? Since my application is being loaded to 0x080000 I would want to return 0x080000 as the EntryAddr in main.c and LRETR will jump there?

    Yes, you should return 0x80000 as the EntryAddr, and LRETR jumps to it. 

    Thanks

    Anu

  • Hey Anu, 

    Thanks for your help! 

    The problem with .bss.1 is that this is all container.obj of size 5623. There is no RAM or FLASH big enough to hold 5623. Container.obj is a large structure containing a bunch of pointers to other structures. It seems that I cannot split container.obj between different memory sections? I have tried and it just is listed under the "Failed allocation" section.

    If this is the case, maybe I just need to break container.obj into 2 pieces. This way it will fit into RAM sections. Just wanted to confirm that is the problem before I went through the trouble to do that - because I use the same library of application code for multiple microcontrollers this will impact the code I have for other vendor microcontrollers as well, which is unfortunate but if it's the only possibility it is ok. 

  • I have another question - 

    My application is in flash bank 0, flash bank 1 now. I moved all initialized sections to flash

    The bootloader is in flash bank 2. What would CODESTART be for the bootloader in flash bank 2? 

    I cannot set CODESTART = 0x0A0000 because then it would overwrite FLASH_BANK2_SEC0?

  • Another question - 

    Is it possible to combine sections 6/7 in the flash bank like this to make a big section? Or will this not work?

  • Any feedback here? I have gotten the project to run through some code on the development board but I'm wondering if some memory mapping issues could be causing this issue I'm having here: https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1107201/tms320f280039c-__ti_resource_lock-__ti_lock_device_tbl-causes-illegal-operation/4102853#4102853

  • Derek, 

    The problem with .bss.1 is that this is all container.obj of size 5623. There is no RAM or FLASH big enough to hold 5623. Container.obj is a large structure containing a bunch of pointers to other structures. It seems that I cannot split container.obj between different memory sections? I have tried and it just is listed under the "Failed allocation" section.

    If this is the case, maybe I just need to break container.obj into 2 pieces. This way it will fit into RAM sections. Just wanted to confirm that is the problem before I went through the trouble to do that - because I use the same library of application code for multiple microcontrollers this will impact the code I have for other vendor microcontrollers as well, which is unfortunate but if it's the only possibility it is ok. 

    Could you post this as a separate thread? The correct expert will get assigned and assist you further here. 

    The bootloader is in flash bank 2. What would CODESTART be for the bootloader in flash bank 2? 

    Codestart for Flash Bank 2 can be 0xA0000, you can modify the start address and length of Bank 2 Sector 0 in the same way that Bank 0 Sector 0 is modified to make space for the codestart section. This is all in a separate linker command file for a separate project? Is the bootloader itself a separate project?

    Is it possible to combine sections 6/7 in the flash bank like this to make a big section? Or will this not work?

    This is fine, you can also combine the sectors in the SECTIONS area of the linker command file. 

    Any feedback here? I have gotten the project to run through some code on the development board but I'm wondering if some memory mapping issues could be causing this issue I'm having here: https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1107201/tms320f280039c-__ti_resource_lock-__ti_lock_device_tbl-causes-illegal-operation/4102853#4102853

    How is this section mapped to memory? 

    Thanks

    Anu

  • Hey Anu, 

    Thanks for the help! 

    1 - bss.1 and Container.obj are not issues if I am allowed to combine memory sections to make bigger sections as below. Caintainer.obj fits into the RAMLS0_1_2 sections I combined. Combining in the "sections" area does not work because Container.obj cannot be split between sections by the compiler but combining sections in the "memory" section seems to work. I have been able to run some of the code in Container.obj on the development board. 

    Regarding bss.1 I will enter a case if I run into any more issues there, but it seems like I have a solution for that issue. 

    2 - Bootloader

    Currently the bootloader is a separate project and application. How do I get the CPU to always run the bootloader first on startup and not the application. I plan to load the application into flash banks 0 and 1 and then the bootloader into flash bank 2. If it is easier I could put the bootloader into flash bank 0 and then the application into flash bank 1 and 2. 

    For CODESTART I did this in the bootloader application - similar to flash bank 0

    3 - TI init functions seem to not be working - specifically I see this breakpoint is being hit and somehow boot28.asm thinks the function returns 0. Is this a memory mapping issue or something weird? It seems _lock() cannot be set to _nop() for some reason. _lock is always at location 0xFFFFFFFF which is weird. Described further in this question I asked.

    https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1107201/tms320f280039c-__ti_resource_lock-__ti_lock_device_tbl-causes-illegal-operation/4102853#4102853

    Even tried below

    Memory mapping is below for trouble functions -

    cinit is mapped to FLASH_BANK0_SEC0

    TI_auto_init looks mapped to FLASH_BANK1_SEC0 in text.16

    lock looks mapped to .data in FLASH_BANK1_SEC11 and to .text18 in FLASH_BANK1_SEC2

    pre_init looks mapped to text.19 in FLASH_BANK1_SEC3

  • Derek, 

    2 - Bootloader

    Currently the bootloader is a separate project and application. How do I get the CPU to always run the bootloader first on startup and not the application. I plan to load the application into flash banks 0 and 1 and then the bootloader into flash bank 2. If it is easier I could put the bootloader into flash bank 0 and then the application into flash bank 1 and 2. 

    The flash entry points are listed below: 

    You can either put the bootloader in Bank 0 or program your BOOTDEF value so that Flash Boot jumps to Bank 2 Sector 0. 

    Regarding your 3rd question, posting a separate thread was the correct move, I will notify the moderators to let the correct expert help you. 

    Thanks

    Anu

  • Hey Anu, 

    I will put my bootloader in Bank0 and my program in Bank1 and Bank2. Is BOOTDEF by default 0x03 (option 0)? How would I change BOOTDEF?

  • Derek, 

    If you put your boot pins, GPIO 32 and 24, in Flash Boot mode, you don't need to modify the BOOTDEF register. The default Flash Boot mode will jump to the start of Bank 0. 

    Thanks

    Anu

  • Thank you for all your support Anu! I think you have answered all of my questions about flash memory, memory mapping, the bootloader and jumping to the bootloader!