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.

TM4C1294NCPDT: ROM_UpdateEMAC() works but a quick question about it.

Part Number: TM4C1294NCPDT

On the Tiva, when doing a firmware update "DFU" over the network, I call the function ROM_UpdateEMAC() and it (the DFU) works as expected.  Before I call the function ROM_UpdateEMAC(), all the IRQ's are disabled etc.

HWREG(NVIC_DIS0) = 0xffffffff;
HWREG(NVIC_DIS1) = 0xffffffff;

HWREG(NVIC_DIS2) = 0xffffffff;
HWREG(NVIC_DIS3) = 0xffffffff;
HWREG(NVIC_DIS4) = 0xffffffff;
SysTickIntDisable();
SysTickDisable(); 

My question is not about getting the "DFU" to work but is there a timeout of about 12 seconds where if the download does not happen, the Tiva will just boot of the app it has in memory?  I do not recall this happening in the past where the will give up waiting on the TFTP server and just boot up.  The behavior I see would seem to imply there is a timeout where the CPU will reboot after about 12 seconds if the TFTP does not start.

I looked in the Tiva ROM user guide and found the function ROM_UpdateEMAC() documented but it did not mention any timeout.

Doug

  • My question is not about getting the "DFU" to work but is there a timeout of about 12 seconds where if the download does not happen, the Tiva will just boot of the app it has in memory?  I do not recall this happening in the past where the will give up waiting on the TFTP server and just boot up.  The behavior I see would seem to imply there is a timeout where the CPU will reboot after about 12 seconds if the TFTP does not start.

    Hi Doug,

      I think you want investigate why the BOOTP/TFTP server does not start after the client sends the BOOTP/TFTP request. As far as I can see for the flash-based Ethernet bootloader, it does have a timeout feature after 3 retries to get response from the TFTP server. Pleas see below snippet of code in bl_emac.c file. 

    #ifdef DOXYGEN
    char
    BOOTPThread(void)
    #else
    PT_THREAD(BOOTPThread(void))
    #endif
    {
    //
    // Begin the proto-thread.
    //
    PT_BEGIN(&g_sThread);

    wait_for_link:
    PT_WAIT_UNTIL(&g_sThread,
    (LOCAL_EMACPHYRead(EMAC0_BASE, 0, EPHY_BMSR) &
    EPHY_BMSR_LINKSTAT) != 0);

    //
    // Reset the host address.
    //
    *((uint32_t *)(void *)(&uip_hostaddr)) = 0;

    //
    // Re-bind the UDP socket for sending requests to the BOOTP server.
    //
    uip_udp_remove(g_pConn);
    *((uint32_t *)(void *)(&g_sServerAddr)) = 0xffffffff;
    uip_udp_new(&g_sServerAddr, HTONS(BOOTP_SERVER_PORT));
    uip_udp_bind(g_pConn, HTONS(BOOTP_CLIENT_PORT));

    //
    // Set the initial delay between BOOTP requests to 1 second.
    //
    g_ui32Delay = SYSTICKHZ;

    //
    // Loop forever. This loop is explicitly exited when a valid BOOTP reply
    // is received.
    //
    while(1)
    {
    //
    // Send a BOOTP request.
    //
    SendBOOTPRequest();

    //
    // Set the amount of time to wait for the BOOTP reply message.
    //
    g_ui32Target = g_ui32Ticks + g_ui32Delay;

    //
    // Wait until a packet is received or the timeout has occurred.
    //
    wait_for_bootp_reply:
    PT_WAIT_UNTIL(&g_sThread,
    ((g_ui32Link = (LOCAL_EMACPHYRead(EMAC0_BASE, 0, EPHY_BMSR) &
    EPHY_BMSR_LINKSTAT)) == 0) ||
    uip_newdata() || (g_ui32Ticks > g_ui32Target));

    //
    // If the link has been lost, go back to waiting for a link.
    //
    if(g_ui32Link == 0)
    {
    goto wait_for_link;
    }

    //
    // See if a packet has been received.
    //
    if(uip_newdata())
    {
    //
    // Clear the new data flag so that this packet will only be
    // examined one time.
    //
    uip_flags &= ~(UIP_NEWDATA);

    //
    // See if this is a BOOTP reply.
    //
    if(ParseBOOTPReply() == 1)
    {
    break;
    }

    //
    // This was not a BOOTP reply packet, so go back to waiting.
    //
    goto wait_for_bootp_reply;
    }

    //
    // If the delay between BOOTP requests is less than 60 seconds, double
    // the delay time. This avoids constantly slamming the network with
    // requests.
    //
    if(g_ui32Delay < (60 * SYSTICKHZ))
    {
    g_ui32Delay *= 2;
    }
    }

    //
    // Reconfigure the UDP socket to target the TFTP port on the server.
    //
    uip_ipaddr_copy(&g_pConn->ripaddr, g_sServerAddr);
    uip_udp_bind(g_pConn, HTONS(13633));

    //
    // Send a TFTP read request.
    //
    SendTFTPGet();

    //
    // Since the first TFTP read request will result in an ARP request, delay
    // for just a bit and then re-issue the TFTP read request.
    //
    PT_YIELD(&g_sThread);

    //
    // Resend the TFTP read request. If the ARP request has already been
    // answered, this will go out as is and avoid the two second timeout below.
    //
    SendTFTPGet();

    //
    // Start the TFTP transfer from block one.
    //
    g_ui32TFTPBlock = 1;

    //
    // Set the number of TFTP retries to zero.
    //
    g_ui32TFTPRetries = 0;

    //
    // Loop forever. This loop is explicitly exited when the TFTP transfer has
    // completed.
    //
    while(1)
    {
    //
    // Set the amount of time to wait for the TFTP data packet.
    //
    g_ui32Target = g_ui32Ticks + (SYSTICKHZ * 4);

    //
    // Wait until a packet is received or the timeout has occurred.
    //
    PT_WAIT_UNTIL(&g_sThread,
    ((g_ui32Link = (LOCAL_EMACPHYRead(EMAC0_BASE, 0, EPHY_BMSR) &
    EPHY_BMSR_LINKSTAT)) == 0) ||
    uip_newdata() || (g_ui32Ticks > g_ui32Target));

    //
    // If the link has been lost, go back to waiting for a link.
    //
    if(g_ui32Link == 0)
    {
    goto wait_for_link;
    }

    //
    // See if a packet has been received.
    //
    if(uip_newdata())
    {
    //
    // Clear the new data flag so that this packet will only be
    // examined one time.
    //
    uip_flags &= ~(UIP_NEWDATA);

    //
    // See if this is a TFTP data packet.
    //
    if(ParseTFTPData() == 1)
    {
    break;
    }
    }
    else if(g_ui32TFTPRetries < 3)
    {
    //
    // The transfer timed out, so send a new TFTP read request.
    //
    SendTFTPGet();

    //
    // Start the TFTP transfer from block one.
    //
    g_ui32TFTPBlock = 1;

    //
    // Increment the count of TFTP retries.
    //
    g_ui32TFTPRetries++;
    }
    else
    {
    //
    // The TFTP transfer failed after three retries, so start over.
    //
    goto wait_for_link;
    }
    }
    //
    // Wait for the last packet to be transmitted.
    //
    while(g_psTxDescriptor[g_ui32TxDescIndex].ui32CtrlStatus &
    DES0_TX_CTRL_OWN)
    {
    }

    //
    // Wait for a bit to make sure that the final ACK packet is transmitted.
    //
    g_ui32Target = g_ui32Ticks + (SYSTICKHZ / 4);
    while(g_ui32Ticks < g_ui32Target)
    {
    PT_YIELD(&g_sThread);
    }

    //
    // Perform a software reset request. This will cause the microcontroller
    // to reset; no further code will be executed.
    //
    HWREG(NVIC_APINT) = NVIC_APINT_VECTKEY | NVIC_APINT_SYSRESETREQ;

    //
    // The microcontroller should have reset, so this should never be reached.
    // Just in case, loop forever.
    //
    while(1)
    {
    }

    //
    // End the proto-thread.
    //
    PT_END(&g_sThread);
    }