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.

EK-TM4C1294XL: TCP Bootloader, Issue in jump to app

Other Parts Discussed in Thread: EK-TM4C1294XL, ENERGIA, TM4C1294NCPDT, UNIFLASH

Hi everybody, I currently use John's TCP Bootloader on my EK-TM4C1294XL board. It's simply great. Here is the link to his post:

https://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/p/587260/2294240?tisearch=e2e-sitesearch&keymatch=tm4c%20tcp%20bootloader#2294240

Now, I would like to slightly modify the bootloader so that after a firmware update, the BOOTLOADING location in the EEPROM is not written by the bootloader itself, but it will be writte by the main app only when it is proven to be stable and ok.

This way, if by mistake I update the Board with a main app that doesn't work and gets stuck, I do not have to manually (i.e. connecting locally to the board with USB and use LM Flash Programmer, or Energia, or any other flashing tool) reprogram the BOOTLOADING location in the EEPROM, but a simple switch OFF - switch ON of the board (or Watchdog expiration) is sufficient to bring it into the bootloader and allow to update a new firmware.

So, within John's function read_localClient, after the firmware transfer in the flash memory at address 0x00010000, I commented out the code which writes BOOTLOADING with 0 and issues an endless loop, and added instead the same code fragment which is contained in the setup function to jump to the main app:

HWREG(0xE000E000 + (0xD08)) = (0x10000 & 0xFFFFF); // Update vector table offset register
asm(" MOVW r0, #0x0000"); // Load r0-Low with low-part of the address, 2-bytes
asm(" MOVT r0, #0x0001"); // Load r0-High with high-part of the address, 2-bytes
asm(" ldr sp, [r0]"); // Load app vector address into SP
asm(" ldr r0, [r0, #4]"); // Prepare jump to starting address + 4
asm(" bx r0"); // Make the jump

But unfortunately, when I try to flash a firmware, the file is completely transferred from TCP client to the board by means of the BL, but the jump to main app does not succeed: the board resets and the BL is started.

Attached you can find a compare between John's original code (on the left) and my modification.

What am I doing wrong with the modifications?

regards

Simone

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style>
.AlignLeft { text-align: left; }
.AlignCenter { text-align: center; }
.AlignRight { text-align: right; }
body { font-family: sans-serif; font-size: 11pt; }
td { vertical-align: top; padding-left: 4px; padding-right: 4px; }

tr.SectionGap td { font-size: 4px; border-left: none; border-top: none; border-bottom: 1px solid Black; border-right: 1px solid Black; }
tr.SectionAll td { border-left: none; border-top: none; border-bottom: 1px solid Black; border-right: 1px solid Black; }
tr.SectionBegin td { border-left: none; border-top: none; border-right: 1px solid Black; }
tr.SectionEnd td { border-left: none; border-top: none; border-bottom: 1px solid Black; border-right: 1px solid Black; }
tr.SectionMiddle td { border-left: none; border-top: none; border-right: 1px solid Black; }
tr.SubsectionAll td { border-left: none; border-top: none; border-bottom: 1px solid Gray; border-right: 1px solid Black; }
tr.SubsectionEnd td { border-left: none; border-top: none; border-bottom: 1px solid Gray; border-right: 1px solid Black; }
table.fc { border-top: 1px solid Black; border-left: 1px solid Black; width: 100%; font-family: monospace; font-size: 10pt; }
td.TextItemInsigAdd { color: #000000; background-color: #EEEEFF; }
td.TextItemInsigDel { color: #000000; background-color: #EEEEFF; text-decoration: line-through; }
td.TextItemInsigMod { color: #000000; background-color: #EEEEFF; }
td.TextItemInsigOrphan { color: #000000; background-color: #FAEEFF; }
td.TextItemNum { color: #696969; background-color: #F0F0F0; }
td.TextItemSame { color: #000000; background-color: #FFFFFF; }
td.TextItemSigAdd { color: #000000; background-color: #FFE3E3; }
td.TextItemSigDel { color: #000000; background-color: #FFE3E3; text-decoration: line-through; }
td.TextItemSigMod { color: #000000; background-color: #FFE3E3; }
td.TextItemSigOrphan { color: #000000; background-color: #F1E3FF; }
.TextSegInsigDiff { color: #0000FF; }
.TextSegReplacedDiff { color: #0000FF; font-style: italic; }
.TextSegSigDiff { color: #FF0000; }
</style>
<title>Text Compare</title>
</head>
<body>
<table class="fc" cellspacing="0" cellpadding="0">
<tr class="SectionMiddle">
<td class="TextItemSame">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; Serial.print(&quot; END &quot;);</td>
<td class="AlignCenter">&nbsp;</td>
<td class="TextItemSame">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; Serial.print(&quot; END &quot;);</td>
</tr>
<tr class="SectionMiddle">
<td class="TextItemSame">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; Serial.print(last_part);</td>
<td class="AlignCenter">&nbsp;</td>
<td class="TextItemSame">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; Serial.print(last_part);</td>
</tr>
<tr class="SectionMiddle">
<td class="TextItemSame">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; Serial.println(&quot; bytes of Final-Block transfered.............. &quot;);</td>
<td class="AlignCenter">&nbsp;</td>
<td class="TextItemSame">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; Serial.println(&quot; bytes of Final-Block transfered.............. &quot;);</td>
</tr>
<tr class="SectionMiddle">
<td class="TextItemSame">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; Serial.println(&quot;&quot;);</td>
<td class="AlignCenter">&nbsp;</td>
<td class="TextItemSame">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; Serial.println(&quot;&quot;);</td>
</tr>
<tr class="SectionMiddle">
<td class="TextItemSame">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</td>
<td class="AlignCenter">&nbsp;</td>
<td class="TextItemSame">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</td>
</tr>
<tr class="SectionEnd">
<td class="TextItemSame">&nbsp;&nbsp;&nbsp; digitalWrite(PN_1, LOW);</td>
<td class="AlignCenter">&nbsp;</td>
<td class="TextItemSame">&nbsp;&nbsp;&nbsp; digitalWrite(PN_1, LOW);</td>
</tr>
<tr class="SectionBegin">
<td class="TextItemSame">&nbsp;</td>
<td class="AlignCenter">&lt;&gt;</td>
<td class="TextItemSigMod"><span class="TextSegInsigDiff">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; </span><span class="TextSegSigDiff">#if</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">0</span></td>
</tr>
<tr class="SectionEnd">
<td class="TextItemInsigMod"><span class="TextSegInsigDiff">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; </span>EEPROM.write(BOOTLOADING, 0);</td>
<td class="AlignCenter">&nbsp;</td>
<td class="TextItemInsigMod"><span class="TextSegInsigDiff">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; </span>EEPROM.write(BOOTLOADING, 0);</td>
</tr>
<tr class="SectionBegin">
<td class="TextItemSame">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; delay(500);</td>
<td class="AlignCenter">=</td>
<td class="TextItemSame">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; delay(500);</td>
</tr>
<tr class="SectionMiddle">
<td class="TextItemSame">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; Serial.println(&quot;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&nbsp;&nbsp; IoT module will now REBOOT in main_application in 6 seconds&nbsp;&nbsp; &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&quot;);</td>
<td class="AlignCenter">&nbsp;</td>
<td class="TextItemSame">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; Serial.println(&quot;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&nbsp;&nbsp; IoT module will now REBOOT in main_application in 6 seconds&nbsp;&nbsp; &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&quot;);</td>
</tr>
<tr class="SectionMiddle">
<td class="TextItemSame">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; while (1)&nbsp; /// Watchdog0 will issue a rebboot in 6 seconds</td>
<td class="AlignCenter">&nbsp;</td>
<td class="TextItemSame">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; while (1)&nbsp; /// Watchdog0 will issue a rebboot in 6 seconds</td>
</tr>
<tr class="SectionMiddle">
<td class="TextItemSame">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; {</td>
<td class="AlignCenter">&nbsp;</td>
<td class="TextItemSame">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; {</td>
</tr>
<tr class="SectionMiddle">
<td class="TextItemSame">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</td>
<td class="AlignCenter">&nbsp;</td>
<td class="TextItemSame">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</td>
</tr>
<tr class="SectionEnd">
<td class="TextItemSame">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; }</td>
<td class="AlignCenter">&nbsp;</td>
<td class="TextItemSame">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; }</td>
</tr>
<tr class="SectionBegin">
<td class="TextItemSame">&nbsp;</td>
<td class="AlignCenter">-+</td>
<td class="TextItemSigMod"><span class="TextSegInsigDiff">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; </span><span class="TextSegSigDiff">#endif</span></td>
</tr>
<tr class="SectionMiddle">
<td class="TextItemSame">&nbsp;</td>
<td class="AlignCenter">&nbsp;</td>
<td class="TextItemInsigMod"><span class="TextSegInsigDiff">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span></td>
</tr>
<tr class="SectionMiddle">
<td class="TextItemSame">&nbsp;</td>
<td class="AlignCenter">&nbsp;</td>
<td class="TextItemSigMod"><span class="TextSegInsigDiff">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; </span><span class="TextSegSigDiff">#if</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">1</span><span class="TextSegInsigDiff">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span><span class="TextSegSigDiff">//Simone:</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">go</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">to</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">main</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">app</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">after</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">FLASH</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">update</span></td>
</tr>
<tr class="SectionMiddle">
<td class="TextItemSame">&nbsp;</td>
<td class="AlignCenter">&nbsp;</td>
<td class="TextItemSigMod"><span class="TextSegInsigDiff">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; </span><span class="TextSegSigDiff">system_watchdog_feed();</span></td>
</tr>
<tr class="SectionMiddle">
<td class="TextItemSame">&nbsp;</td>
<td class="AlignCenter">&nbsp;</td>
<td class="TextItemSigMod"><span class="TextSegInsigDiff">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; </span><span class="TextSegSigDiff">HWREG(0xE000E000</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">+</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">(0xD08))</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">=</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">(0x10000</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">&amp;</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">0xFFFFF);</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">//</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">Update</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">vector</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">table</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">offset</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">register</span></td>
</tr>
<tr class="SectionMiddle">
<td class="TextItemSame">&nbsp;</td>
<td class="AlignCenter">&nbsp;</td>
<td class="TextItemSigMod"><span class="TextSegInsigDiff">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; </span><span class="TextSegSigDiff">asm(&quot;</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">MOVW</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">r0,</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">#0x0000&quot;);</span><span class="TextSegInsigDiff">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span><span class="TextSegSigDiff">//</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">Load</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">r0-Low</span><span class="TextSegInsigDiff">&nbsp; </span><span class="TextSegSigDiff">with</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">low-part</span><span class="TextSegInsigDiff">&nbsp; </span><span class="TextSegSigDiff">of</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">the</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">address,</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">2-bytes</span></td>
</tr>
<tr class="SectionMiddle">
<td class="TextItemSame">&nbsp;</td>
<td class="AlignCenter">&nbsp;</td>
<td class="TextItemSigMod"><span class="TextSegInsigDiff">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; </span><span class="TextSegSigDiff">asm(&quot;</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">MOVT</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">r0,</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">#0x0001&quot;);</span><span class="TextSegInsigDiff">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span><span class="TextSegSigDiff">//</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">Load</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">r0-High</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">with</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">high-part</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">of</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">the</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">address,</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">2-bytes</span></td>
</tr>
<tr class="SectionMiddle">
<td class="TextItemSame">&nbsp;</td>
<td class="AlignCenter">&nbsp;</td>
<td class="TextItemSigMod"><span class="TextSegInsigDiff">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; </span><span class="TextSegSigDiff">asm(&quot;</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">ldr</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">sp,</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">[r0]&quot;);</span><span class="TextSegInsigDiff">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span><span class="TextSegSigDiff">//</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">Load</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">app</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">vector</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">address</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">into</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">SP</span></td>
</tr>
<tr class="SectionMiddle">
<td class="TextItemSame">&nbsp;</td>
<td class="AlignCenter">&nbsp;</td>
<td class="TextItemSigMod"><span class="TextSegInsigDiff">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; </span><span class="TextSegSigDiff">asm(&quot;</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">ldr</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">r0,</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">[r0,</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">#4]&quot;);</span><span class="TextSegInsigDiff">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span><span class="TextSegSigDiff">//</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">Prepare</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">jump</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">to</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">starting</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">address</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">+</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">4</span></td>
</tr>
<tr class="SectionMiddle">
<td class="TextItemSame">&nbsp;</td>
<td class="AlignCenter">&nbsp;</td>
<td class="TextItemSigMod"><span class="TextSegInsigDiff">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; </span><span class="TextSegSigDiff">asm(&quot;</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">bx</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">r0&quot;);</span><span class="TextSegInsigDiff">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span class="TextSegSigDiff">//</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">Make</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">the</span><span class="TextSegInsigDiff"> </span><span class="TextSegSigDiff">jump</span></td>
</tr>
<tr class="SectionMiddle">
<td class="TextItemSame">&nbsp;</td>
<td class="AlignCenter">&nbsp;</td>
<td class="TextItemSigMod"><span class="TextSegInsigDiff">&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; </span><span class="TextSegSigDiff">#endif</span></td>
</tr>
<tr class="SectionEnd">
<td class="TextItemSame">&nbsp;</td>
<td class="AlignCenter">&nbsp;</td>
<td class="TextItemInsigMod"><span class="TextSegInsigDiff">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span></td>
</tr>
<tr class="SectionBegin">
<td class="TextItemSame">}</td>
<td class="AlignCenter">=</td>
<td class="TextItemSame">}</td>
</tr>
<tr class="SectionMiddle">
<td class="TextItemSame">&nbsp;</td>
<td class="AlignCenter">&nbsp;</td>
<td class="TextItemSame">&nbsp;</td>
</tr>
</table>
<br/>
</body>
</html>

  • Hi Simone,
    You have a call to system_watchdog_feed(). How are you setting up the watchdog? Is it possible that your reset is due to the watchdog before the bx instruction or the application is run? Can you comment out the asm(" bx r0") and single step the new code you added?

    BTW, did you have a chance to try the TivaWare's ethernet bootloader example? In TivaWare's example, the application will wait for a magic word from the BOOTP client. When the magic word is received it will start the firmware update. You can also use a pin (i.e. pressing a switch) to force a firmware. I'm wondering if there is any issue that prevents you from referencing the TivaWare example?

  • Hi Charles, the watchdog setup is not changed respect to John's version of the bootloader, i.e.:

    void system_watchdog_setup()
    {
    /// Enable the watchdog peripheral
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_WDOG0);
    while(!ROM_SysCtlPeripheralReady(SYSCTL_PERIPH_WDOG0))
    {
    /// Wait for Watchdog module to be ready
    }
    
    /// Check to see if the registers are locked, and if so, unlock them.
    if(ROM_WatchdogLockState(WATCHDOG0_BASE) == true)
    {
    ROM_WatchdogUnlock(WATCHDOG0_BASE);
    }
    
    ROM_WatchdogReloadSet(WATCHDOG0_BASE, bl_SysClock * 3 ); // DTMF_lSysClock has been assined 120MHz at setup()
    // Boot in 6 seconds. (3 sec until 1st time-out & 
    // interrupt and another 3 sec for processor boot. 
    /// Enable the reset when watchdog expires
    ROM_WatchdogResetEnable(WATCHDOG0_BASE);
    
    /// Enable the watchdog interrupt
    // WatchdogIntEnable(WATCHDOG0_BASE);
    
    /// Enable the watchdog
    ROM_WatchdogEnable(WATCHDOG0_BASE);
    
    /// Get and print the reset cause
    if(ROM_SysCtlResetCauseGet() & SYSCTL_CAUSE_WDOG0) 
    {
    Serial.println("WatchDog Reset");
    }
    else if(ROM_SysCtlResetCauseGet() & SYSCTL_CAUSE_EXT) 
    {
    Serial.println("External reset");
    }
    ROM_SysCtlResetCauseClear(SYSCTL_CAUSE_WDOG0 | SYSCTL_CAUSE_EXT);
    
    /// ******************************************************************************** 
    Serial.println("*****************************************************************");
    Serial.println("*****************************************************************");
    Serial.print("System Clock Frequency has been set to: ");
    Serial.println(bl_SysClock);
    Serial.println("System WATCHDOG Reboot Time is set to : 6 seconds.");
    Serial.println("*****************************************************************");
    Serial.println("*****************************************************************");
    Serial.println("");
    }

    called in the setup() function just after TCP server has been started.

    I put a call to system_watchdog_feed() since I initially thought the board undue reset was caused by watchdog expiration before assembler instructions, but this did not solve the issue. Unfortunately I'm using Energia IDE (not CCS) so I do not have the possibility to perform a debug and step into the assembler code.

    Please could you (or John) confirm that I shall setup the lm4fcpp_snowflake.ld  linker file for compilation as in the following ?

    MEMORY
    {
    flash (rx) : ORIGIN = 0x00000000, LENGTH = 0x00100000
    ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000
    }

    for bootloader

    MEMORY
    {
    flash (rx) : ORIGIN = 0x00010000, LENGTH = 0x00040000
    ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000
    }

    for compilation of main app.

    Reagrds,

    Simone

  • Hi Simone,
    Is there any reason why you need to stick with the Energia IDE. If you are in any serious s/w development I will strongly suggest you use a full-fledged IDE like CCS or IAR or etc. I'm not familiar with the Energia platform. If it can't provide any debug capability then it is difficult to know what is going on. You can import the Energia into CCS. Perhaps that is one way for you to debug the problem in CCS. BTW, CCS is free though.

    I had a wrong comment in my earlier reply. I meant for you to comment out the system_watchdog_feed(), not the asm(" bx r0"). Sorry about that. I guess you have tried to comment out system_watchdog_feed(), correct?

    You haven't told me if there is anything wrong with the TivaWare bootloader example that prevents you from referencing it for your project.

    Where are the two linker command files coming from? Are you showing only partial portion of the files? I don't spot a problem with the linker commands you show above.

    The forum link where you show John's bootloader project in dropbox perhaps has been taken down. I will suggest you contact him directly for suggestions. In the forum you can try to contact him via a friend request.
  • Hi Charles,
    which application shall I use "as TCP client" in order to perform an update over the Internet (not within a simple LAN) with TivaWare Bootloader?

    The linker commands are from a linker file included in Energia IDE and used when compiling. The file has much more "instructions" but I only modified the address and size of FLASH portion when compiling bootloader or main application.

    thanks
    Simone
  • Hi Simone,
    TivaWare ethernet example can use LM flash programmer or the eflash.exe utility to update the firmware. The LM flash programmer acts as the BOOTP/TFTP server. I think it is only for LAN.

    The bootloader and your main app are two different projects. So at first glance I don't see a problem with your command file. One thing I notice is that for the bootloader the flash size is specified for 0x100000 (this is the entire 1Mbyte range). Your bootloader image should be less than 0x10000 since your application will start at 0x10000. Since they are two different projects and if you know for sure that the bootloader image will not exceed 0x10000 then having specify 0x100000 should be ok. But to stay on the safe side you can change the flash length to 0x10000 for the bootloader. I would image the bootloader linker command to contain SECTIONS where it specify the "run" and "load" addresses. The load address will be 0x0. After the bootloader is programmed into the flash memory there will be code to copy the bootloader itself into SRAM where the bootloader is actually run from. The run address will be 0x20000000. Please refer to the TivaWare example. I'm not sure if this is done in John's bootloader. You need to check. Anyway, if John's bootloader was working for you, why would you want to modify his linker command files?
  • I think it is only for LAN.

    -->this is why I did use John's BL instead of TivaWare.

    As regards modification of linker files this was requested for John's BL. I only needed a confirmation if I did it correct.

    I Will try to contact him.

    Thanks

    Simone

  • Hello Simone and thank you for mentioning "my" bootloader, which of course is a collective result of the work of many other developers here in the forum, of the help given to me from the forum's managers/gurus, and of some networking spicy touches of mine. The good thing is that it works at all times. The main issue regarding the over the internet bootloading/firmware updates-uploads is that the chunks of data that you may safely use when in remote access should be no more than 512 bytes per transfer cycle, while locally you can scale up to 16KB per transfer cycle.
    It has been some time since I coded the project, some minor modifications in between, and by now it seems that successfully handles remote firmware updating & control issues on more that 1500 IoT units. TIVA Ware's Ethernet local bootloaders are also of exceptional quality but I have experienced problems trying some modifications to enable them access cloud firmware servers and not only local PCs. Of course, problems are due to mistakes of mine that remain unsolved so far due to the limited time available to me to hack deeply on these issues. Next summer I hope I'll have very good results on a push-notification like cloud updating system that I'm coding from time-to-time and I will of course post the whole project here.
    I will post the latest version of the current bootloader software+firmware here some time tomorrow via a permanent dropbox link. Now let me see if I understand well the problem you are experiencing:

    The addresses for the linker file are correct given that when you compile for bootloader the app's RAM ranges are disabled and vice versa. (Don't forget the app's RAM addresses declarations also in the main app's code)

    Regarding what Charles is saying about the Tivaware's bootloader auto loading to SRAM after initial load is absolutely correct. The scenario Tivaware uses is as following: a) You always compile/link both your app and the Tivaware bootloader for same flash address 0x00000000. b) Then some bootloader code auto transfers bootloader from flash to SRAM c) Then bootloader waits for your app and places it at flash address 0x00000000 and of course overwrites its flash image which is not needed any more, and also relocates itself permanently into the upper flash.
    So the next time you want to change firmware you simply trigger the bootloader using to the outside pin functionality or if you have available EEPROM internally, by some hack of course, on the Tivaware bootloader of your choice.

    My bootloader can be also easily modified to relocate itself to the upper flash, via the first time's loading SRAM scenario, but since I use three different apps/firmwares onto the same flash of our IoTs that boot themselves according to EEPROM changes that caused from each distinct app's behavior, I want all space above the first 48KBs of flash to be free and manage it at will depending on the distinct apps' size.

    So, please check your app's source if the initial definitions of the RAM's/FLASH addresses are properly defined so the compiler will know how to handle source's relocation. Tomorrow I'll have more time and I'll check on your source thoroughly and I'll let you know.

    All the best to all the great guys here at the forum & HAPPY EQUINOX,
    John
  • Hi John, thanks for your reply.

    I cannot catch some points:

    The addresses for the linker file are correct given that when you compile for bootloader the app's RAM ranges are disabled and vice versa.


    Is it correct if I compile bootloader with:

    MEMORY 
    {
        flash (rx) : ORIGIN = 0x00000000, LENGTH = 0x00100000 
        ram  (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000 
        //flash (rx) : ORIGIN = 0x00010000, LENGTH = 0x00040000 
        //ram  (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000 
    
    }

    and my application with:

    MEMORY 
    {
        //flash (rx) : ORIGIN = 0x00000000, LENGTH = 0x00100000 
        //ram  (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000 
        flash (rx) : ORIGIN = 0x00010000, LENGTH = 0x00040000 
        ram  (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000 
    
    }

    ? Or should I modify something else ?

    As regards the defines you mention to put at the beginning of my app:

    (Don't forget the app's RAM addresses declarations also in the main app's code)

    #define APP_BASE 0x00010000 (I put my main_app_1 there)
    #define APP_LENG 0x00040000 (length of my main app + margins)
    #define RAM_BASE 0x20000000
    #define RAM_LENG 0x00040000

    I have seen no change in the output binary file (I compared them with a specific program) whether I include the above mentioned defines at the beginning of my app or not. The output file without the 4 defines is identical to the related output file with the 4 defines. Of course if I try to compile my app with:

    MEMORY 
    {
        flash (rx) : ORIGIN = 0x00000000, LENGTH = 0x00100000 
        ram  (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000 
        //flash (rx) : ORIGIN = 0x00010000, LENGTH = 0x00040000 
        //ram  (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000 
    
    }

    the output binary file is different than if I compile my app with:

    MEMORY 
    {
        //flash (rx) : ORIGIN = 0x00000000, LENGTH = 0x00100000 
        //ram  (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000 
        flash (rx) : ORIGIN = 0x00010000, LENGTH = 0x00040000 
        ram  (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000 
    
    }

    but it is not sensitive to the defines at the beginning.

    Thanks for your help,

    Simone

  • Hello Simone,

    The snowflake file is handled as it should and you're o.k. there. But in the main app the definitions

    #define APP_BASE 0x00010000 
    #define APP_LENG 0x00040000 
    #define RAM_BASE 0x20000000
    #define RAM_LENG 0x00040000

    it is obligatory to be like above and must be included in the source.

    I would suggest before any new attempts, to code a small bin and just go and zero all EEPROM locations, or at least those that you use.
    It is sometimes the case that during testing periods we set some EEPROM or flash addresses with a specific values and we forget to
    clean them after a crash or unwanted reboot. So our app then may toggle them to states that we don't expect or test them without any
    success in finding what it would expect.

    Regards,
    John
  • Hi John, I'm not sure if I understood your point, but:

    1) before flashing the bootloader on the board I ALWAYS flash and execute a small program that cleans (i.e. sets to 0xff) all EEPROM locations, then sets the GATEWAY, MAC, IP, PORT locations with the required values for my LAN
    2) in any case my will is that after firmware transfer on Flash the bootloader performs a JUMP to the app, regardless the EEPROM location value (i.e. without writing and checking the EEPROM BOOTLOADING location), so once the firmware upload on flash is completed, the EEPROM value should be not meaningful, isn't it?

    thanks
    Simone
  • Hi Simone,
    Can you please explain what is the purpose of the #if 0 and 1 checks? Later I'll post the latest bootloader firmware.
    John
  • Hi,
    just to include in the compilation my modification (#if 1), i.e. direct jump to application, instead of your initial implementation (#if 0), i.e. writing of BOOTLOADING location and board restart caused by WatchDog expiration.
  • I can't really understand what's happening with my board. I tried to re-flash John's original bootloader, and then the upload a simple app doed not succeed.

    I performed these steps:

    1) flashed on the board a simple app that clears (0xff) the entire EEPROM, then sets GATEWAY, IP, PORT, SUBNET --> it executes correctly

    2) flashed with LM Flash Programmer John's original binary tcp_bootloader.bin on the board at address 0x0. The operation completes succesfully. The CRC32 matches between device and Source ( 0xA233A7B4 )

    3) compiled the Energia Blink example with the following setup in the snowflake.ld file:

    MEMORY 
    {
        //flash (rx) : ORIGIN = 0x00000000, LENGTH = 0x00100000
        flash (rx) : ORIGIN = 0x00010000, LENGTH = 0x00040000 
        ram  (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000 
    
    }

    with also the following defines at the beginning of source:

    #define APP_BASE 0x00010000 
    #define APP_LENG 0x00040000 
    #define RAM_BASE 0x20000000
    #define RAM_LENG 0x00040000

    although their presence or absence does not modify the generated binary file.

    4) used the SendFiles.exe application to load the Blink.cpp.bin on the board. The download is apparently succesful:

    TCP Server Listener Started. Waiting for new firmware....
    External reset
    *****************************************************************
    *****************************************************************
    System Clock Frequency has been set to: 120000000
    System WATCHDOG Reboot Time is set to : 6 seconds.
    *****************************************************************
    *****************************************************************
    
    
    
    Flash memory from 0x10000 up to 0x000FA000 is now erased.
    
    Waiting for new firmware update................
    2428
    File Size: 2428   ***   1 parts of 2048 bytes each.   ***   Bytes of Last-Part: 380
    
    ~~~~~~~~~~~~~~~~2428ffff!!!!ffff!!!!
    
    
    Entering Receiving mode...
    65536    >< 0 >*< 2048 bytes block transfered...........Block No. 1
    67584    >< 0 >*< 2048 bytes block transfered...........Block No. 2
     END 380 bytes of Final-Block transfered.............. 
    
    >>>>>>>>>>>>>   IoT module will now REBOOT in main_application in 6 seconds   <<<<<<<<<<<<<
    

    But the board resets but the blink example does not run:

    I am the <boot-app> and I'm now passing control to the main_app_1 in 3 seconds.....
    
    
    
    

    (it gets stucked at this point)

    So, as a verification, with LM flash programmer I read Flash content from address 0x10000 to 0x50000 and compared the resulting binary file with the Blink.cpp.bin. It seems that the last block (starting at offset 0x800) has not correctly been stored into the flash. See the attached file for compare between the two binaries. I performed different attempts with the same file and the result is identical. Then performed an attempt with a larger file, which has a different number of blocks. Also in that case all blocks match between original file and flash content, except for the last block.

    What's going on? 

    thanks for help

    Simone

    BlinkCompare.html

  • Hello Simone, 

    As I can see from the messages printed, at the beginning, the bootloader's firmware computes 1 part of 2048 bytes 

    and 380 bytes as the last part. Then, at the log of the uploading, bootloader displays transfers of 2 parts of 2048 bytes 

    each and 380 as the last part. Obviously, an accidental modification inside the code leads to the faulty behavior. 

    How many bytes in total is the blink binary eventually? 

    John

  • It is 2428 bytes. I did flash your Bin, as extracted from the compressed folder. No modification. Moreover, the print messages seem compliant to source code: write_flash() function is called at each block (even last one) and each time it prints the message "2048 bytes block transfered..........." (the part exceeding 380 bytes in the last block is filled with '\0' before writing on flash). So, no surprise it prints twice the message.

    In the content read from flash, the zeros from 0x97C to 0xFFF (zero filling of unused 1668 bytes of last block) are correctly present. The only thing that is not coherent are the first 380 bytes: they are not as expected from the original binary file. In particular, they are the repetition of the first 380 bytes of the secondlast block.

    thank you

    Simone

  • I can't tell the reason why, but to make your bootloader work again I had to introduce a small delay:
    delay(500);
    just after the:
    bl_localClient.write('$');

    It seems that the transfer of last block on the network did not occur, so the first last_part (380) bytes of input_buffer kept the previous value (this justifies why in the binary retrieved from flash such bytes were identical to the second-last block).

    With the delay it works fine and the content of flash from address 0x10000 matches perfectly with the binary generated and uploaded.
    However, the initial modification I had in mind (inhibition of the writing of BOOTLOADING location, and direct jump to the application initial address) does not work. I will try to understand what I am doing wrong. Any help would be appreciated.
    You told that a new release of bootloader is available: I'd be very thankful if you could share it, to see what's new in the implementation.

    Thanks for your help and patience.
    Simone

  • Hello Simone.

    Following is the link of my latest bootloader's firmware for TM4C1294NCPDT chip: https://www.dropbox.com/s/hjpl1qgt2irqfnk/jopil_Bootloader.ino?dl=0  I'll try to keep this link   "permanent" for as long as my dropbox's usage allows. The C# application source is not included any more since it is now part of a larger namespace which contains many protected commercial parts of source. However, the logic of the initial C# firmware-update application is 99% identical and you can still refer to it.

    Also remember that when you erase flash, the address locations are filled with 0xff and not 0x00, so your check in the bootloader should be for 0xff from inside my bootloader's source.

    All the best,

    John

  • John, thank you very much for uploading the new firmware.

    When you say "Also remember that when you erase flash, the address locations are filled with 0xff and not 0x00, so your check in the bootloader should be for 0xff from inside my bootloader's source.", which check are you referring to?

    Simone

  • The initial check in the setup section, where it is decided if a direct jump to the app's space will happen or a firmware update waiting loop will follow. John
  • ok, so are you referring to erase of EEPROM ? (not flash)
  • Correct Simone, EEPROM I mean,
    John
  • Correct Simone. Did you try it?

    John

  • Hi John, unfortunately I do not have the board with me now, so I could not try your new bootloader. Moreover, I need also to modify the c# client to adequate It to the new bootloader, so It will take a little. Anyway I had a quick look at the code and liked very much the push button management and the "Dynamic" packet size management. Excellent idea!

    I was thinking about my initial idea of modification. Maybe the assembler instruction are correctly placed but something is not allowed: for example I think that if serial.begin is already called by bootloader then I cannot call It even in the setup function of my main application. Similarly for Ethernet.begin.

    I think this Can be the cause preventing my application  to work correctly when called from bootloader without board reset. Could It Be ?

    Thanks

    Simone

  • Hmmmm, I can't understand what might be the problem Simone. I can't think of something else that prevents your app from starting after firmware bootloading. My last guess would be to give a try and use UniFlash programmer instead of LM flash and see what happens.
    John
  • Hello Simone. Did you eventually solved the problem? All the best, John

  • Hello John and thanks for your interest.

    Unfortunately I had not time to test either your new bootloader, or to flash with uniflash the one I modified to jump directly to application after firmware download. I will give a try in the weekend, in the following order:

    1) first of all I will try to remove the delay I had to introduce in the old bootloader, to see if it works again as it did excellently in the past. In this phase i will exclude my modification for direct jump

    2) try to introduce the direct jump to application after remote firmware download, and flash the modified bootloader with uniflash (as you suggested) to see if it makes any difference respect to LM Flash Programmer

    3) I will try your new bootloader. Unfortunately I will keep this as last attempt as I have to modify the TCP Client App, and I am not very familiar with string manipulation in C#

    4) if step 2 is succesful, I will try to modify your new bootloader to introduce the modification for direct jump

    Point 1 is the biggest concern: I don't understand why at some point your original bootloader did not correctly store the last data block, and I had to introduce the delay. Do you have any idea ? I don't see any error in your old bootloader. Only difference in the new one is elimination of out_buffer[i] which was filled but not used, but I would not consider it an error, just some unused code.

    Best regards

    Simone

  • Hi John,

    I tried the steps above.

    1) unfortunately your original bootloader does not work anymore for me. I have to keep the delay just after the bl_localClient.write('$'); to make it work. Maybe it's due to some delay in my network, even if I tried it with ethernet connection (no WiFi, no WAN)

    2) I couldn't flash the bootloader with Uniflash. The following error occurred:

    [09:56:25] Start operations on multiple programs on the target core...
    [09:56:26] Loading program: C:\Dati\Download\Elettronica\TM4C\Bootloader\tcp_bootloader\BOOTLOADER_CCS7_Projects\tcp_bootloader\Release\tcp_bootloader.bin
    [09:56:26] ERROR >> Tiva_LM_device: GEL: Encountered a problem loading file: C:\Dati\Download\Elettronica\TM4C\Bootloader\tcp_bootloader\BOOTLOADER_CCS7_Projects\tcp_bootloader\Release\tcp_bootloader.bin Could not determine target type of file

    [09:56:26] Encountered a problem loading file: C:\Dati\Download\Elettronica\TM4C\Bootloader\tcp_bootloader\BOOTLOADER_CCS7_Projects\tcp_bootloader\Release\tcp_bootloader.bin
    Could not determine target type of file
    [09:56:26] Programs operation finished.

    II used Uniflash 3.4.

    3) modified the C# client app in order to try your new bootloader. This also works only if I put a delay just after the bl_localClient.write('$'). But at least I managed to modify the client to adapt it to your new BL, so I'm quite satisfied.

    4) skipped point 4 since I had no success at task #2

    In conclusion:

    a) maybe it's just a problem of my personal network, but to make both your bootloaders work a small delay is needed between one block and another,

    b) could not find a solution to jump to main app after firmware upload, without the need to reset the board.

    Thanks for your support.

    Simone