STM32/LwIP/FreeRTOS on Nucleo : how to handle ethernet link status change ?
Hello,
I'm developping a demonstrator with a shield I made to fit a Nucleo 144 - F207ZG board. My application uses ethernet link (TCP, UDP client and server) and FreeRTOS. Base project is generated from CubeMX and I work under Atollic True Studio. This is my first projet with STM32, FreeRTOS and LwIP.
My application works fine, but the ethernet low level management is pretty basic (generated by CubeMX) : wait for 5 seconds to get a link up, then run app. If link is down at startup and becomes up later, the driver does not get the updated information and the system remains down. If link is up at start and application runs correctly, I'm not informed by low level driver of link loss.
I looked at code examples for EVAL boards and in this case this is handled by an additionnal task because the PHY has an INT signal connected to the STM32, that triggers the link check routines. But on the NUCLEO144 boards, using a low cost PHY (LAN8742) the INT signal is not connected and used a clock signal to synchronise PHY and MAC. So I'm not able to use that kind of warning to handle link status changes.
The only solution I see would be to check periodically the PHY internal STATUS register to check link status, but I'm not confident enough to modify the driver and perform checks without inferering with existing running driver task. However, my idea is to create a task with priority higher than ethernet task, executed periodically :
- if link is down, check the PHY status register, and if link is now up, restart the init sequence and create all the threads required by my application using ethernet
- if link is up, check if the heth->State is equal to HAL_ETH_STATE_READY, and if ready, check the PHY register to see if link is still up. If link down, call the function that disables the MAC, and stop the high level ethernet tasks. But I'm afraid of interfering with ETH interrupt. What happens if I'm accessing the PHY with my test task, and an IT triggers with received data to handle ?
Would that be reliable ? Does someone has some tips to give to me, or have better implementations of low level ethernet management with freertos/lwip ?
Would it be more reliable if I get the functions related to link state change management from an EVAL demo, and I just modify the trigger of the call to be not an interrupt, but a periodic delay (ie every second) ?
Moreover, I'm surprised that the init function is so long for initializing. In stm32f2xx_hal_eth.c, each step is limited by a timeout, for example 5 seconds to get the link (ETH_TIMEOUT_LINKED_STATE), and this is defined inside the file itself, not a configurable feature without modifying the driver. This is a blocking execution ; when running at startup it's not really a problem, but if running from a thread (when app needs to reinit MAC after link switching from down to up), that does not give the hand to lower priority task until operations are finished. That means that this task should be executed with the lowest priority, am I right ?
Thanks
Aurelien
