Any STM 32F4 ETH + LWIP + FreeRTOS + MbedTLS experts here? (not free advice) - Page 1
Forum section: electronics / general

author: peter-h
author_rank: Super Contributor
timestamp: July 13, 2022, 01:46:49 pm
content: There is basically nobody out there that I can find.The internet is full of contradictory junk, and obsolete advice from 2008/2009.To start with, I would like to solve the question of thread-safetyhttps://www.eevblog.com/forum/microcontrollers/lwip-32f417-how-to-optimise-network-stack-memory-allocation/msg4295431/#msg4295431Then the question of MEMP_MEM_MALLOC=1 which does work but produces a lot of crashes (which I suspect are due to exposing non thread safe issues).I've found that the mem_ heap used by LWIP is thread safe (uses FreeRTOS mutexes). But the LWIP API (e.g. socket()) is not thread safe unless LWIP_TCPIP_CORE_LOCKING=1 (which then brings in the same mutex protection to the API functions) but that breaks some other code.Obviously this cannot be solved remotely. But perhaps somebody knows something about LWIP_TCPIP_CORE_LOCKING breaking stuff. I found some posts about this being not properly implemented. But at the same time I do not believe this has not been solved, because LWIP which is not thread safe for the socket API calls is of very limited use.

author: peter-h
author_rank: Super Contributor
timestamp: July 14, 2022, 06:18:50 am
content: Well, after asking everywhere, putting this out on freelancer.com, etc, I did more digging around and found the main issue. In ethernetif.cI noticed those mutex macros (which are not suggested anywhere including in the ST UM1713 implementation notes) were rather similar to the ones protecting the LWIP socket etc APIif LWIP_TCPIP_CORE_LOCKING=1... You can't do that; you must not have overlapping mutex regions. Especially obvious protecting low level ETC calls with the same mutex as is used for the high level TCP API! So I used different mutexes. That fixed it.Actually I wonder if mutexing these low level ETH calls is even needed. The code runs without it, but that can easily be by luck. Nobody else is calling those functions. But they can be chopped by an RTOS task switch. Disabling interrupts ("CRITICAL" region) would have been another way, but with a significant interrupt latency. This code is polled anyway, not interrupt driven.I also uses one mutex for tx and one mutex for rx. It is an interesting Q whether the 32F417 ETH can transmit and receive at the same time, given that there is only one RJ45, but I think ETH can be bidirectional in general.Hopefully this helps somebody one day.Then I retested MEMP_MEM_MALLOC=1 which was the other thing that broke things. Now, the statically allocated buffer MEM_SIZE (inside which LWIP runs a private heap) gets stuffed with more stuff, notably the PBUF_POOL_SIZE * PBUF_POOL_BUFSIZE packet buffers, so MEM_SIZE has to go up from 6k to 16k in my case, but the static RAM usage remains the same because previously LWIP was statically allocating a load of stuff. That now runs also but not reliably so I won't bother with it. It cannot magic up RAM from nowhere.If MEMP_MEM_MALLOC=0, I have a very reliable system. MEM_SIZE is statically allocated and, by experimentation, holds the PBUF_POOL_BUFSIZE buffers and (if MEMP_MEM_MALLOC=0) some other odd small bits which seem to be just a few bytes in size and appear mysteriously in different places.