cancel
Showing results for 
Search instead for 
Did you mean: 

How to change the IP Address at runtime

VSomasekhar
Associate II

This is my Environment:
Microcontroller: STM32H723ZET6
LWIP is used. No RTOS used.
I am setting a Static IP address in the *.ioc file. I am setting the same IP address in the TCP Raw Socket Echo Server to Bind the socket. Over that I am running the Modbus Server. DHCP is disabled. 
I want to change the IP Address at run-time. How is it possible?

9 REPLIES 9
Andrew Neil
Evangelist III

@VSomasekhar wrote:

I want to change the IP Address at run-time. How is it possible?


Use DHCP.

Provide an interface so that the user can provide the (static) IP address.

ASEHST
ST Employee

Hello,

To change the IP address, please try disabling the network interface. Next, use netif_set_addr to set the new IP address, subnet mask, and gateway. Finally, re-enable the interface to apply the new configurations.

 

With Regards,

If your question is answered, please close this topic by clicking "Accept as Solution".

Thanks for the reply. I've tried it but found that it was not working out. I've used Modbus to send the new IP address from the client machine to the server board. Then I'm calling the relevant functions as suggested. I've confirmed that the new IP is set in the LWIP stack, by using the ST-LINK/V2 debugger. But the TCP/IP Raw socket server, which is the front end of the Modbus server is already set to the earlier IP address. I've done changes to it also, by making the IP Address global and tried to set it in the TCP Raw Socket server also, using this function call:

IP_ADDR4(&myIPADDR, new_ipaddr[0], new_ipaddr[1], new_ipaddr[2], new_ipaddr[3]);

Even this was not working out, most likely due to the "tpcb" knows only the previous IP Address. If I call the TCP server initialization again, it is disconnecting, freeing up the earlier "tpcb" and not preceding further. I've also tried with using a new "gnetif" and also the existing one. Either way it didn't work. I've copied the described functions below, please help.

/********** function for runtime ip address change start***********/

void LwIP-change-ip-cfg(uint8_t* ip_addr_array)

{

extern struct netif gnetif;

ip4_addr_t ipaddr;

ip4_addr_t netmask;

ip4_addr_t gw;

uint8_t IP_ADDRESS[4];

uint8_t NETMASK_ADDRESS[4];

uint8_t GATEWAY_ADDRESS[4];



IP_ADDRESS[0] = ip_addr_array[0];

IP_ADDRESS[1] = ip_addr_array[1];

IP_ADDRESS[2] = ip_addr_array[2];

IP_ADDRESS[3] = ip_addr_array[3];

NETMASK_ADDRESS[0] = 255;

NETMASK_ADDRESS[1] = 255;

NETMASK_ADDRESS[2] = 255;

NETMASK_ADDRESS[3] = 0;

GATEWAY_ADDRESS[0] = IP_ADDRESS[0]; //192;

GATEWAY_ADDRESS[1] = IP_ADDRESS[1]; //168;

GATEWAY_ADDRESS[2] = IP_ADDRESS[2]; //1;

GATEWAY_ADDRESS[3] = 1;



#ifdef USE_DHCP

ipaddr.addr = 0;

netmask.addr = 0;

gw.addr = 0;

#else

netif_set_down(&gnetif);

IP4_ADDR(&ipaddr, IP_ADDRESS[0], IP_ADDRESS[1], IP_ADDRESS[2], IP_ADDRESS[3]);

IP4_ADDR(&netmask, NETMASK_ADDRESS[0], NETMASK_ADDRESS[1] , NETMASK_ADDRESS[2], NETMASK_ADDRESS[3]);

IP4_ADDR(&gw, GATEWAY_ADDRESS[0], GATEWAY_ADDRESS[1], GATEWAY_ADDRESS[2], GATEWAY_ADDRESS[3]);

#endif



// add the network interface (IPv4/IPv6) without RTOS

//netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &ethernet_input);

// Set the new address parameters.

netif_set_addr(&gnetif, &ipaddr, &netmask, &gw);

// Registers the default network interface

netif_set_default(&gnetif);

// When the netif is fully configured this function must be called.

netif_set_up(&gnetif);



uint32_t local_IP = gnetif.ip_addr.addr;

uint8_t ip1 = local_IP & 0xff;

uint8_t ip2 = (local_IP >> & 0xff;

uint8_t ip3 = (local_IP >> 16) & 0xff;

uint8_t ip4 = (local_IP >> 24);

}

/**********function for runtime ip address change end ********/



/*********tcp raw socket server initialization start*********/

void tcp-server-init(void)

{

struct tcp_pcb *tpcb;

ip_addr_t myIPADDR;

err_t err;



/* 1. create new tcp pcb */

tpcb = tcp_new();



/* 2. bind _pcb to port 7 ( protocol) */

//IP_ADDR4(&myIPADDR, new_ipaddr[0], new_ipaddr[1], new_ipaddr[2], new_ipaddr[3]);

IP_ADDR4(&myIPADDR, 192, 168, 1, 70);

err = tcp_bind(tpcb, &myIPADDR, 502);



if (err == ERR_OK)

{

/* 3. start tcp listening for _pcb */

tpcb = tcp_listen(tpcb);



/* 4. initialize LwIP tcp_accept callback function */

tcp_accept(tpcb, tcp_server_accept);

}

else

{

/* deallocate the pcb */

memp_free(MEMP_TCP_PCB, tpcb);

}

}

/*********tcp raw socket server initialization end*********/
Pavel A.
Evangelist III

@VSomasekhar your code (as in the posted fragment) cannot compile. Are you sure that described changes are compiled and run on the target?

 

VSomasekhar
Associate II

I am using STM32CubeIDE and it has compiled and also running. I have used the debugger in the same IDE and have confirmed that the new IP has in fact been set in the LwIP_change_ip_cfg(..) function. I've replaced "_" with "-" for security reasons, due to which you've said that it can't compile. Please check the functionality / functional call sequence. It is more or less "Catch-22" situation, which I'm looking to circumvent. I know that small Microcontrollers won't have the facility to change the IP at runtime, but this is STM32H723ZET6, a comfortably high-end controller, which should have equivalent functionality of a Processor. I know that in the case of a Processor, changing IP Address is a routine task and the suggested method will surely work. In this Application, there is no OS/RTOS, but only LWIP is included. Hope this helps. 

 


@VSomasekhar wrote:

this is STM32H723ZET6, a comfortably high-end controller, which should have equivalent functionality of a Processor. 


But remember that the "Lw" in LwIP" stands for Light-weight - it's not intended to be a full-fat, all-singing, all-dancing stack...

VSomasekhar
Associate II

OK, in that case, I've to use a full featured TCP/IP stack. Could you please mention what I need to check for this purpose? Any option is available from STM32CubeIDE? Do I have to enable FreeRTOS in STM32CubeIDE, and disable LWIP?  

LwIP is full featured enough. The problem is at the application (modbus) level or somewhere else.

In LwIP change of interface IP address should work as @ASEHST wrote: close active connections, bring interface down, change the IP, bring interface up.