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.

TMS320F28069: Need Bootloader to Restart if Issues Occurred During Bootloader

Part Number: TMS320F28069
Other Parts Discussed in Thread: CONTROLSUITE

I've been able to use a bootloader to load code successfully to flash. However, for my application, I need the bootloader to automatically restart if either communication is lost or if power is lost to the device.

Just to provide some background, here is what I have:

1. GPIO37 and 34 are both set to one (in order to enter Get mode). These values are fixed and the user cannot be modified by the user.

2. My main function is then entered. See the image below. "enter_bootloader" establishes SCI and performs autobaud. If this is all successful, SciBoot() is then entered. SciBoot is a function defined in an assembly file. This then branches to the SCI Boot Rom.



3. From there, the C2000 Serial Firmware Upgrader is then used. It starts by loading "f28069_flash_kernel" to RAM. This both the C2000 Serial Firmware Upgrader and flash kernel are originally from TI controlSUITE. 

4. Once this is successful, the flash kernel then loads the application code to flash.

5. When this is complete, the board restarts. Since no autobaud character is sent, the board times out of the "enter_Bootloader()" function and continutes with the rest of the application code. Everything up to this point works if the power is never turned off during bootloading process or if the communication is never interrupted.

In order to make this work even if the bootloader was unsuccessful, I decided to put all the functions associated with the bootloader in sector E. This sector will never be erased by the flash kernel. All the other application code is in sectors F, G, and H. In order to do this, I modified the linker command file to list specific address in sector E for the bootloader. I then used the CODE_SECTION pragma in Main.c. See the images below:







After I added this, I powered off the device when it was loading to flash. When I turned it back on, it seems like it didn't attempt to go to the "enter_bootloader" function since C2000 Serial Firmware Upgrader wasn't able to start loading the flash kernel. Does anyone know what the issue might be? Is it because main is referencing a function, "DynalinkXLoop()", that's in a sector that's part of a sector that gets erased and then written to during the bootloader process?

Sorry about the long post.

  • Your codestart section which contains a long branch to _c_int00 needs to be programmed in to flash. It is usually linked to BEGIN. but BEGIN for you is a RAM location. This will not work. BEGIN needs to be assigned to flash.

    sal
  • Sal

    Thank you for the response. First, I want to point out that in the image above, "BEGIN" was commented out. Therefore, "codestart" was set to a flash address.

    In the image above, .text, .cinit, .econst, and .switch were all using "FLASH_FGH". Since sectors F, G, and H are being erased in the flash kernel (since those sectors are being used for my application code), I figured that if I used some other sectors that were not being erased, it would be ok. So for .text, .cinit, .econst, and .switch, I assigned "FLASH_BCD" instead. Again, the bootloader code was only in Sector E.

    I downloaded this to the MCU. Then I made a small changed to the application code, and attempted to load that. However, the application code wouldn't load to flash this time. I would guess that since the initialization sections are referencing sectors that were not erased but needed by the application, it wouldn't finish because it was able to program all the sectors.

    Therefore, I have the following question: is it possible to have two separate pairs of initialization sections? Meaning, one set of initialization sections will be for "enter_Bootloader()" and the other set will be for "DynalinkXLoop()"? Each initialization section will consist of .text, .cinit, .econst, and .switch. What do you think? Again, the goal is to make sure "enter_Bootloader()" will always start but "DynalinkXLoop()" is always freely modifiable.

    Syed
  • Yes this is possible. It seems you have a good understanding.

    You just need to ensure that when you boot to flash, you have the proper long branch to _c_int00 which then branches to your code which determines which application to run..

    sal
  • Sal

    Yes, I've verified that my code is branching to _c_int00. However, I'm having trouble finding out how to make _c_int00 branch to Sector E (which contains the bootloader code). How would I do this? My guess is that I can specify this from the linker command file, but I don't what that command would be.

    Syed
  • Can you figure out where it is branching too? Wherever it is branching too (likely a main) there I would insert your logic to determine where to branch too, like your bootloader.

    sal
  • Sal

    Sorry for not replying sooner. Yes, I do know where my code is branching too. Right now, I have my main function and the function that determines whether or not to do the bootloader stored in Sector E. It's now going to it both initially and in cases where the flash kernel can't load the application code to flash. This is the way it should function since the user needs to be able to reattempt the bootloader incase it fails.

    However, I'm now having an issue where the bootloader is failing frequently. Specifically, the flash kernel will always load, but the flash kernel will now fail to load the application code to flash. After looking at the disassembly for Sector E, I still see some references to ISRs that don't have anything to do with my bootloader (at least I don't think they have anything to do with them). I also see some functions from other non-bootloader related parts.

    My guess is that the linker command file uses the .text command to determine where to start the code. However, care must be taken to make sure that Sector E contains only the bootloader code and nothing else since this sector will never be erased. It's probably failing because the flash kernel is attempting to write to sector E at times. It's difficult to tell for sure since it's not possible to step through the flash kernel (since that would require manually entering in the hex file - which would take to long). I do know that before I split the code to different sectors, the flash kernel was consistently loading to flash correctly.

    Do you have any other ideas for why it might be failing so often? Thanks.

  • First, make sure you are doing a memcpy of the kernel to RAM and running from RAM. Second, If you desire not to erase the kernel in flash, then you need to ensure that no code from the hex file resides in that sector. You can likely confirm this manually by observing the block addresses and block sizes of the flash application's hex file.

    sal
  • Sal

    Sorry for not replying sooner, I was out of the office.

    I'm fairly confident that the flash kernel is running from RAM. Just as a test, I downloaded the flash kernel on it's own to the board using the JTAG port. I observed the disassembly in code composer and verified that it was all in RAM.

    It's ok if the flash kernel gets overwritten. However, the bootloader section (which is in flash in it's own sector) should never get erased.

    After doing some research, I found out that it would be easier to put the bootloader code in sectors G and H. The rest of the code (which can be upgraded) will reside in sectors A to F.

    As a test, I downloaded this to the board using the JTAG port. Looking at the disassembly in Code Composer, I can see that all the bootloader code resides in sectors G and H. After doing this, I re-tested loading through serial communication using the components I described above and this occurred successfully.

    However, I now need to make sure that the starting address is in Sector G or H (and not in any of the other sectors). This will ensure that incase loading the code serially failed, It won't erase the sectors that contains the bootloader. In order to do this, I need to set _c_int00 to an address in Sector G or H. Do you know how to do this? I did some research, but in the link below, I'm not sure what option is applicable in my case. Any help would be greatly appreciated.

    http://processors.wiki.ti.com/index.php/Accessing_c_int00

    Syed