2024-01-25 12:52 AM - edited 2024-01-29 01:14 AM
Working with STM32H743IIT single CM7 core MCU I was managed to have a stable product with Ethernet connectivity. Thanks everybody (@Piranha especially) for your advices
Now I was going to implement secure communication over ALTCP instead of regular manual mbedTLS way. It was very promising at the beginning with clean and understandable code... BUT! As soon as I enable ALTCP library in my project by having defined LWIP_ALTCP in lwipopts.h I have a problem:
It works like a charm for some time (from some minutes to couple of days) and then my application looses Ethernet link and gets it back again in a second, but with wrong DUPLEX state (half-duplex instead of full duplex). The problem originates in reading wrong values from LAN7820 link status register and is not related to stack overflow.
The only difference is in this macro. Link fails if ALTCP is enabled even it is not used (just regular clear-text protocol), but works fine with mbedTLS but not through ALTCP.
ethernetif.c
void ethernet_link_thread(void* argument)
{
...
for(;;)
{
PHYLinkState = LAN8742_GetLinkState(&LAN8742); <= Wrong link state returned
...
}
}
lan8742.c
int32_t LAN8742_GetLinkState(lan8742_Object_t *pObj)
{
...
pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BSR, &readval);
pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &readval);
pObj->IO.ReadReg(pObj->DevAddr, LAN8742_PHYSCSR, &readval);
...
}
Register values:
Normal operation | Failure | |
BSR | 0x782D (Auto-negotiation complete) | 0x780D |
BCR | 0x1100 (Auto-negotiation, FDX) | 0x0000 |
SCSR | 0x1058 | 0x1058 |
So, the registers are clearly show that there is no auto-negotiation after link failure. But it does not explain why could it happen just because of the code like this:
#if LWIP_ALTCP && LWIP_ALTCP_TLS
// fails even if client_info->tls_config == 0
if (client_info->tls_config) {
client->conn = altcp_tls_new(client_info->tls_config, IP_GET_TYPE(ip_addr));
} else
#endif
// Works only if LWIP_ALTCP is undefined
{
client->conn = altcp_tcp_new_ip_type(IP_GET_TYPE(ip_addr));
}
if (client->conn == NULL) {
return ERR_MEM;
}