2024-04-23 09:58 AM
Hi,
I am using STM32F207 series microcontroller and I am using ethernet using LWIP version 2.0.3.
Also after LWIP init(), I am doing to initializing the tcp server.(means created TCP server within stm32)
When ethernet cable is connected with the PC, the TCP client connection works well after power up the microcontroller.
But if the ethernet cable is not connected with the PC and do the power up, TCP client is not able to connect and also the server is not accepting the connection.
Below is my code of TCP server init AND server accept function:
void tcp_server_init(void){
/* create new tcp pcb */
tcp_server_pcb = tcp_new();
//printf("tcp server init(), port:%d\n", TCP_SERVER_PORT);
if (tcp_server_pcb != NULL)
{
err_t err;
/* bind echo_pcb to port 7 (ECHO protocol) */
err = tcp_bind(tcp_server_pcb, IP_ADDR_ANY, 2024/*TCP_SERVER_PORT*/);
if (err == ERR_OK)
{
/* start tcp listening for echo_pcb */
tcp_server_pcb = tcp_listen(tcp_server_pcb);
/* initialize LwIP tcp_accept callback function */
tcp_accept(tcp_server_pcb, tcp_server_accept);
}
else
{
/* deallocate the pcb */
memp_free(MEMP_TCP_PCB, tcp_server_pcb);
printf("bind tcp server fail\r\n");
}
}
//---------------------------------------------------------------------------------------------------
static err_t tcp_server_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
{
err_t ret_err;
struct tcp_server_struct *es;
LWIP_UNUSED_ARG(arg);
LWIP_UNUSED_ARG(err);
/* set priority for the newly accepted tcp connection newpcb */
tcp_setprio(newpcb, TCP_PRIO_MIN);
/* allocate structure es to maintain tcp connection informations */
es = (struct tcp_server_struct *)mem_malloc(sizeof(struct tcp_server_struct));
if (es != NULL)
{
es->state = ES_ACCEPTED;
es->pcb = newpcb;
es->p = NULL;
printf("Tcp conn accepted\r\n");
/* pass newly allocated es structure as argument to newpcb */
tcp_arg(newpcb, es);
/* initialize lwip tcp_recv callback function for newpcb */
tcp_recv(newpcb, tcp_server_recv);
/* initialize lwip tcp_err callback function for newpcb */
tcp_err(newpcb, tcp_server_error);
/* initialize lwip tcp_poll callback function for newpcb */
tcp_poll(newpcb, tcp_server_poll, 1);
ret_err = ERR_OK;
}
else
{
/* close tcp connection */
tcp_server_connection_close(newpcb, es);
printf("Accept TCP conn fail\r\n");
/* return memory error */
ret_err = ERR_MEM;
}
return ret_err;
}
//----------------------------------------------------------------------------------------------
Please suggest, I am stuck and not able to proceed if after powerup if the ethernet cable is not connected with the PC.
Thanks and Regards,
Jasmin
2024-07-08 04:36 AM
Hello @jjmamtora ,
I think you are facing this issue because you are missing some steps like the link callback which will handle the scenario of disconnected cable.
here is what I will suggest you test:
- Ensure that the network interface is up and running before you initialize the TCP server. You can check the link status and bring up the interface if it is down.
- Use a link callback function to detect when the Ethernet cable is connected and then initialize the TCP server.
here is a revised version of your implementation :
#include "lwip/netif.h"
#include "lwip/dhcp.h"
#include "lwip/tcpip.h"
#include "ethernetif.h"
extern struct netif gnetif; // Assuming gnetif is your network interface
void tcp_server_init(void);
static err_t tcp_server_accept(void *arg, struct tcp_pcb *newpcb, err_t err);
void netif_link_callback(struct netif *netif);
void tcp_server_init(void) {
/* create new tcp pcb */
tcp_server_pcb = tcp_new();
if (tcp_server_pcb != NULL) {
err_t err;
/* bind echo_pcb to port 2024 */
err = tcp_bind(tcp_server_pcb, IP_ADDR_ANY, 2024);
if (err == ERR_OK) {
/* start tcp listening for echo_pcb */
tcp_server_pcb = tcp_listen(tcp_server_pcb);
/* initialize LwIP tcp_accept callback function */
tcp_accept(tcp_server_pcb, tcp_server_accept);
} else {
/* deallocate the pcb */
memp_free(MEMP_TCP_PCB, tcp_server_pcb);
printf("bind tcp server fail\r\n");
}
}
}
static err_t tcp_server_accept(void *arg, struct tcp_pcb *newpcb, err_t err) {
err_t ret_err;
struct tcp_server_struct *es;
LWIP_UNUSED_ARG(arg);
LWIP_UNUSED_ARG(err);
/* set priority for the newly accepted tcp connection newpcb */
tcp_setprio(newpcb, TCP_PRIO_MIN);
/* allocate structure es to maintain tcp connection informations */
es = (struct tcp_server_struct *)mem_malloc(sizeof(struct tcp_server_struct));
if (es != NULL) {
es->state = ES_ACCEPTED;
es->pcb = newpcb;
es->p = NULL;
printf("Tcp conn accepted\r\n");
/* pass newly allocated es structure as argument to newpcb */
tcp_arg(newpcb, es);
/* initialize lwip tcp_recv callback function for newpcb */
tcp_recv(newpcb, tcp_server_recv);
/* initialize lwip tcp_err callback function for newpcb */
tcp_err(newpcb, tcp_server_error);
/* initialize lwip tcp_poll callback function for newpcb */
tcp_poll(newpcb, tcp_server_poll, 1);
ret_err = ERR_OK;
} else {
/* close tcp connection */
tcp_server_connection_close(newpcb, es);
printf("Accept TCP conn fail\r\n");
/* return memory error */
ret_err = ERR_MEM;
}
return ret_err;
}
void netif_link_callback(struct netif *netif) {
if (netif_is_link_up(netif)) {
printf("Ethernet cable connected\r\n");
tcp_server_init();
} else {
printf("Ethernet cable disconnected\r\n");
}
}
int main(void) {
// Initialize the hardware and LWIP stack
// ...
// Set the link callback function
netif_set_link_callback(&gnetif, netif_link_callback);
// Check if the network interface is up
if (netif_is_link_up(&gnetif)) {
tcp_server_init();
} else {
printf("Waiting for Ethernet cable to be connected...\r\n");
}
// Main loop
while (1) {
// Handle other tasks
// ...
}
}
Regards