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.

TM4C1230H6PM: Custom bootloader for firmware update.

Part Number: TM4C1230H6PM

Hi,

I am trying to create a custom flash bootloader for TM4C1230H6PM which needs to update my application firmware over the CAN bus. Until now, I have accomplished the following things- 

1)Erasing and writing data to  flash memory by using functions from "driverlib/flash.h"

2)Switching execution between the bootloader app residing at 0x00000000 address and another app residing at 0x00004000 by setting the MSP value to the start address of the respective app and by calling the reset handler located at  (start address+4)

3) I am not changing the offset value in Vector table offset register while switching execution still my interrupts are working fine and this is confusing me.

Now I will list down the queries that I have-

1) I went through the Bootloader demo app provided in Tivaware and I found that bootloader contents are first copied to SRAM and then executed from SRAM. I want to know why it is done that way exactly when bootloader can be executed from flash itself.

2)Why my interrupt handlers are running fine even if I haven't set any offset value in VTOR.

Hoping for a quick response.

  • Hi, 

    I have noticed one key thing which is as follows-

    When I use IntRegister() function and pass the handler function as parameter to this function then my Interrupt works but when I use IntEnable() function and extern handler in startup script interrupt doesn't work and a similar thing works in application where there are no partitions in flash,.

  • Pradeep choudhary said:
    1) I went through the Bootloader demo app provided in Tivaware and I found that bootloader contents are first copied to SRAM and then executed from SRAM. I want to know why it is done that way exactly when bootloader can be executed from flash itself.

    Copying the code to RAM allows that the bootloader itself can be updated. 

    Pradeep choudhary said:
    2)Why my interrupt handlers are running fine even if I haven't set any offset value in VTOR.

    When you first call the function IntRegister() it will copy all of your Flash based vectors to RAM, update the one vector that you are changing and change the vector table offset register to point to the RAM.

  • Hi Bob,

    Thanks for your reply. As you have described perfectly what happens when IntRegister() now I am curious to know what happens when Int Enable() is called and which of the following option is the ideal way to handle the interrupts in such applications-

    1)To use IntRegister() and do not worry about the offset register or

    2)To use IntEnable() after setting offset value in the vector table offset register.

    Regards,

    Pradeep Choudhary

  • The choice is up to you. If I use dynamic vectors (vectors copied to RAM), I use the IntRegister() function. I know it works and it reduced the chance I make an error setting up the vector table offset register.

    I am actually in the final stages of publishing an application note that discusses a CAN bootloader implementation for TM4C123. I can email you a draft copy if you send me a friend request providing me your email address and agree not to distribute the draft.

  • Hi Bob,

    I would like to read that application note. Please email it to me. I will send a friend request.

    Thanks and Regards,

    Pradeep Choudhary

  • Hi Bob,

    I have developed a custom flash bootloader and I am able to update the application using CAN. I am using IntRegister() for registering Interrupt Handlers in both Application and Bootloader and it is working fine. So, now I want to know whether there will be any negative implications of using IntRegister() if I plan to use some RTOS in my application in the future.

    Hoping for a quick response.

    Best Regards,

    Pradeep Choudhary

  • While I believe it is true in general, I cannot speak for all RTOS implementations. For TI RTOS if you configure the Runtime Vector Table address in RAM different from the Reset Vector Table address at 0, then by the time your code gets to main() the vector table offset will be set to the RAM address and all of the RTOS vectors will be copied to RAM. If you call IntRegister() in main() before the call to BIOS_Start(), IntRegister() will simply replace the one vector, in this case the CAN vector. 

  • Hi Bob,

    So you are suggesting that with TI-RTOS it won't do any harm and can run properly just by changing the runtime vector table address to RAM. Please let me know if I have misunderstood something? And if I do not want to use dynamic vectoring by using IntRegister() then how can I do it by using vector tables?

    Thanks for being patient with me.

    Best Regards,

    Pradeep Choudhary

  • To be more specific, I am suggesting that if you developed a CAN bootloader that uses the CAN interrupt, you can replace the CAN interrupt in a TI-RTOS system with your interrupt function using IntRegister(). You can do this because there currently is no TI-RTOS CAN driver for Tiva devices. You will bypass the RTOS interrupt dispatcher. This means that your CAN interrupt routine is not OS aware. It cannot use semaphores, mailboxes, post events or software interrupts. It will not be interrupted by TI-RTOS interrupts or task switching. 

    Here is some more information on how interrupts are handled on TM4C devices in TI-RTOS

    https://processors.wiki.ti.com/index.php/SYS/BIOS_for_Stellaris_Devices#SYS.2FBIOS_M4_Hardware_Interrupt_.28Hwi.29_Handling

    A community member has posted a TI-RTOS CAN driver implementation. I have not evaluated it yet, but you may be interested:

    https://e2e.ti.com/support/tools/ccs/f/81/t/942614