Hi,
Greetings of the day!
I am new to TIVA C controller, now am working on TCP/IP echo client program, I got a document from TI here,(www.ti.com/.../spna248) I just followed the steps , server program works properly, but the problem begins with client program. In tcp_echo_client code, program get halt at this line while (g_bIPAddrValid == 0);
I just connected my board and computer with the LAN port of my office network, and I mentioned server IP address as my computers IP (i.e) #define SERVER_IPADDR "192.168.70.106" , for your reference I have attached the screenshots and the code below.
//***************************************************************************** // // enet_tcpecho_client_lwip.c - Sample Echo Client Application using lwIP. // // Copyright (c) 2019-2020 Texas Instruments Incorporated. All rights reserved. // Software License Agreement // // Texas Instruments (TI) is supplying this software for use solely and // exclusively on TI's microcontroller products. The software is owned by // TI and/or its suppliers, and is protected under applicable copyright // laws. You may not combine this software with "viral" open-source // software in order to form a larger program. // // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL // DAMAGES, FOR ANY REASON WHATSOEVER. // // //***************************************************************************** #include <stdbool.h> #include <stdint.h> #include <string.h> #include <stdio.h> #include "inc/hw_ints.h" #include "inc/hw_memmap.h" #include "inc/hw_emac.h" #include "driverlib/flash.h" #include "driverlib/interrupt.h" #include "driverlib/gpio.h" #include "driverlib/rom_map.h" #include "driverlib/sysctl.h" #include "driverlib/systick.h" #include "drivers/pinout.h" #include "utils/locator.h" #include "utils/lwiplib.h" #include "utils/ustdlib.h" #include "utils/uartstdio.h" #include "lwip/debug.h" #include "lwip/stats.h" #include "lwip/tcp.h" #include "lwip/inet.h" //***************************************************************************** // //! \addtogroup example_list //! <h1>Ethernet TCP Echo Client (enet_tcpecho_client_lwip)</h1> //! //! This example application demonstrates the TM4C129x Ethernet Controller //! operating as a client on the network using the lwIP TCP/IP Stack. The //! processor will send a hello greeting message to the server after it //! establishes a connection with the server. It will then echo back whatever //! the server sends to it. The DHCP is used to obtain an Ethernet address. //! If DHCP times out without obtaining an address, AutoIP will be used to //! obtain a link-local address. The address that is selected will be shown //! on the UART. //! //! UART0, connected to the Virtual Serial Port and running at 115,200, 8-N-1, //! is used to display messages from this application. //! //! For additional details on lwIP, refer to the lwIP web page at: //! http://savannah.nongnu.org/projects/lwip/ // //***************************************************************************** //***************************************************************************** // // Defines for the server IP address and PORT numbers. // // TODO: User must change these settings per their application. // //***************************************************************************** #define SERVER_IPADDR "192.168.70.106" #define SERVER_PORT 23 //***************************************************************************** // // Defines for setting up the system clock. // //***************************************************************************** #define SYSTICKHZ 100 #define SYSTICKMS (1000 / SYSTICKHZ) //***************************************************************************** // // Interrupt priority definitions. The top 3 bits of these values are // significant with lower values indicating higher priority interrupts. // //***************************************************************************** #define SYSTICK_INT_PRIORITY 0x80 #define ETHERNET_INT_PRIORITY 0xC0 //***************************************************************************** // // The variable g_ui32SysClock contains the system clock frequency in Hz. // //***************************************************************************** uint32_t g_ui32SysClock; //***************************************************************************** // // The current IP address. // //***************************************************************************** uint32_t g_ui32IPAddress; //***************************************************************************** // // Global counter to keep track the duration the connection has been idle. // //***************************************************************************** uint32_t g_ui32tcpPollTick = 0; //***************************************************************************** // // Volatile global flag to manage LED blinking, since it is used in interrupt // and main application. The LED blinks at the rate of SYSTICKHZ. // //***************************************************************************** volatile bool g_bLED; //***************************************************************************** // // Global flag indicating when the IP address is acquired // //***************************************************************************** bool g_bIPAddrValid = 0; //***************************************************************************** // // Global flag indicating when the client connects to the server // //***************************************************************************** bool g_bconnect = 0; //***************************************************************************** // // Global LwIP PCB structure and error variables. // //***************************************************************************** err_t err; static struct tcp_pcb *tpcb; //***************************************************************************** // // The error routine that is called if the driver library encounters an error. // //***************************************************************************** #ifdef DEBUG void __error__(char *pcFilename, uint32_t ui32Line) { } #endif #define UART_DEBUG_OUT 1 //***************************************************************************** // // Display an lwIP type IP Address. // //***************************************************************************** void DisplayIPAddress(uint32_t ui32Addr) { char pcBuf[16]; // Convert the IP Address into a string. usprintf(pcBuf, "%d.%d.%d.%d", ui32Addr & 0xff, (ui32Addr >> 8) & 0xff, (ui32Addr >> 16) & 0xff, (ui32Addr >> 24) & 0xff); UARTprintf(pcBuf); } //***************************************************************************** // // Required by lwIP library to support any host-related timer functions. // //***************************************************************************** void lwIPHostTimerHandler(void) { uint32_t ui32NewIPAddress; // // Get the current IP address. // ui32NewIPAddress = lwIPLocalIPAddrGet(); // // See if the IP address has changed. // if(ui32NewIPAddress != g_ui32IPAddress) { // // See if there is an IP address assigned. // if(ui32NewIPAddress == 0xffffffff) { // // Indicate that there is no link. // UARTprintf("Waiting for link.\n"); } else if(ui32NewIPAddress == 0) { // // There is no IP address, so indicate that the DHCP process is // running. // UARTprintf("Waiting for IP address.\n"); } else { g_bIPAddrValid = 1; // // Display the new IP address. // UARTprintf("IP Address: "); DisplayIPAddress(ui32NewIPAddress); } // // Save the new IP address. // g_ui32IPAddress = ui32NewIPAddress; } // // If there is not an IP address. // if((ui32NewIPAddress == 0) || (ui32NewIPAddress == 0xffffffff)) { // // Do nothing and keep waiting. // } } //***************************************************************************** // // The interrupt handler for the SysTick interrupt. // //***************************************************************************** void SysTickIntHandler(void) { // // Call the lwIP timer handler. // lwIPTimer(SYSTICKMS); // // Tell the application to change the state of the LED (in other words // blink). // g_bLED = true; } //***************************************************************************** // // The EchoReceive is a callback function when payload is received from the // remote host // //***************************************************************************** err_t EchoReceive(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) { int len; char *header = "Client: "; int header_len = strlen(header); char mydata[1024]; // // Check for null pointer. // if (p == NULL) { // // If null pointer has been passed in, close the connection. // UARTprintf("The remote host closed the connection.\n"); tcp_close(tpcb); return ERR_ABRT; } else { tcp_recved(tpcb, p->tot_len); #if UART_DEBUG_OUT UARTprintf("Receive %d bytes from the remote host.\n", p->tot_len); #endif // // Determine the size of the payload. // len = p->tot_len + header_len; strcpy(mydata, header); strcat(mydata, (char *)p->payload); // // Free the packet buffer. // pbuf_free(p); // // Check output buffer capacity. // if (len > tcp_sndbuf(tpcb)) len= tcp_sndbuf(tpcb); // // Queue the data to transmit. // err = tcp_write(tpcb, mydata, len, 0); if (err == ERR_OK) { #if UART_DEBUG_OUT UARTprintf("Echo the data out\n"); #endif } else if(err == ERR_MEM) { // // We are low on memory, try later, defer to poll. // UARTprintf("Low on memory.\n"); } else { // // Other problems to take care of. // UARTprintf("Other problems.\n"); } // // No need for a callback when transmitting. // tcp_sent(tpcb, NULL); } return ERR_OK; } //***************************************************************************** // // Function to send TCP packets to the server // //***************************************************************************** uint32_t TcpSendPacket(char *string) { // // Queues the data pointed to by string. // err = tcp_write(tpcb, string, strlen(string), TCP_WRITE_FLAG_COPY); if (err) { UARTprintf("ERROR: Code: %d (TcpSendPacket :: tcp_write)\n", err); return 1; } // // Transmit the data. // err = tcp_output(tpcb); // // Report any error that occurs. // if (err) { UARTprintf("ERROR: Code: %d (TcpSendPacket :: tcp_output)\n", err); return 1; } return 0; } //***************************************************************************** // // Callback function when the client establishes a successful connection to // the remote host. // //***************************************************************************** err_t ConnectCallback(void *arg, struct tcp_pcb *tpcb, err_t err) { char *string = "Hello World! \n\r "; if (err == ERR_OK){ #if UART_DEBUG_OUT UARTprintf("Connection Established.\n"); #endif g_bconnect = true; // // Register the callback function EchoReceive when // receiving data // tcp_recv(tpcb, EchoReceive); tcp_sent(tpcb, NULL); #if UART_DEBUG_OUT UARTprintf("Sending a greeting message to the Server\n"); #endif TcpSendPacket(string); return 0; } else { UARTprintf("No Connection Established.\n"); return 1; } } //***************************************************************************** // // Function to create a LwIP client. // //***************************************************************************** void EchoClientInit(void) { // // Create IP address structure. // struct ip_addr server_addr; // // Create a new TCP control block. // tpcb = tcp_new(); if (tpcb != NULL) { // // Assign destination server IP address. // server_addr.addr = inet_addr(SERVER_IPADDR); // // Configure destination IP address and port. // err = tcp_connect(tpcb, &server_addr, SERVER_PORT, ConnectCallback); if (err) { UARTprintf("ERROR: Code: %d (tcp_connect)\n", err); } UARTprintf("\nPCB CREATED\n"); } else { memp_free(MEMP_TCP_PCB, tpcb); UARTprintf("PCB NOT CREATED\n"); } } //***************************************************************************** // // This example demonstrates the use of the Ethernet Controller. // //***************************************************************************** int main(void) { uint32_t ui32User0, ui32User1; uint8_t pui8MACArray[8]; // // Make sure the main oscillator is enabled because this is required by // the PHY. The system must have a 25MHz crystal attached to the OSC // pins. The SYSCTL_MOSC_HIGHFREQ parameter is used when the crystal // frequency is 10MHz or higher. // SysCtlMOSCConfigSet(SYSCTL_MOSC_HIGHFREQ); // // Run from the PLL at 120 MHz. // Note: SYSCTL_CFG_VCO_240 is a new setting provided in TivaWare 2.2.x and // later to better reflect the actual VCO speed due to SYSCTL#22. // g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000); // // Configure the device pins. // PinoutSet(true, false); // // Configure UART. // UARTStdioConfig(0, 115200, g_ui32SysClock); // // Clear the terminal and print banner. // UARTprintf("\033[2J\033[H"); UARTprintf("Ethernet lwIP TCP echo client example\n\n"); // // Configure Port N1 for as an output for the animation LED. // MAP_GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_1); // // Initialize LED to OFF (0) // MAP_GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, ~GPIO_PIN_1); // // Configure SysTick for a periodic interrupt. // MAP_SysTickPeriodSet(g_ui32SysClock / SYSTICKHZ); MAP_SysTickEnable(); MAP_SysTickIntEnable(); // // Configure the hardware MAC address for Ethernet Controller filtering of // incoming packets. The MAC address will be stored in the non-volatile // USER0 and USER1 registers. // MAP_FlashUserGet(&ui32User0, &ui32User1); if((ui32User0 == 0xffffffff) || (ui32User1 == 0xffffffff)) { // // We should never get here. This is an error if the MAC address has // not been programmed into the device. Exit the program. // Let the user know there is no MAC address // UARTprintf("No MAC programmed!\n"); while(1) { } } // // Tell the user what we are doing just now. // UARTprintf("Waiting for IP.\n"); // // Convert the 24/24 split MAC address from NV ram into a 32/16 split MAC // address needed to program the hardware registers, then program the MAC // address into the Ethernet Controller registers. // pui8MACArray[0] = ((ui32User0 >> 0) & 0xff); pui8MACArray[1] = ((ui32User0 >> 8) & 0xff); pui8MACArray[2] = ((ui32User0 >> 16) & 0xff); pui8MACArray[3] = ((ui32User1 >> 0) & 0xff); pui8MACArray[4] = ((ui32User1 >> 8) & 0xff); pui8MACArray[5] = ((ui32User1 >> 16) & 0xff); // // Initialize the lwIP library, using DHCP. // lwIPInit(g_ui32SysClock, pui8MACArray, 0, 0, 0, IPADDR_USE_DHCP); // // Wait here until a valid IP address is obtained before // starting the client connection to the server. // while (g_bIPAddrValid == 0); // // Initialize the client. // EchoClientInit(); // // Set the interrupt priorities. We set the SysTick interrupt to a higher // priority than the Ethernet interrupt to ensure that the file system // tick is processed if SysTick occurs while the Ethernet handler is being // processed. This is very likely since all the TCP/IP and HTTP work is // done in the context of the Ethernet interrupt. // MAP_IntPrioritySet(INT_EMAC0, ETHERNET_INT_PRIORITY); MAP_IntPrioritySet(FAULT_SYSTICK, SYSTICK_INT_PRIORITY); // // Loop forever, processing the LED blinking. All the work is done in // interrupt handlers. while(1) { while(g_bLED == false || g_bconnect == false) { } // // Clear the flag. // g_bLED = false; // // Toggle the LED. // MAP_GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, (MAP_GPIOPinRead(GPIO_PORTN_BASE, GPIO_PIN_1) ^ GPIO_PIN_1)); } }
Thanks & regards,
Aravinth K