dnil-daniel wrote on Sunday, January 22, 2017:
Greetings,
I’ve evaluated the TCP stack from FreeRTOS+TCP version 160919 on the STM32F746 MCU together with FreeRTOS 9.0.0. Using the STM32F4 demo as a base, I’ve ported the driver layer to the STM32F7 MCU. This process wasn’t all that straight forward unfortunately, partly since it took some time to understand how the ST supplied HAL ethernet driver layer had been altered in this F4 demo, and since I wanted to work on the F7 I could’t just use the FreeRTOS modifed F4 HAL drivers as is. I ended up modifying the glue layer between +TCP and HAL quite a bit in order not to require any HAL layer changed. At the end of this process I was stuck with a silly intermittent error which causes intermittent TX frame drops, as far as I can tell this is an F7 specific issue which seems to have hit other users as well. My findings are documented towards the end of this thread: https://community.st.com/thread/31587, conclusion is that there appears to be a race condition inside the HAL driver, so I ended up having to apply a small patch to ST HAL layer.
With my HAL patch in place I have enabled the D-cache on the F7, this cache requires some fairly specific MPU setup to ensure cache coherency. Atmel has a nice presentation on this topic for Cortex-M7, even though it is a different MCU their reasoning behing the GMAC buffer coherency in this presentation holds true also for STM32F7 as far as I can tell: http://atmel.force.com/support/servlet/fileField?id=0BEG000000002X7. What it comes down to is setting up the linker control file and the MPU for a non-cachable memory area to store the MAC buffers. I’m using the BufferAllocation_1.c allocator, but haven’t spent the time for a true zero-copy scheme yet.
To test the stack I ended up using the iperf client/server from this thread: https://sourceforge.net/p/freertos/discussion/382005/thread/211fa5fa/3f27/attachment/iperf_plus_tcp.zip. This iperf code integrates nicely, but I’m not convinced about the results yet, the throughput is very assymetrical as in this iperf output (192.168.2.142 is target, 192.168.2.26 is host)
iperf -c 192.168.2.142 --dualtest -p 5001 -i 2 -n 128M
Server listening on TCP port 5001
TCP window size: 85.3 KByte (default)
Client connecting to 192.168.2.142, TCP port 5001
TCP window size: 144 KByte (default)
[ 5] local 192.168.2.26 port 42152 connected with 192.168.2.142 port 5001
[ 4] local 192.168.2.26 port 5001 connected with 192.168.2.142 port 59766
[ ID] Interval Transfer Bandwidth
[ 5] 0.0- 2.0 sec 22.2 MBytes 93.3 Mbits/sec
[ 4] 0.0- 2.0 sec 161 KBytes 660 Kbits/sec
[ 5] 2.0- 4.0 sec 22.2 MBytes 93.3 Mbits/sec
[ 4] 2.0- 4.0 sec 71.3 KBytes 292 Kbits/sec
[ 4] 4.0- 6.0 sec 71.3 KBytes 292 Kbits/sec
[ 5] 4.0- 6.0 sec 22.2 MBytes 93.3 Mbits/sec
[ 5] 6.0- 8.0 sec 22.1 MBytes 92.8 Mbits/sec
[ 4] 6.0- 8.0 sec 71.3 KBytes 292 Kbits/sec
[ 5] 8.0-10.0 sec 22.1 MBytes 92.8 Mbits/sec
[ 4] 8.0-10.0 sec 71.3 KBytes 292 Kbits/sec
[ 5] 0.0-11.5 sec 128 MBytes 93.1 Mbits/sec
[ 4] 0.0-11.6 sec 502 KBytes 355 Kbits/sec
While running these tests, there are no errors from the TCP stack. Reason why there seems to be so little data from the target to the host is since the call to FreeRTOS_Send() around line 363 inside vIPerfTCPWork() returns -pdFREERTOS_ERRNO_ENOSPC and the data to host is not actually sent. I’m not sure how this iperf server is intended to work and haven’t gone into details on this yet. But it seems to me that the TCP stack is very busy ACKing data on the socket in the direction towards to host and no resources are left to transmit data on the socket in the other direction. Maybe someone can shed some light on how the stack is intended to work in this scenario? Apart from that, the F7 is running at 192MHz, compiler is gcc 5.4 with newlib, ART and I+D caches enabled, STM32F7xx HAL drivers version 1.1.2.
All in all, I think the integration of FreeRTOS+TCP is showing promise though the complexity of the intergration towards the platform layer (CMSIS and ST HAL) is quite complex at the moment.