Skip to main content
Associate
March 1, 2025
Solved

STM32F767 LwIP TCP Client

  • March 1, 2025
  • 4 replies
  • 2115 views

Hello,

I'm facing some weird problem that I can't solve myself. I'm trying to get to work a TCP client using LwIP.

Now the weird part:

Everything works just fine in debug mode when I run the program. Connection is being established, and communication works as intended. But when I run the program without debug mode, I get ERR_RTE error.

I searched the internet and couldn't find an answer to my problem.

I suppose the code is fine due to the fact it works in debug mode.

Program generates error in tcp_connect function at netif = ip_route part.

Here is the code:

uint8_t TCP_ClientInit()
{
struct tcp_pcb *tpcb = {0};
err_t res = 0;
tpcb = tcp_new();

if(tpcb != 0) {
ip_addr_t sourceIPAddr;
IP_ADDR4(&sourceIPAddr, 192, 168, 0, 111);
res = tcp_bind(tpcb, &sourceIPAddr, 1500);

ip_addr_t destIPADDR;
IP_ADDR4(&destIPADDR, 192, 168, 0, 15);

res = tcp_connect(tpcb, &destIPADDR, 1400, tcp_client_connected); // this returns error ERR_RTE
}
else {
return HAL_ERROR;
}

if(res == ERR_OK) {
return HAL_OK;
}

return HAL_ERROR;
}

err_t tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port,
tcp_connected_fn connected)
{
struct netif *netif = NULL;
err_t ret;
u32_t iss;
u16_t old_local_port;

LWIP_ASSERT_CORE_LOCKED();

LWIP_ERROR("tcp_connect: invalid pcb", pcb != NULL, return ERR_ARG);
LWIP_ERROR("tcp_connect: invalid ipaddr", ipaddr != NULL, return ERR_ARG);

LWIP_ERROR("tcp_connect: can only connect from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN);

LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port));
ip_addr_set(&pcb->remote_ip, ipaddr);
pcb->remote_port = port;

if (pcb->netif_idx != NETIF_NO_INDEX) {
netif = netif_get_by_index(pcb->netif_idx);
} else {
/* check if we have a route to the remote host */
netif = ip_route(&pcb->local_ip, &pcb->remote_ip); // ### this returns NULL
}
if (netif == NULL) {
/* Don't even try to send a SYN packet if we have no route since that will fail. */
return ERR_RTE;
} 
Best answer by ASEHST

Hello @DziadGarbaty , 

Please take a look at this post: Solved: Basic UDP Echo server works in debug, but not run ... - STMicroelectronics Community. You might be experiencing a similar issue.

 

With Regards,

4 replies

Andrew Neil
Super User
March 1, 2025

@DziadGarbaty wrote:

Everything works just fine in debug mode when I run the program. Connection is being established, and communication works as intended. But when I run the program without debug mode, I get ERR_RTE error.


Instrument your code so that you can see what's happening with & without the debugger.

Are you using a standard ST example?

For LwIP diagnostic messages, see:

https://community.st.com/t5/stm32-mcus/using-the-itm-console-for-printf-redirects-and-lwip-debug/ta-p/723472

 

More on STM32H7 and LwIP:

https://community.st.com/t5/forums/searchpage/tab/message?advanced=false&allow_punctuation=false&filter=includeTkbs&inactive=false&include_tkbs=true&q=H7%20lwip

 

Have you looked-up what this "ERR_RTE error" actually means? Where, exactly, does it occur?

 


@DziadGarbaty wrote:

Here is the code:


Your code has lost all indentation - please see How to insert source code.

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Guillaume K
ST Employee
April 1, 2025

"ERR_RTE" means "routing error". There's no interface for the IP packet you want to send.

But in that case I think it is because there's no interface at all. 

This may be caused by the time taken by autonegotiation between the board's PHY and the ethernet switch.

Normally, the examples provided by ST do a polling on the PHY registers to wait until the PHY says it is connected. No need for delay.

Andrew Neil
Super User
April 1, 2025

@Guillaume K wrote:

Normally, the examples provided by ST do a polling on the PHY registers to wait until the PHY says it is connected. No need for delay.


But @DziadGarbaty  (this thread), and  @Hey0256 and @KMill (the older threads) did all find a delay to be necessary 

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
ASEHSTBest answer
ST Employee
March 3, 2025

Hello @DziadGarbaty , 

Please take a look at this post: Solved: Basic UDP Echo server works in debug, but not run ... - STMicroelectronics Community. You might be experiencing a similar issue.

 

With Regards,

Associate
March 3, 2025

Thank you, @ASEHST 
Indeed adding HAL_Delay after clock initialisation solved the problem. Program starts most of the time so perhaps I need to adjust the delay value.
Interesting problem, I never would have thought the solution would be so simple!

Andrew Neil
Super User
March 4, 2025

@DziadGarbaty wrote:

 perhaps I need to adjust the delay value.


Better, look at what it is that is needing time to "stabilise" and, instead of an arbitrary delay, test for that condition...

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Andrew Neil
Super User
March 26, 2025
A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
ST Employee
July 7, 2025

Hello @DziadGarbaty ,

During the initialization process, the ETH MAC must be configured with the correct Ethernet link speed and duplex mode after the auto-negotiation process is completed, which can take up to a few seconds (see the API HAL_ETH_SetMACConfig).

To resolve the issue, please follow these steps:

  • With FreeRTOS: Add the task ethernet_link_thread (refer to the example "STM32F767ZI-Nucleo\Applications\LwIP\LwIP_HTTP_Server_Netconn_RTOS" ).
  • Without an RTOS: Add a call to the API Ethernet_Link_Periodic_Handle in your main loop (refer to the example "STM32F769I_EVAL\Applications\LwIP\LwIP_HTTP_Server_Raw").

 

This fix periodically polls the PHY status and updates the MAC configurations if any changes occur to the Ethernet link.

Note: There is no need to add an additional HAL_Delay().

           Both examples can be retrieved in the STM32CubeF7 v1.17.0 package.

Best regards.