I am making an ethernet application using the lwip library with "Hercules TMS570LS31x/21x Development Kit".
If I give a static IP, I can get IP, I did not encounter any problems.
But if I want it to get an IP via DHCP, it rarely succeeds.
And I haven't seen it succeed in LocatorConfig either.
lwip library version: 1.4.1
downloaded the library from here: http://git.ti.com/hercules_examples/hercules_examples/trees/master/Application/LwIP
I did tests for a long time, but I could not identify the source of the problem, do you have any advice for me?
Thanks for your help.
The code I use is as follows.
sys_main.c
uint8 emacAddress[6U] = { 0x00U, 0x08U, 0xEEU, 0x03U, 0xA6U, 0x6CU }; uint32 emacPhyAddress = 1U; int main(void) { /* USER CODE BEGIN (3) */ EMAC_LwIP_Init(); EMAC_LwIP_Main(emacAddress); while (1) { } /* USER CODE END */ return 0; }
lwip_functions.c
void EMAC_LwIP_Init(void) { sciInit(); /* Enable the interrupt generation in CPSR register */ IntMasterIRQEnable(); _enable_FIQ(); } uint8_t EMAC_LwIP_Main(uint8_t *macAddress) { unsigned int ipAddr; struct in_addr devIPAddress; /* Initialze the lwIP library, using DHCP.*/ ipAddr = lwIPInit(0, macAddress, 0, 0, 0, IPADDR_USE_DHCP); if (0 == ipAddr) { sciDisplayText(sciREGx, txtCRLF, sizeof(txtCRLF)); sciDisplayText(sciREGx, txtCRLF, sizeof(txtCRLF)); sciDisplayText(sciREGx, txtErrorInit, sizeof(txtErrorInit)); sciDisplayText(sciREGx, txtCRLF, sizeof(txtCRLF)); sciDisplayText(sciREGx, txtCRLF, sizeof(txtCRLF)); return 0; } else { /* Convert IP Address to string */ devIPAddress.s_addr = ipAddr; txtIPAddrItoA = (uint8_t*) inet_ntoa(devIPAddress); LocatorConfig(macAddress, "LaunchPad enet_lwip"); sciDisplayText(sciREGx, txtCRLF, sizeof(txtCRLF)); sciDisplayText(sciREGx, txtCRLF, sizeof(txtCRLF)); sciDisplayText(sciREGx, txtIPAddrTxt, sizeof(txtIPAddrTxt)); sciDisplayText(sciREGx, txtIPAddrItoA, 16); sciDisplayText(sciREGx, txtCRLF, sizeof(txtCRLF)); return 1; } }
lwiplib.c/** * * \brief Initializes the lwIP TCP/IP stack. * * \param instNum The instance index of the EMAC module * \param macArray Pointer to the MAC Address * \param ipAddr The IP address to be used * \param netMask The network mask to be used * \param gwAddr The Gateway address to be used * \param ipMode The IP Address Mode. * ipMode can take the following values\n * IPADDR_USE_STATIC - force static IP addressing to be used \n * IPADDR_USE_DHCP - force DHCP with fallback to Link Local \n * IPADDR_USE_AUTOIP - force Link Local only * * This function performs initialization of the lwIP TCP/IP stack for the * HDK EMAC, including DHCP and/or AutoIP, as configured. * * \return IP Address. */ unsigned int lwIPInit(unsigned int instNum, unsigned char *macArray, unsigned int ipAddr, unsigned int netMask, unsigned int gwAddr, unsigned int ipMode) { struct ip_addr ip_addr; struct ip_addr net_mask; struct ip_addr gw_addr; volatile unsigned char *state = NULL; unsigned int *ipAddrPtr; volatile unsigned int cnt = 0x3FFFFFFF; lwip_init(); /* Setup the network address values. */ if (ipMode == IPADDR_USE_STATIC) { ip_addr.addr = htonl(ipAddr); net_mask.addr = htonl(netMask); gw_addr.addr = htonl(gwAddr); } else { ip_addr.addr = 0; net_mask.addr = 0; gw_addr.addr = 0; } hdkif_macaddrset(instNum, macArray); /* ** Create, configure and add the Ethernet controller interface with ** default settings. ip_input should be used to send packets directly to ** the stack. The lwIP will internaly call the hdkif_init function. */ if (NULL == netif_add(&hdkNetIF[instNum], &ip_addr, &net_mask, &gw_addr, &instNum, hdkif_init, ip_input)) { return 0; }; netif_set_default(&hdkNetIF[instNum]); /* Start DHCP, if enabled. */ #if LWIP_DHCP if (ipMode == IPADDR_USE_DHCP) { unsigned int dhcp_flag = 0; unsigned int dhcp_tries = 5; unsigned int count; unsigned int delay; while (dhcp_tries--) { dhcp_start(&hdkNetIF[instNum]); count = 10; /* Check for DHCP completion for 'count' number of times, each for the given delay. */ while (state == 0) { delay = 0x8FFFFFFU; while (delay--) ; state = &(hdkNetIF[instNum].dhcp->state); uint8_t buf[20]; sprintf(buf, "State: %d\n\r", *state); sciDisplayText(sciREGx, &buf[0], strlen(buf)); if (DHCP_BOUND == *state) { dhcp_flag = 1; ipAddrPtr = (unsigned int*) &(hdkNetIF[instNum].ip_addr); return (*ipAddrPtr); } } } /* In case of DHCP failure, return 0. */ if (dhcp_flag == 0) return 0; } #endif /* Start AutoIP, if enabled and DHCP is not. */ #if LWIP_AUTOIP if(ipMode == IPADDR_USE_AUTOIP) { autoip_start(&hdkNetIF[instNum]); } #endif if ((ipMode == IPADDR_USE_STATIC) || (ipMode == IPADDR_USE_AUTOIP)) { /* Bring the interface up */ netif_set_up(&hdkNetIF[instNum]); } ipAddrPtr = (unsigned int*) &(hdkNetIF[instNum].ip_addr); return (*ipAddrPtr); }
locator.c/* ** This function is called by the lwIP TCP/IP stack when it receives a UDP ** packet from the discovery port. It produces the response packet, which is ** sent back to the querying client. */ static void LocatorReceive(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port) { unsigned char *pucData; unsigned long ulIdx; /* Validate the contents of the datagram.*/ pucData = p->payload; if((p->len != 4) || (pucData[0] != TAG_CMD) || (pucData[1] != 4) || (pucData[2] != CMD_DISCOVER_TARGET) || (pucData[3] != ((0 - TAG_CMD - 4 - CMD_DISCOVER_TARGET) & 0xff))) { pbuf_free(p); return; } pbuf_free(p); p = pbuf_alloc(PBUF_TRANSPORT, sizeof(locatorData), PBUF_RAM); if(p == NULL) { return; } /* Calcuate and fill in the checksum on the response packet.*/ for(ulIdx = 0, locatorData[sizeof(locatorData) - 1] = 0; ulIdx < (sizeof(locatorData) - 1); ulIdx++) { locatorData[sizeof(locatorData) - 1] -= locatorData[ulIdx]; } /* Copy the response packet data into the pbuf. */ pucData = p->payload; for(ulIdx = 0; ulIdx < sizeof(locatorData); ulIdx++) { pucData[ulIdx] = locatorData[ulIdx]; } /* Send the response.*/ udp_sendto(pcb, p, addr, port); pbuf_free(p); } /* ** Initializes the locator service. Prepares the locator service to ** handle device discovery requests. . */ void LocatorConfig(unsigned char *macArray, const char *appTitle) { unsigned int idx; void *pcb; /* Clear out the response data.*/ for(idx = 0; idx < 84; idx++) { locatorData[idx] = 0; } /* Fill in the header for the response data.*/ locatorData[0] = TAG_STATUS; locatorData[1] = sizeof(locatorData); locatorData[2] = CMD_DISCOVER_TARGET; /* Fill in the MAC address for the response data. */ locatorData[9] = macArray[0]; locatorData[10] = macArray[1]; locatorData[11] = macArray[2]; locatorData[12] = macArray[3]; locatorData[13] = macArray[4]; locatorData[14] = macArray[5]; /* Create a new UDP port for listening to device locator requests.*/ pcb = udp_new(); udp_recv(pcb, LocatorReceive, NULL); udp_bind(pcb, IP_ADDR_ANY, 23); udp_connect(pcb, IP_ADDR_ANY, 23); /* Copy the application title string into the response data. */ for(idx = 0; (idx < 64) && *appTitle; idx++) { locatorData[idx + 19] = *appTitle++; } /* Zero-fill the remainder of the space in the response data (if any).*/ for(; idx < 64; idx++) { locatorData[idx + 19] = 0; } }