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.

TM4C123GH6PZ: CAN Enabled Flash Bootloader Questions

Part Number: TM4C123GH6PZ
Other Parts Discussed in Thread: UNIFLASH

I have a custom board with the above TIVA part.  We have an application that is currently in production and reliable.  The goal is to implement a flash bootloader that will allow application updates via the CAN bus (which is the primary comm link on the board.  

My though was to implement this in several steps:

1.  Use the TI serial_boot example found in the TivaWare examples to start. 

2. Verify that  the bootloader  hands over control to the application and the application functions properly.

3. Program the application via the serial

3. Using the serial_boot example as a baseline, modify the bootloader to use the CAN bus in place of the serial.

The problem is that I can't beyond step 1.  The bootloader and application have been modified to reflect the correct memory spaces.  

The bl_config.h file in the boot_serial project has been modified to include:

#define VTABLE_START_ADDRESS    0x2800

#define APP_START_ADDRESS       0x2800

The file tm4c123gh6pz_startup.cmd in the application was modified:

#define APP_BASE_ADDR 0x00002800
#define RAM_BASE_ADDR 0x20000000

MEMORY
{
FLASH (RX) : origin = APP_BASE_ADDR, length = 0x0003d800
SRAM (RWX) : origin = 0x20000000, length = 0x00008000
}

/* The following command line options are set as part of the CCS project. */
/* If you are building using the command line, or for some reason want to */
/* define them here, you can uncomment and modify these lines as needed. */
/* If you are using CCS for building, it is probably better to make any such */
/* modifications in your CCS project and leave this file alone. */
/* */
/* --heap_size=0 */
/* --stack_size=256 */
/* --library=rtsv7M4_T_le_eabi.lib */

/* Section allocation in memory */

SECTIONS
{
.intvecs: > APP_BASE_ADDR
.text : > FLASH
.const : > FLASH
.cinit : > FLASH
.pinit : > FLASH
.init_array : > FLASH

.vtable : > RAM_BASE_ADDR
.data : > SRAM
.bss : > SRAM
.sysmem : > SRAM
.stack : > SRAM
}

Using the UniFlash application, I load the boot_serial.bin to address 0x0000 and the application to address 0x2800

My expectation is that the bootloader would run, there is no serial input and would transfer control to the application at start address 0x2800 but it's not happening.  I am basing this on the LED indicator on the board that is lit immediately upon the application init.

My questions are:

1. Are my expectations incorrect?  Is there something I am missing?  Should the example boot_serial not start the application?

2. What is the best approach to debugging the bootloader?  I'm using CCS7 as my development environment and the XDS2xx USB emulator.

Thanks!

  • the second file is tm4c123gh6pz.cmd
  • Hello Brian,

    Brian Savage said:
    My expectation is that the bootloader would run, there is no serial input and would transfer control to the application at start address 0x2800 but it's not happening.  I am basing this on the LED indicator on the board that is lit immediately upon the application init.

    That understanding is not right, the application location would be checked first and then if there is an application, it would just go into the application, so what you are seeing is right. You need to trigger the boot loader if there is a valid application already loaded.

    boot_serial lays underneath the application in is only invoked when triggered or if when it powers up, an invalid application is in place. Then when invoked it will program the new application and then once more wait until it is invoked or the application is not valid. The check it does at startup to verify the application is described here:

    //*****************************************************************************
    //
    // The starting address of the application.  This must be a multiple of 1024
    // bytes (making it aligned to a page boundary).  A vector table is expected at
    // this location, and the perceived validity of the vector table (stack located
    // in SRAM, reset vector located in flash) is used as an indication of the
    // validity of the application image.
    //
    // The flash image of the boot loader must not be larger than this value.
    //
    // Depends on: None
    // Exclusive of: None
    // Requires: None
    //
    //*****************************************************************************
    #define APP_START_ADDRESS       0x4000

  • Thanks for the reply.  So, the flash bootloader at address 0x0000 and the application at 0x4000 is correct though?  

    The overall goal is that the application runs, there is a "program mode" GPIO that is read.  If the GPIO is low, then the system is in program mode.  There are multiple CAN nodes that may be updated.  Each has a specific "Start Programming" CAN message that would call the bootloader to update the flash on that specific node.  

    I'm still not able to get the application to start.  

  • Just to clarify, the ROM bootloader will "skip" the flash bootloader if there is a valid application loaded at the application start address specified? How does the ROM bootloader know what the start address is?
  • Hello Brian,

    The ROM bootloader will look for a valid reset vector, and if it sees one then it will set the device to execute from Flash instead which would then invoke the Flash bootloader. From there the Flash Bootloader would then follow the behavior I mentioned before where it sees a valid application and then executes it instead.

    This is how the Flash Bootloader can be used over the ROM bootloader even though the ROM bootloader supports some of the serial interfaces.

    This excerpt from the datasheet gives further details on the ROM Bootloader conditions:

    After Power-On-Reset (POR) and device initialization occurs, the hardware loads the stack pointer from either flash or ROM based on the presence of an application in flash and the state of the EN bit in the BOOTCFG register. If the flash address 0x0000.0004 contains an erased word (value 0xFFFF.FFFF) or the EN bit is of the BOOTCFG register is clear, the stack pointer and reset vector pointer are loaded from ROM at address 0x0100.0000 and 0x0100.0004, respectively. The boot loader executes and configures the available boot slave interfaces and waits for an external memory to load its software. If the check of the Flash at address 0x0000.0004 contains a valid reset vector value and the BOOTCFG register does not indicate the boot loader, the boot sequence causes the stack pointer/reset vector fetch from Flash. This application stack pointer and reset vector is loaded and the processor executes the application directly.

  • Ralph -

    I am using the boot_serial example for initial testing (we need to migrate to CAN instead of serial, but I just want it to start my application right now.  I had more time today to get back on this effort.  What I found is that if I flash (using UniFlash) boot_serial.bin to address 0x0000, then verify by comparing to the .bin file at 0x0000 it returns successfully.  Then if I flash my application to 0x4000, I can verify the application at that location.  However, if I then go back at that point and try to verify the boot_serial.bin at 0x0000 it fails.  Uniflash output:

    [14:20:01] Begin Launching session operation.
    [14:20:04] CORTEX_M4_0: GEL Output:
    Memory Map Initialization Complete

    [14:20:04] Operation Launching session returned.
    [14:20:04] Loaded target configuration from: C:\TivaWorkspace\cpd_cca\CPD_CCA.ccxml
    [14:20:19] Begin Writing flash memory operation.
    [14:20:21] Loading program at 0x0: C:\TivaWorkspace\boot_serial\Debug\boot_serial.bin
    [14:20:22] Operation Writing flash memory returned.
    [14:20:33] Begin Verifying flash memory operation.
    [14:20:34] Verifying program at 0x0: C:\TivaWorkspace\boot_serial\Debug\boot_serial.bin
    [14:20:34] CORTEX_M4_0: Program verification successful for C:\TivaWorkspace\boot_serial\Debug\boot_serial.bin

    [14:20:35] Operation Verifying flash memory returned.
    [14:20:44] Begin Writing flash memory operation.
    [14:20:45] Loading program at 0x4000: C:\TivaWorkspace\cpd_cca\Debug\102043.bin
    [14:20:48] Operation Writing flash memory returned.
    [14:20:59] Begin Verifying flash memory operation.
    [14:21:00] Verifying program at 0x4000: C:\TivaWorkspace\cpd_cca\Debug\102043.bin
    [14:21:00] CORTEX_M4_0: Program verification successful for C:\TivaWorkspace\cpd_cca\Debug\102043.bin

    [14:21:01] Operation Verifying flash memory returned.
    [14:21:13] Begin Verifying flash memory operation.
    [14:21:14] Verifying program at 0x0: C:\TivaWorkspace\boot_serial\Debug\boot_serial.bin
    [14:21:14] ERROR >> CORTEX_M4_0: File Loader: Verification failed: Values at address 0x0000000000000000 do not match Please verify target memory and memory map.

    [14:21:14] File: C:\TivaWorkspace\boot_serial\Debug\boot_serial.bin: a data verification error occurred, file load failed.
    [14:21:15] Operation Verifying flash memory returned.

    Is UniFlash clearing/overwriting the bootloader in flash?  

  • Hello Brian,

    Ah I see the issue in your process, it sounds like you are loading the application via the ICDI and not via the boot loader. You'd need to load the application via the boot loader to not have it erased, so you'd want to reboot the board and then connect Uniflash via serial and not via ICDI. I had thought you were uploading the application via the boot loader.
  • I'm connected to the JTAG via a USB2xx debug probe. Device Manager on my laptop shows two serial port connections:
    XDS2xx Emulator CDC Serial Port (COM4)
    XDS2xx User CDC Serial Port (COM 5)

    Are one of these connections appropriate for loading the application? I'm trying to get it to connect, but it's not working.
  • This is a custom production board by the way.
  • Hi Brian,

    So I had been under the impression that Uniflash would just invoke the boot loader when it was properly programmed in, but it looks like it operates more like CCS and it doesn't try and invoke the boot loader at all. Perhaps via command line it would be possible to do this, but that isn't practical for what you want to test.

    Can you try these tests with our LMFlash Programmer instead? You can download it from here: www.ti.com/.../LMFLASHPROGRAMMER

    LMFlash Programmer is designed to program TM4C MCU's and definitely supports the serial boot loader, that is how I've used the serial_boot example for years.
  • I programmed the boot_serial.bin with UniFlash, then started LM Flash Programmer, but it's not recognizing the connection. I'm tried both COM4/5 as listed above. Am I correct in thinking that the serial connection is present in the JTAG connection via the emulator?
  • Hello Brian,

    I'm sorry, I was so focused on testing the Uniflash/LM Flash issues with my LaunchPad's that I wasn't thinking of the additional challenge from a hardware standpoint when using a custom board. The JTAG connection via the XDS200 would not tie into the serial boot loader on a custom board, because the point of the serial boot loader is to program the board without a JTAG probe.

    You would need a connection from your PC to the UART which is usually done via an FTDI cable. I've done tests with FTDI cables connecting to LM Flash so I know that definitely works. Though if you aren't going to do a UART boot loader on your board and don't have the connections for it, then you may want to consider starting with a LaunchPad where you can access the UART boot loader via the ICDI and then when you get that setup to your liking and have learned more about the boot loader process, you can then move to testing out the CAN boot loader on your custom board.
  • Ok, I'm going to step back and re-evaluate my plan. Thank you for the help
  • Glad to help and sorry I didn't give you that important info sooner.
  • Is there a good tutorial or thread on debugging bootloaders ont eh TIVA?

  • Hello Brian,

    I am not aware of any, I can't think of a time I actually debugged the bootloader. It works very well when configured properly, and configuration is covered in the TIvaWare Bootloader guide under Section 8.
  • Can you explain the function/purpose of the UART to CAN Bridge.  I know what I think it should do, but some things I'm reading don't make sense to me.

  • Hi Brian,

    I haven't used that feature myself yet but see if this explanation from Charles helps: e2e.ti.com/.../2498842