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.

TM4C1290NCZAD: Firmware update using SD card interfaced through UART with MCU

Part Number: TM4C1290NCZAD
Other Parts Discussed in Thread: UNIFLASH

I am planning to implement the feature of updating the firmware using SD card interfaced through UART with my custom board that has the MCU - TM4C1290NCZAD.

SD card is interfaced through UART with the MCU - TM4C1290NCZAD and the SD card will have the firmware .out file or other format(please suggest suitable format).

Whenever the SD card in inserted into my custom board and power reset happens, the firmware resides in the on-chip flash of the MCU - TM4C1290NCZAD should get updated if the CRC of the .out file from SD card did not match with the already existing firmware in the MCU, and once the firmware upgrade is over it should get transition to my application code.

Please share me the specific details on how to start designing this feature.

I have already seen the TIVA samples and I am bit confused with the information given and also gone through the spmu301e.pdf and could not get the required details.

  • SD card is interfaced through UART with the MCU - TM4C1290NCZAD and the SD card will have the firmware .out file or other format(please suggest suitable format).

    Hi,

      Please use the binary .bin file. 

    Whenever the SD card in inserted into my custom board and power reset happens, the firmware resides in the on-chip flash of the MCU - TM4C1290NCZAD should get updated if the CRC of the .out file from SD card did not match with the already existing firmware in the MCU, and once the firmware upgrade is over it should get transition to my application code.

    Please share me the specific details on how to start designing this feature.

    Not sure what is not clear on the example and the user's guide. I will suggest you first run the example as is to get a feel for it. There is a boot_serial program and there is also a boot_demo1 program. The boot_serial is a flash-based bootloader that resides on the flash at 0x0. After power up, the bootloader will run and if it does not find a valid application then it will be in boot mode. If there is a valid application firmware detected then it will directly jump to the application.  Let's suppose there is not a valid application yet.  The boot_serial will download the boot_demo1 firmware after the bootloader receives a command from the host through the UART port. After the firmware is downloaded, it will reset the device and jump to the application since there is now a valid application. This is basically how a bootloader works. The boot_demo1 is a simple application firmware example that will blink the LED.  If a switch is pressed on the LaunchPad, it will jump back to the bootloader to download/upgrade new firmware.

    Part of the bootloader configuration is to allow checking CRC during run time and as well as storing the CRC after the download is complete. Refer to the user's guide for details. 

    In your case, part of your application should be designed to read the CRC value of a new image from the SD card. If that new CRC is different from what is stored in the flash then the application can jump to the bootloader to upgrade the new firmware. Where the new CRC is stored in the SD card is up to you and that is what you need to define. 

  • Not sure what is not clear on the example and the user's guide. I will suggest you first run the example as is to get a feel for it. There is a boot_serial program and there is also a boot_demo1 program. The boot_serial is a flash-based bootloader that resides on the flash at 0x0.

    Ram: Is the flash-based bootloader resides on the MCU flash by default at 0x0? Or it has to be loaded by me? If to be loaded, how to load it?

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

    After power up, the bootloader will run and if it does not find a valid application then it will be in boot mode.

    Ram: Where it will check for the valid application? In the flash? or the external device? Assume if the MCU is used for the first time and there is no firmware loaded in it, how to proceed in such case?

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

    If there is a valid application firmware detected then it will directly jump to the application.  Let's suppose there is not a valid application yet.  The boot_serial will download the boot_demo1 firmware after the bootloader receives a command from the host through the UART port.

    Ram: boot_serial program will download the boot_demo1 from where? which memory?

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

    After the firmware is downloaded, it will reset the device and jump to the application since there is now a valid application. This is basically how a bootloader works. The boot_demo1 is a simple application firmware example that will blink the LED.  If a switch is pressed on the LaunchPad, it will jump back to the bootloader to download/upgrade new firmware.

  • Ram: Is the flash-based bootloader resides on the MCU flash by default at 0x0? Or it has to be loaded by me? If to be loaded, how to load it?

    Yes, you need to load the flash-based bootloader by JTAG. Loading the bootloader through JTAG is no different than loading any program such as blinky or hello program.

    Ram: Where it will check for the valid application? In the flash? or the external device? Assume if the MCU is used for the first time and there is no firmware loaded in it, how to proceed in such case?

    The bootloader will check the first two locations of the flash where the application is expected to reside. For example, if you look at the boot_serial example, it is configured to program the application at 0x4000. Therefore, the bootloader will first check if the first two locations at 0x4000 are non-F's value. If they are F's, then there is no application there yet. When a flash is erased, the data will be F's. If there is a non-F's value then the bootloader will just jump to 0x4000 to execute the application. Please refer to the user's guide and boot_serial example. Look at the bl_config.h file. 

    Ram: boot_serial program will download the boot_demo1 from where? which memory?

    The external host (your PC) will run the download tool such as LM Flash Programmer or Uniflash that will send the binary to the MCU through the UART. This means you will need to hookup the MCU to the PC and the data is downloaded from the PC through the Virtual COM port. 

  • Does it mean that whenever the bootloader wanted to load or update the firmware during the boot program execution, the UART connection should exist between the PC and MCU?

    Assume, I do have a boot loader runs from 0x0000 and valid application(ex. image1.bin) already exists at 0x4000 and the upgraded firmware application(ex. image2.bin) stored in SD Card interfaced with MCU through UART need to be upgraded to send to the MCU where image1.bin resides. One more case is that if the SD  card have the image1.bin, the boot loaded does not need to upgrade the firmware.

    Which program decide in this case that firmware upgrade is necessary?

  • Does it mean that whenever the bootloader wanted to load or update the firmware during the boot program execution, the UART connection should exist between the PC and MCU?

    The UART is setup by the bootloader. Therefore, if the bootloader is running then the UART is already initialized (e.g. the UART instance you specify, baud rate, STOP bits and parity). See below configuration in bl_config.h related to UART. 

    //*****************************************************************************
    //
    // Selects the UART as the port for communicating with the boot loader.
    //
    // Depends on: None
    // Exclusive of: CAN_ENABLE_UPDATE, ENET_ENABLE_UPDATE, I2C_ENABLE_UPDATE,
    //               SSI_ENABLE_UPDATE, USB_ENABLE_UPDATE
    // Requires: UART_AUTOBAUD or UART_FIXED_BAUDRATE, UART_CLOCK_ENABLE, 
    //           UARTx_BASE, UART_RXPIN_CLOCK_ENABLE, UART_RXPIN_BASE, 
    //           UART_RXPIN_PCTL, UART_RXPIN_POS, UART_TXPIN_CLOCK_ENABLE,
    //           UART_TXPIN_BASE, UART_TXPIN_PCTL and UART_TXPIN_POS
    //
    //*****************************************************************************
    #define UART_ENABLE_UPDATE
    
    //*****************************************************************************
    //
    // Enables automatic baud rate detection.  This can be used if the crystal
    // frequency is unknown, or if operation at different baud rates is desired.
    //
    // Depends on: UART_ENABLE_UPDATE
    // Exclusive of: UART_FIXED_BAUDRATE
    // Requires: None
    //
    //*****************************************************************************
    //#define UART_AUTOBAUD
    
    //*****************************************************************************
    //
    // Selects the baud rate to be used for the UART.
    //
    // Depends on: UART_ENABLE_UPDATE, CRYSTAL_FREQ
    // Exclusive of: UART_AUTOBAUD
    // Requires: None
    //
    //*****************************************************************************
    #define UART_FIXED_BAUDRATE     115200
    
    //*****************************************************************************
    //
    // Selects the clock enable for the UART peripheral module
    //
    // Depends on: UART_ENABLE_UPDATE
    // Exclusive of: None
    // Requires: UARTx_BASE
    //
    //*****************************************************************************
    #define UART_CLOCK_ENABLE     SYSCTL_RCGCUART_R0
    
    //*****************************************************************************
    //
    // Selects the base address of the UART peripheral module
    //
    // Depends on: UART_ENABLE_UPDATE
    // Exclusive of: None
    // Requires: UART_CLOCK_ENABLE
    //
    //*****************************************************************************
    #define UARTx_BASE     UART0_BASE
    
    //*****************************************************************************
    //
    // Selects the clock enable for the GPIO corresponding to UART RX pin
    //
    // Depends on: UART_ENABLE_UPDATE
    // Exclusive of: None
    // Requires: UART_RXPIN_BASE, UART_RXPIN_PCTL and UART_RXPIN_POS
    //
    //*****************************************************************************
    #define UART_RXPIN_CLOCK_ENABLE     SYSCTL_RCGCGPIO_R0
    
    //*****************************************************************************
    //
    // Selects the base address for the GPIO corresponding to UART RX pin
    //
    // Depends on: UART_ENABLE_UPDATE
    // Exclusive of: None
    // Requires: UART_RXPIN_CLOCK_ENABLE, UART_RXPIN_PCTL and UART_RXPIN_POS
    //
    //*****************************************************************************
    #define UART_RXPIN_BASE     GPIO_PORTA_BASE
    
    //*****************************************************************************
    //
    // Selects the port control value for the GPIO corresponding to UART RX pin
    //
    // Depends on: UART_ENABLE_UPDATE
    // Exclusive of: None
    // Requires: UART_RXPIN_CLOCK_ENABLE, UART_RXPIN_BASE and UART_RXPIN_POS
    //
    //*****************************************************************************
    #define UART_RXPIN_PCTL     0x1
    
    //*****************************************************************************
    //
    // Selects the pin number for the GPIO corresponding to UART RX pin
    //
    // Depends on: UART_ENABLE_UPDATE
    // Exclusive of: None
    // Requires: UART_RXPIN_CLOCK_ENABLE, UART_RXPIN_BASE and UART_RXPIN_PCTL
    //
    //*****************************************************************************
    #define UART_RXPIN_POS     0
    
    //*****************************************************************************
    //
    // Selects the clock enable for the GPIO corresponding to UART TX pin
    //
    // Depends on: UART_ENABLE_UPDATE
    // Exclusive of: None
    // Requires: UART_TXPIN_BASE, UART_TXPIN_PCTL and UART_TXPIN_POS
    //
    //*****************************************************************************
    #define UART_TXPIN_CLOCK_ENABLE     SYSCTL_RCGCGPIO_R0
    
    //*****************************************************************************
    //
    // Selects the base address for the GPIO corresponding to UART TX pin
    //
    // Depends on: UART_ENABLE_UPDATE
    // Exclusive of: None
    // Requires: UART_TXPIN_CLOCK_ENABLE, UART_TXPIN_PCTL and UART_TXPIN_POS
    //
    //*****************************************************************************
    #define UART_TXPIN_BASE     GPIO_PORTA_BASE
    
    //*****************************************************************************
    //
    // Selects the port control value for the GPIO corresponding to UART TX pin
    //
    // Depends on: UART_ENABLE_UPDATE
    // Exclusive of: None
    // Requires: UART_TXPIN_CLOCK_ENABLE, UART_TXPIN_BASE and UART_TXPIN_POS
    //
    //*****************************************************************************
    #define UART_TXPIN_PCTL     0x1
    
    //*****************************************************************************
    //
    // Selects the pin number for the GPIO corresponding to UART TX pin
    //
    // Depends on: UART_ENABLE_UPDATE
    // Exclusive of: None
    // Requires: UART_TXPIN_CLOCK_ENABLE, UART_TXPIN_BASE and UART_TXPIN_PCTL
    //
    //*****************************************************************************
    #define UART_TXPIN_POS     1

    Assume, I do have a boot loader runs from 0x0000 and valid application(ex. image1.bin) already exists at 0x4000 and the upgraded firmware application(ex. image2.bin) stored in SD Card interfaced with MCU through UART need to be upgraded to send to the MCU where image1.bin resides. One more case is that if the SD  card have the image1.bin, the boot loaded does not need to upgrade the firmware.

    Which program decide in this case that firmware upgrade is necessary?

    Your image1.bin can decide if you need to upgrade the firmware. I thought you wanted to read the CRC for image2 from the SD card to determine if an upgrade is needed. It is all decided by your software. You can also use a pin just like the boot_demo1. When a specified pin is detected, it will jump to the bootloader. This is an system/application level question that you need to answer for yourself.   

  • Not sure what is not clear on the example and the user's guide. I will suggest you first run the example as is to get a feel for it. There is a boot_serial program and there is also a boot_demo1 program.

    Ram: Which program should be loaded first? Can we load the programs using CCS and establish debug session?

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

    The boot_serial is a flash-based bootloader that resides on the flash at 0x0. After power up, the bootloader will run and if it does not find a valid application then it will be in boot mode. If there is a valid application firmware detected then it will directly jump to the application. 

    Ram: How to debug the bootloader program and the jumping of the bootloader to application in CCS by establishing debug session through setting a breakpoint?

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

    Let's suppose there is not a valid application yet.  The boot_serial will download the boot_demo1 firmware after the bootloader receives a command from the host through the UART port.

    Ram: My requirement is access the firmware .bin file stored in SD card which is interfaced through UART with the MCU and then use the firmware .bin file in flash for upgrading. Do I need to update the bootloader program?

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

    After the firmware is downloaded, it will reset the device and jump to the application since there is now a valid application. This is basically how a bootloader works. The boot_demo1 is a simple application firmware example that will blink the LED. 

    Ram: How to debug the transition from bootloader to application and see the LED blink etc.,

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

  • Ram: Which program should be loaded first? Can we load the programs using CCS and establish debug session?

    Can you go back to all the answers I provided before. I thought I already gave you the answer. You need to load the bootloader first using JTAG. You can load the bootloader using CCS just like any program like a hello or a blinky program. 

    Ram: How to debug the bootloader program and the jumping of the bootloader to application in CCS by establishing debug session through setting a breakpoint?

    Debug the bootloader is like debugging any program. Make sure you load the symbols. You can set up breakpt or single step. 

    Ram: My requirement is access the firmware .bin file stored in SD card which is interfaced through UART with the MCU and then use the firmware .bin file in flash for upgrading. Do I need to update the bootloader program?

    No, you don't need to update the bootloader program. After the firmware is programmed, it is up to the firmware to decide if an upgrade is needed or not. If the firmware decides it needs to upgrade for a new firmware it will jump back to the bootloader. Please, why don't you run the examples first.

    Ram: How to debug the transition from bootloader to application and see the LED blink etc.,

    After the firmware is loaded, you need to load the symbols for the firmware. See below.