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.
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);
}