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.

TMS570 Flash boot loader using F035 API

Other Parts Discussed in Thread: TMS570LS20216

Hi there,

I'm using TMS570LS20216 for my two of my projects now, programmed in the BE32 CPU mode.. I'm getting very confused as far as bootstrap loader is concerned. Any help would be greatly appreciated to my below questions.

In the TRM, all I can find related to the boot is para. 1.3.1 on Boot Memory Selection between Flash address 0x00000000 and CPU data RAM, and para. 3.1.1, Table 3-1 explaning the Software Reset when writing to bit 14 or 15 or the SYSECR register, typically used by a boot-loader.

My understanding is that we have to produce a boot loader binary with the F035 API library that was packaged by TI in the Thumb CPU mode. This code should then be programmed somewhere (where and how ???) in the Flash, then brings up at power-up (how ???), and then receives data-to-be-programmed from protocols such as RS232, CAN, USB or SPI, then write to Flash address starting at 0x00000000, then make the jump by writing to SYSECR within the loader.

Is my understanding correct?

Can anyone please clarifies the "where ???" and "how ???" in my description?

Looks like that the bootstrap loader is much well implemented in the MSP430, am I wrong?

Thanks.

 

  • Hello Chuck,

    Hopefully I can clear a few things up. First, section 1.3.1 is discussion an option where the flash and ram address space can be swapped. i.e., on power up, flash begins at address 0x00000000 and RAM at address 0x08000000. By setting the RAM Flash swap bit in the RAMCTRL register, 0x00000000 will be the beginning of RAM and 0x0800000 will be flash. This is useful because reset vectors to address 0x00000000 for the program execution. Note that the normal RAM address range starting at 0x08000000 will not longer writable since it is physically flash and no longer RAM.

    Section 3.1.1 references the ability to force a soft reset of the device. A soft reset will assert a warm reset to all of the peripherals and the CPU which means much of the system configuration will remain allowing code to be copied into RAM and, using the RAM/Flash swap feature, have the system jump to the "new" address 0x00000000 located in RAM

    Note that your boot loader code will reside in flash and begin execution from flash based on some external stimulous such as a CAN, SPI, or UART message or even specific pin state combinations that are unique enough they wouldn't ocurr in the field. Another approach is to  perhaps always execute at startup and then proceed to the application after some timeout period if there is no boot loader communication. This process is flexible and has some room for creativity. It is mostly dependent on your application and system requirements.

    Once the boot loader code in flash is actively executing, some protocol is utilized to communicate with an external tool that will download a dataset and commands to the device. These commands can be to do what ever tasks your application needs. For examply, for programming the device, you would need to use code that is built from the Flash API loaded into and executing from RAM. The link below points to an application note of how to program the devices flash using the flash API.

    http://www.ti.com/mcu/docs/litabsmultiplefilelist.tsp?sectionId=96&tabId=1502&literatureNumber=spna117a&docCategoryId=1&familyId=1870

    Some boot loader examples and documentation can be found at this link and should give you some ideas even though they are not specific to your device.

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

    Additional software and information can be found here:

    http://processors.wiki.ti.com/index.php/Category:HerculesSWExamples

  • Hi Chuck,

    Thank you very much for your detailed post! New to the TMS570 family, for sure it helps me understand lot of thing regarding the boot loader. I used to store the boot loader in external memory because my previous MCUs have external memory bus (not the case for the TMS570 144-pin package) and have boot select pins to start either the in-MCU Flash or the external Flash, so there is no need to use the swap and warm-reset features.

    As for this TMS570, please let me know if my understanding is correct:

    1. Build a boot loader standalone binary and store the whole binary code using JTAG at, let say, BANK3 sector 0.
    2. Build the operational software binary and store the whole binary start at Flash address 0x00000000 (must end at BANK2 sector 3). Beside doing its main job, this operation software should provide mechanism to check whether it should involk the boot loader based on predefined hardware and/or software conditions.
    • If boot loader is requested, copy the boot loader binary from BANK3 sector 0 to the RAM at 0x08000000, set the swap bit in RAMCTRL register, then warm reset the MCU by writing to the SYSECR register.
    • Otherwise, execute operational software code.

    The available F035 Flash API library that was packaged by TI in the Thumb CPU mode only, so the boot loader has to be built in the Thumb mode.

    Is my understanding correct?

    Besidet that, is there any RS232 Flash boot loader sample code available?

     

  • Hi Chuck,

    There is some sample code for an SPI bootloader on this page http://processors.wiki.ti.com/index.php/RM48_HDK_Kit. Whilst the code is identified for RM4 it should compile quite happily for TMS570.

    Regards,
    Richard

  • I see there is also a CAN bootloader on this page too now.

    Regards,
    Richard

  • Jusr one other thing - the RM48 is a newer part and therefore uses the F021 flash library. However there is not a huge difference between the F021 and the F035 APIs so you should be able to port to the TMS570LS20216 quite easily.

    Regards,
    Richard

  • Thanks Richard for all those links and info.

    Can you please tell me whether my understanding of the TMS570 boot loader was correctly described in the post just prior your postings?

    I didn't have a chance to look into the example, but please, can you possibly tell me whether the external SPI or CAN client just have to send the raw binary of the linked file to the MCU without any interface, after powering up the MCU? :)

    Best regards!

  • Hello Chuck W.,

    Where the boot loader is stored is application dependent so it is not entirely necessary to put it in Bank2 Sector 3. Also, it is not necessary to complete the RAM-Flash Swap and this should probably be avoided. Instead, simply jump/branch to the RAM location where you copy your code into RAM. This can be be easily done using function pointers.

    In the example boot loaders TI has provided at the links given previously, the boot code is stored in the first sector (address 0x00000000) and the application starts at address 0x00020000. If the image being programmed as indicated by the address, is a new boot loader, the boot loader is copied to RAM and then replaces itself at address 0x00000000. If it is the application, the sectors starting at 0x00020000 are erased and programmed.

    There are 2 useful documents that would be worth looking over to get a feel for how our example boot loaders work. They are located at the following links:

    SPI based boot loader:

    http://processors.wiki.ti.com/images/9/9d/SPNA157.pdf

    CAN based boot loader:

    http://processors.wiki.ti.com/images/7/76/CAN_Bootloder_UG.pdf

    Each of these documents outline the functions, commands, and flow of the boot loader process.

    As noted in another post, these are for the F021 devices and, as such, use the F021 Flash API. The Flash API function calls can be replaced with the comparable F035 function calls using the F035 API.

  • Thank you Chuck D.,

    Your post does help me understand how the bootloader under the TMS570 architecture works.

    Because we are building aeronautical/avionic embedded software, regulations require us to follow the RTCA/DO-178B or -178C guidelines, and submit the system to the certification authorities for approval. Therefore we have to select an implementation method with which can minimize the amount of test/analysis/review works.

    We have designed bootloader in the past with an ARM7 based MCU, with external memory bus and boot-selector pins (boot-selector pins are required to completely decouple the bootloader from the operational software). The bootloader is stored on external memory and the main operational software is stored on in-dice Flash ROM, there is absolutely no link between both softwares. If the main operational software is been selected, the external memory will be disabled. There is no partitioning to prove; there is no link between the main application and the bootloader, which was very efficient and no issue for software certification. With the TMS570, however, the 144-pin PGA packaged MCU doesn’t have an external memory bus nor boot-selector pins.

    With your proposed method, we have to certify the switching mechanism of the bootloader/main software selection, but the main software will be standalone and doesn't contain any bootloader code (can be stored at 0x00000000 when operating without a bootloader). If the bootloader software is not present or damage, then the system will not boot.

    With my method described in one of the previous post (I assume that this method works too; if this is not the case, please let me know), the switching mechanism will be certified as the main operational software (less complicate in terms of software certification), but if the main software is not present or damage, then the system will not boot.

    Voilà! I will see what is the best method before implementing it ...

    Thanks again!

  • Hi Chuck,

    As I see it there are 4 ways that a bootloader can work on a TMS570:

    1. You have a bootloader that starts at address 0. The application starts at some higher address on a segment boundary. On power up the bootloader runs and checks that a valid application is present (probably using the CRC engine) before calling it. The bootloader and application are totally separate from each other. The only downside is that it is difficult to replace the bootloader if required.

    2. You have only an application stored in flash. If you want to re-flash the application you download an image for an updater into RAM and call into that. From then on the updater can update the application. The main disadvantage with this approach is that a power failure during a programming operation will result in bricking your hardware!

    3. You have a two stage bootloader. The first stage bootloader contains only the exception vectors and some code to check for the presence of the second stage bootloader or application. This bit of code is never changed. The secondary bootloader contains the routines to re-flash the application and is also stored in flash in a different segment to the first stage bootloader. The application sits in another segment and is called by the second stage bootloader. This method has the advantage that if power is lost whilst re-flashing the application you still have the bootloaders present which can be used to try again. Also you can replace the second stage bootloader if required.

    4. The 4th option is a combination of 2 and 3 where you have a primary bootloader which has the capability of loading an updater program to RAM. The application can also load the updater program to RAM. This has the advantage that a power fail during re-flashing does not brick the hardware. From a functional safety viewpoint it may also be beneficial if the main application and bootloader cannot reprogram flash to protect against an invalid program counter running amok and calling erase or programming routines.

    There may be other variations on these 4 schemes. For your information we use the first scheme. If we ever need to replace the bootloader we do this through an application that overwrites the bootloader.

    In all cases you probably also need to include some mechanism that can be used to stop the bootloader from calling the application in case you have loaded an application where comms doesn't work.

    Regards,

    Richard 

  • Hi Richard,

    Richard Burke said:
    There may be other variations on these 4 schemes. For your information we use the first scheme. If we ever need to replace the bootloader we do this through an application that overwrites the bootloader.

    In your SPNA157 application note for the SPI bootloader, the bootloader has the ability to load itself to RAM. I think that the bootloader could be slightly changed to detect additional GIO pins or other data, to decide whether the update is to be performed on the bootloader itself or the main application. Is this right?

    One question though, I can see that the static library for the F035 architecture to link with the bootloader is more than 400 KB in size, how could this be copied into the RAM of 160 KB? I must have missed something.

     

    Richard Burke said:
    In all cases you probably also need to include some mechanism that can be used to stop the bootloader from calling the application in case you have loaded an application where comms doesn't work.

    Can you please clarify this point? It looks like an additional security measure worth considering for critical embedded software.

     

    Many thanks!

     

  • Hello Richard,

    Thanks for providing the list of options for bootloader implementation. I believe that these are all viable solutions depending onspecific needs of the application.

     

    Chuck W,

    In regard to your prior post, I certainly understand your requirements and can appreciate the difficulties they impose on you for your bootloader implementation. The traditional approach you mention is ideal for your application but, unfortunately, this comes at a high cost in silicon and we have not implemented it on our 570 devices.

    There is, however, another package available (337BGA) for the TMS570 products that offer the external memory interface (EMIF). With this additional interface, the bootloader code could be stored in an external ROM or Flash and loaded into RAM for execution upon the assertion of one or more assigned IO pins. In this way you would have comparable operation to the scenario you describe and keep the bootloader separate from the application. The down side of this is there would still have to be some software that manages switching to bootloader mode.

    Another possible solution is to place your bootloader code into the EEPROM emulation space and again use assigned pins to trigger the bootloader. Once triggered the entire bootloader would have to be loaded into RAM and executed from there since code execution is not allowed from the EEPROM emulation flash.

    Both of these are similar to the options offered by Richard but provide the separation of the code storage.

    Hopefully, these options can allow you to find a solution to your requirements that minimize the level of testing that would need to be done to prove separation/safety. If there are any additional questions, please let me know.

    Hopefully these suggestions are helpful and can get your started on an implementation that is

  • Hi Chuck D.,

    Wooowwww, this thread will become the ultimate resource for anyone wanting to understand possible boot-loader implementations and architecture.

    I fully understand your explanations and greatly appreciate the insights. We've evaluated the 337BGA package MCU but have determined it would be overkilled for our application and will complicate the fabrication process.

    Without wanting to compare the TMS570 (much more feature-rich and security-oriented) to our previous ARM7 MCU, I just want to point out that unlike the TMS570 MCU, the predefined boot-selector pins are assessed by the ARM7 CPU microcode and appropriate memory is enabled and application is loaded (does not require software switching): bottom line is that both applications are truly separate, no link at all, and no additional first stage bootstrap-loader is required.

    With all the clarification from you and Richard, I'm almost ready to made a decision ... just waiting for additional info from Richard for the library size question.

    Thanks again! :)

     

  • Hi Chuck W.,

    I am looping in our API library owner so that he can address the RAM storage question. My first inclination is to state that this is achievable by only copying the needed functions into RAM which would greatly reduce the size; however, lets wait until he has a chance to review the thread and comment for a final answer on this.

    Note that the programming utility NowFlash also copies API functions for program and erase into RAM but over JTAG. So this is, most certainly, possible. I simply do not have the details.

  • Hi Chuck W,

    In response to your question about the SPI bootloader, I'm afraid you will have to ask a TI expert. I was merely pointing out that it exists.

    On the point of the mechanism to stop the bootloader loading the application, here is an example scenario:

    • To reflash an application you would normally have a CAN message to jump back to the bootloader (reset or similar message).
    • You have accidentally programmed an application that causes CAN not to work so the application doesn't receive the reset message.
    • If you re-power the system the bootloader thinks the application is valid so immediately calls it. There is therefore no way to re-flash the application.
    One solution is to have a short delay in the bootloader to allow a programming message to be received before jumping to the application. Alternatively you might want to look at a hardware line to indicate to the bootloader that it should not call the application.
    Regards,
    Richard 
  • Hi Richard,

    It is now well understood for the question on the stopping mechanism.

    Additional to a magic word or CRC checking, the provided SPI boot-loader already checks for the hardware line for possible forced application update so it shouldn't be a concern.

    Thanks.

  • Chuck W.

    For the SPI based bootloader or any other of the example bootloaders that TI provides, you can modify the detection method as you see fit for your application. Currently, these examples look for the incoming data and if the data is to be programmed starting at 0x00000000 it assumes it will reprogram itseld and copies the bootloader to RAM for execution. In my opinion, detecting a pin state would allow an even better determination than sniffing our the address of the data to be programmed.

  • Totally agreed!

    We cannot just trust a magic word stored in the Flash or application CRC checking. If the CRC has failed in the field, there is a reason and the unit would have to be returned to factory for analysis and troubleshooting. This is all about safety of the people!

    Field programming of avionic products should only be enabled by strap-pin program selector, and requires even a password once the communication is established.

    Chuck W.

  • Hello Chuck W.,

    Chuck D. is correct.  You only need to copy into RAM the API functions you are using.

    You do need to make sure that you include all functions called by the main function.  Some examples are:

    setup_state_machine() -> calls the functions get_timing(), Feed_Watchdog_V()

    IssueCommand() -> calls the functions IssueCommand_U16(), IssueCommandU32()

    Flash_Erase_Sector_B() -> call the functions setup_state_machine(), Flash_Sector_Select_V(), IssueCommand(), Fapi_PollFlashStatus()

    Flash_Erase_Bank_B() -> call the functions setup_state_machine(), Flash_Sector_Select_V(), IssueCommand(), Fapi_PollFlashStatus()

    Flash_Prog_Data_B() -> call the functions setup_state_machine(), Flash_Sector_Select_V(), IssueCommand(), Fapi_PollFlashStatus()

    Flash_Start_Async_Command_B() -> call the function IssueCommand()

    Flash_Verify_Data_B() -> Feed_Watchdog_V()

  • Hi John,

    I'm a bit confused now.

    If code from the F035 API are linked into the final boot-loader binary because they are needed. When it is time to reprogram the boot-loader, the whole binary should be copied to RAM (and executed from there) before launching the erase-program cycle, simply because all the binary previously stored in the boot-loader Flash is needed but will be erased and replaced. My understanding is that any code remains in the Flash will no longer be accessible once the reprogramming process is actioned.

    I must have missed something. Could you please clarify?

    What is the typical size of the SPI or CAN boot-loader binary?

    Thanks.

  • Hello Chuck W.,

    If you have a look at the examples provided in the links given earlier, perhaps this will better explain how the API is linked and included. Also, these projects will give some idea of the size of the binary once they are built. There are examples there for SPI and CAN bootloaders. Although these are for the LS3137 devices and use the F021 API library, they should give you some better idea of the implementation details.

    Also, it was pointed out to me that the  TMS570LS20216 device does not have an on-chip EEPROM emulation bank so this would not be an option for bootloader storage on your specific device. This means you would have to locate in some specific area of program flash and protect it from access using the MPU.

  • Hi Chuck W.,

    I would assume your new code would only include the functions that are actually used from the API (Link time optimization).  So say your bootloader is going to reprogram bank 0 completely.  You would then need to copy only the following functions to RAM to complete this you would call a sequence of functions like:

    Flash_Erase_Sector_B() -> Erases Bank0

    Flash_Prog_Data_B() -> Programs the new image, depending on how big a RAM transfer buffer you allocate, this will need to be called multiple times

    Flash_Verify_Data_B() -> Verifies the previously programmed image for each call to Flash_Prog_Data_B()

    which means the following functions need to be copied to RAM:

    setup_state_machine(),

    Flash_Sector_Select_V(),

    IssueCommand(),

    Fapi_PollFlashStatus(),

    get_timing(),

    Feed_Watchdog_V(),

    IssueCommand_U16(),

    IssueCommandU32(),

    Flash_Erase_Sector_B(),

    Flash_Prog_Data_B(),

    Flash_Verify_Data_B()

    Someone else will need to comment on the typical size of a CAN or SPI boot-loader binary as I do not know.

  • OK John,

    I would have to try that out. For those who need a link, I found a previous thread regarding copy code from Flash to RAM here: http://e2e.ti.com/support/microcontrollers/hercules/f/312/p/62954/227583.aspx#227583

    However, because I'm using IAR Embedded Workbench (IAR EWARM), I would have to figure a way out to build an equivalent version.

    If you have a link to the IAR EWARM version, please let me know.

    Thank you very much!

  • Chuck W.,

    I have not tried this but I think you can do the following:

    iobjmanip --rename_section .text=.textrw pf035a_api_eabi.lib pf035a_api_eabi_rel.lib

    and then add to your IAR icf file

    /* Split the .textrw section into a readonly and a readwrite
    section */
    initialize by copy { section .textrw };
    /* Place both in a block */
    define block RamCode { section .textrw };
    define block RamCodeInit { section .textrw_init };
    /* Place them in ROM and RAM */
    place in ROM { block RamCodeInit };
    place in RAM { block RamCode };

  • Hi John,

    Thank you for sharing your knowledge and your willingness to help.

    From your script, I understand that I need to convert the F035 API to the IAR EWARM recognizable format in order to be able to link with their IDE. I'm currently not in a stage of project that can try this conversion script yet but will certainly give it a try when time comes.

    Best regards,

    Chuck W.