2026-01-30 5:58 AM - edited 2026-01-30 6:26 AM
Hello!
I am writing a program for STM32F769I-DISCO board that uses FreeRTOS and LwIP to communicate with the server and send data to it. It generally works, but unplugging and plugging Ethernet cable (especially doing it several times within a few seconds) usually causes Ethernet DMA errors which make program stop calling HAL_ETH_IRQHandler and thus board can't even try to reconnect to server. I don't know how I should handle those errors and where to look for information that could offer a solution to my problem.
Any kind of help, whether a direct response or a link to helpful resources, is appreciated.
Ethernet DMASR register
heth error code
MPU and Ethernet descriptors
EDIT 1: Added ethernetif.c and lwip.c files to attachments and screenshot of MPU configuration.
2026-01-30 6:07 AM
Can you share your lwip.c implementation as well as ethernetif.c? Also how often per second do you plug it out?
It could be possible that something in the ethernet thread is silently failing or a mutex is internally overflowing. Maybe you could internally in the thread implement a logging mechanism and track it, or you accept that it is maybe out of scope XD
2026-01-30 6:29 AM
I added files to attachments. In short, I didn't really change those files, only added attributes to semaphores and inserted some uint8_t variables to check them in debugger. The biggest changes are in lwipopts.h file where I decided to turn off some features without regenerating code with CubeMX.
2026-02-02 3:28 AM - edited 2026-02-02 3:30 AM
I made some progress in regard to restarting the Ethernet peripheral and its DMA, but I still have a problem with reconnecting to the server.
if (resetDMA==1) {
resetDMA=0;
heth.Instance->DMAOMR &= ~(ETH_DMAOMR_ST | ETH_DMAOMR_SR); //clear start/stop transmit and receive flags
heth.Instance->DMABMR |= (ETH_DMABMR_SR); //set software reset flag
while (heth.Instance->DMABMR & ETH_DMABMR_SR) {
//wait
}
volatile HAL_StatusTypeDef ethInit=HAL_ETH_Init(&heth);
volatile HAL_StatusTypeDef ethStartIt=0x04;
if (netif_is_up(&gnetif) && netif_is_link_up(&gnetif)) {
ethStartIt=HAL_ETH_Start_IT(&heth);
}
}
Screenshot from RM0410 document
EDIT 1: Spelling mistakes.
2026-02-02 6:18 AM
Working a) without RTOS, b) H723, and c) only as TCP server here, so I don't know if that helps.
Usually lwip has a function called something like Ethernet_Link_Periodic_Handle().
I have it in LwIpProcess().
This checks periodically the PHY if it's still connected, then calls ethernetif_update_config() if necessary, which was set as netif->link_callback. Only used if LWIP_NETIF_LINK_CALLBACK is set in some lwip opt.h file.
ethernetif_update_config() re-inits the ETH peripheral if it's up, or stops the peripheral (Tx & RX stop, flush FIFOs, disable state machine).
At least here with server only functions, it works like a charm.
IDK if that helps if the STM32 is the client.
2026-02-03 3:07 AM
Could you please share ethernetif_update_config() function's body here? I generated new STM32 project with LwIP and without FreeRTOS and there is no ethernetif_update_config(), only ethernet_link_check_state() which exists in the same form in my project but as a separate thread.
2026-02-03 3:49 AM
in ethernetif.c:
#if LWIP_NETIF_LINK_CALLBACK
/**
* @brief Link callback function, this function is called on change of link status
* to update low level driver configuration.
* @PAram pNetif: The network interface
* @retval None
*/
void ethernetif_update_config(struct netif *pNetIf)
{
if( netif_is_link_up(pNetIf) )
{
/* Restart the auto-negotiation */
/* PHY settings and readback done in MAC init */
/* ETHERNET MAC Re-Configuration */
EthMacInit();
/* Restart MAC interface */
EthStartIT();
}
else
{
/* Stop MAC interface */
EthStop();
}
ethernetif_notify_conn_changed(pNetIf);
}
#endif /* LWIP_NETIF_LINK_CALLBACK */
2026-02-03 3:50 AM
But as I said, I have no idea how lwip handles being a TCP client when disconnecting.
2026-02-03 5:09 AM
Is this code generated by STM32CubeMX? I created new project for STM32H723ZGTx MCU and it doesn't have functions You have.
2026-02-03 5:52 AM
When generating code for LWIP, only ethernetif.c is out-of-the-box working. lwip.c, where you write the application layer functions, which you later call from freertos.c, is nothing useful as it comes from CubeMX. I implemented funtions for DHCP, the functions to connect, reconnect and disconnect as well as a few tweaks to stack sizes in my lwip.c.
In generel, go to the github of you MCU and copy the pieces of that what you want to achieve. Be aware trhat you need to decide first, which API you want to use, I am personally a fan of Netconn API.
Feel free to ask further questions!
Best regards