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.

TM4C ethernet bootloader writes to flash incorrectly

Hello all,

I'm using a Tiva TM4C chip in a product that requires both an application an ethernet-based bootloader.  After much weeping and gnashing of teeth the bootloader compiles, checks if a firmware download is required, and branches to the application.  The application, then, runs properly.  

This all works beautifully if downloaded through the JTAG interface directly.  I can use LMFlash to either download the bootloader first (after erasing all chip memory) and then follow it with the application at the specified memory offset, or I can merge the files and download a single merged binary image.  Both work beautifully.

It falls on its face when the bootloader is used to download the application image.  

Our boot process works like this:

1. Connect to our application via our proprietary communication protocol.  Our firmware reflash command instructs the chip to write a byte to a specific location in off-chip EEPROM and then reboot itself.  

2. The bootloader initializes its SPI interface to read from that EEPROM address.  If the boot flag is NOT set, it branches directly to the application (loads its reset vector and reboots).  If the boot flag IS set, it proceeds to bring up the ethernet interface, send a BOOTP request and initiate the TFTP file transfer.  This transfer appears to complete properly, according to wireshark traces.

3.  Following the TFTP transfer the bootloader flag is cleared and the chip reboots itself.

4.  The bootloader again fires up the SPI interface, reads the EEPROM byte and (since it's cleared) branches to the application.  At this point the device becomes unresponsive.  My only recourse is to flash it directly via JTAG.

The debugger doesn't work with the bootloader for reasons I don't fully understand, so I can't really monitor its execution.  We don't have much in the way of GPIO on this board, so I cannot use LEDs to blink status information for any sort of feedback.  It literally either works or it doesn't - and I'm running out of ideas.

The only method I've found that can actually tell me anything useful is to extract the memory of the chip following both programming methods.  First, JTAG the merged image (or bootloader and application separately - same effect) and extract it directly to a temp file.  Second, use the bootloader to download the application image, and extract the result of that write.

The two images should be identical, but they are not.

The following differences exist:

1. The bootloader section (0x00 --> 0x8000) matches perfectly.  This is expected, as the bootloader is not allowed to overwrite itself.  

2. There are three other sections that match:  0xBC00 - 0xBFFF, 0xFC00 - 0xFFFF, and 0x10400 to the end of the image.

The bootloader determines where to put each TFTP packet's data as follows (taken from ParseTFTPData() in bl_emac.c):

    //
    // What address are we about to program to?
    //
    ui32FlashAddr = ((g_ui32TFTPBlock - 1) * TFTP_BLOCK_SIZE) + APP_START_ADDRESS;

    //
    // Do not program this data into flash if it is beyond the end of flash.
    //
    //if(ui32FlashAddr < g_ui32FlashEnd)

    // Do not program this data into flash if it is beyond the end of flash or below APP_START_ADDRESS.
    if( (ui32FlashAddr < g_ui32FlashEnd) && (ui32FlashAddr >= APP_START_ADDRESS) )
    {
        (...erase the flash block, write to it, move on to the next...  Omitted for clarity, but available upon request.)
    }

Some things to note about that code:

* APP_START_ADDRESS is defined as 0x8000.  Remember, this jump to the application space works just fine if flashed with the JTAG.

* The initial intent was to overwrite the bootloader as well as the application, but we decided against that approach.  This is why there are two "if" lines, one of which is commented out.  It is entirely possible that I broke something in this line or one like it, but I haven't been able to find the error.

The tool VBindiff was used to examine and compare the firmware images at the hex level.

I'm not sure how to attach files to this post, but I'm happy to share the binary images I mentioned here if you'd like to confirm my findings.

Any thoughts?  I'd love to hear them.

  • Hello Glenn,

    Sorry for the delayed response.

    As far as I can understand, you flow is to program the flash based Ethernet bootloader through the JTAG (LMFLASH + ICDI?) and then use this flash-based Ethernet bootloader to program the application.

    TivaWare has example code to demonstrate this exact scenario. The flash-based Ethernet bootloader is called "boot_emac_flash" and the accompanying applications (that will work with ""boot_emac_flash") are "boot_demo_emac_flash" and "boot_demo_flash".

    Did you already look at these examples and try them on any board? It would be useful (I think) if you can first try these examples and then see where/how your application is different.

    Thanks,
    Sai