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.

Custom boot-loader with jump in RAM



Hi,

 

we have to develop a custom boot-loader for a TMS320F28337s with the following requirements:

 

1) it starts and run in internal flash

2) on normal conditions, it performs some checks and jump to another FLASH application stored again in internal flash and there executed 

3) on a special conditions, it starts an upload of another application form an dedicated interface (for example, SCI) coping it in RAM: at the end of the upload if everything is OK, it jumps into the RAM application.

 

Our questions:

1) where can we find an example (for TMS320F28337s or another of C2000 DSP family) that shows how to do the copy of RAM application and the jump, switching the execution from FLASH to RAM?

2) how the RAM memory should be configured? In particular, the BOOT and FLASH applications have to reserve (and not use) the memory area where the RAM application will be copied and executed?

3) any other suggestion?

 

Thanks a lot,

Nicola

  • Nicola,

    Nicola Mazzacane said:

    1) where can we find an example (for TMS320F28337s or another of C2000 DSP family) that shows how to do the copy of RAM application and the jump, switching the execution from FLASH to RAM?

    There are a number of posts on this subject.  See these for example:

    https://e2e.ti.com/support/microcontrollers/c2000/int-c2000/f/175/p/401792/1422232#1422232

    https://e2e.ti.com/support/microcontrollers/c2000/int-c2000/f/175/p/480959/1732377#1732377

    Nicola Mazzacane said:

    2) how the RAM memory should be configured? In particular, the BOOT and FLASH applications have to reserve (and not use) the memory area where the RAM application will be copied and executed?

    In the BOOT app, create a large buffer (array) that will hold the RAM app, and link to the desired memory in the linker .cmd file.  You can also use the address of this buffer for the copy-to address when you load the RAM app from the serial port (for example).

    For your FLASH application, I think it can use the ram for the RAM app because you're either running the FLASH app or the RAM app, but not both.  Right?  If for some reason you don't want the FLASH app to use that ram, just don't link anything to that memory in the .cmd file.  I'm assuming here that the FLASH app is a separate project from the BOOT.  If the FLASH is part of the BOOT app, then the ram is already handled with the large buffer I described in the previous paragraph.

    Regards,

    David

  • I just realized that the forum threads I cited above are not accessible externally.  Here are cut-and-pastes of the relevant posts:

    ------------ POST #1: ------------------

    They can use a hard address to accomplish the jump. This is what TI does with the ROM bootloader. After execution, the ROM bootloader jumps to a known entry point, for example the jump-to-flash entry point. This address is documented in the datasheet. The user puts a LB (long branch) instruction there that jumps to the start of his code, say _c_int00, or perhaps a watchdog disable routine (up to the user). The LB instruction is linked to the bootloader entry point using the linker command file (LB instruction is found in file CodeStartBranch.asm in the ControlSuite examples).

    Your customer can do the same thing. Pick a known address in flash, and have the secondary bootloader always jump there. In the code being booted in, they would place a LB instruction at that address. The linker will resolve the destination of the LB instruction to wherever they want to jump (e.g., _c_int00).

    I should add, this known flash address should be in a flash sector used by the main application, and NOT in the flash sector containing the secondary bootloader.  It is the main app that has the LB instruction in it.  Generally, you'd want to use the last two words in the main app flash for the LB instruction.  This keeps the LB out of the way (instead of busting up the flash that is used by the main app).

    -------------- POST #2 ------------------

    A custom bootloader is very common.  I've made a number of posts on the forum about this in the past.  Here is one way to do it.

    Sector A is reserved entirely for the secondary (custom) bootloader.  Sector A is never erased in the field.  That way, if you loose power during flash reprogramming you can reset and recover.

    You write two completely separate CCS projects.  Project 1 is the secondary bootloader.  Project 2 is your main application.

    The device is operated in jump-to-flash bootmode.  The code-start-branch for the secondary bootloader is located at the target address for the ROM bootloader jump-to-flash.  This way, the secondary bootloader ALWAYS runs after a reset.  The secondary bootloader then checks for a "Valid" main app.  If valid, the secondary bootloader jumps to the main app.  If not valid, it starts the flash reprogramming via the CAN bus.

    The main app has a data word in flash someplace that indicates "Valid".  This word is at a known, hard address, and should have a known value (e.g., 0x1234 indicates valid.  Anything else indicates invalid).  By this I mean it is linked to a specific known address in the flash using the linker .cmd and a DATA_SECTION pragma in the main app.  When the main app is flashed, the validity word should have the value of "Valid".  This is just set in the main app code, e.g.

    const int validity = 0x1234;

    When the main app gets the CAN command to upgrade the firmware, it invalidates the main app by writing, say, 0x0000 to the validity word.  It can then do the reset, which will start the secondary bootloader.  The secondary bootloader then checks and finds the main app invalid, and starts the flash reprogramming.

    The jump from secondary bootloader to main app is done similar to how the ROM bootloader does the jump to flash.  Choose a known, hard address in the main app.  My suggestion is to make it the last two words in the flash being used for the main app (two words because a LB branch instruction needs 32 bits).  The code start branch for the main app is located here.  In the secondary bootloader, you know this hard address, so when you want to transfer control to the main app you do a hard branch to that address, e.g.

    asm(" LB 0x123456");     // use the correct address

    You asked about initialization, e.g. ,PIE.  Both projects are completely independent.  You should re-init everything as needed.  For the main app, be aware that registers will not be in the reset default state since the secondary bootloader has already changed things.  So, make sure you disable whatever it is you are configuring before you configure it (e.g., turn off interrupts with INTM bit, disable the PIE in the PIECTRL reg, then you can re-init the PIE).

    For the linker .cmd files, it is best to remove whatever memory belongs to the other project.  For secondary bootloader, list only FLASHA (assuming it fits in FLASHA alone.  If not, bring in FLASHB, then C, etc.).  For main app, do not list FLASHA.  Both projects have their own stack, BEGIN (as I've already directed), etc.

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

    - David

  • Hi David,

    We are in the process of building a slightly modified version of Serial Flash Programmer on Microsoft VS2010, and have just succeeded in a first create, download the 'B' flash kernel, download target test program (as always, Blinky) as a .txt file, load to flash, then cold reboot the hardware and lo and behold it blinks!

    We are always booting via SCIA and for some tests, we use the .b00 format and load direct to RAM rather than to flash. In both cases (flash and RAM) the start address is set for us. Is there a utility / file analyser somewhere that can load in a hex2000 output module (either .txt or .b00, or even the originating .out file) and provide a memory map of where everything is going to be put? And allow us to (safely) change the load address and start address of a file to be downloaded, then save the modified file?

    More importantly, we need to know the target size of our program to make sure that the program will fit into either flash or RAM. We don't think we have hit a limit yet, but if we do, will the downloader tell us?

    Thanks and regards,

    Chris Moir