Please find attached a new NetworkInterface.c for STM32F4. It has implemented the zero-copy feature in both directions, and therefore it is more efficient and faster than its earlier version.
I would like to invite anyone interested to try it out. Be aware that it may not be as stable yet as the existing driver. I tested it with UDP/TCP/ICMP/etc, and also with iperf.
The following settings are recommended for this driver:
/* Add to your 'FreeRTOSIPConfig.h'. */
#define ipconfigZEROCOPYRXDRIVER 1
#define ipconfigZEROCOPYTXDRIVER 1
#define ipconfigETHERNETDRIVERFILTERS_PACKETS 1
/* Add/change to your stm32f4xx_hal_conf.h : */
#define ETH_RX_BUF_SIZE ( ipconfigNETWORK_MTU + 36 )/* buffer size for receive */
#define ETH_TX_BUF_SIZE ( ipconfigNETWORK_MTU + 36 )/* buffer size for transmit */
ETH_TX_BUF_SIZE are defined as
ETH_MAX_PACKET_SIZE, which is hard-coded as
With a limited amount of RAM, it may be very profitable to reduce the value of
ipconfigNETWORK_MTU to e.g.
So let tha value of
ETH_TX_BUF_SIZE depend on
The new driver will also filter incoming packets. That can be important in networks with many UDP broadcasts. These packets should be filtered-out as soon as possible in order not to occupy resources.
The following CUBE/HAL functions won't be called any more:
For two reasons: they're not compatible with zero-copy, and/or the in-line implementation is faster.
The interface will now work for two types of PHY's: DP83848I ( found on STM324xG-EVAL ), and also LAN8720 ( found on STM32F4-DISCOVERY ).
I pressed on Post too soon, hadn't attached the driver yet. Here it is
xNetworkInterfaceInitialise() had become quite large and therefore less readable, I've split up some code into separate functions:
/* Initialise TX-descriptors. */
/* Initialise RX-descriptors. */
This time I also I included the latest iperf3 module. I tested on a STM3240G-EVAL, using the following defines for iperf:
/* Some defines for iperf, optimised for speed. /
/ Put these in your 'FreeRTOSIPConfig.h' */
#define ipconfigIPERFDOESECHO_UDP 0
#define ipconfigIPERF_VERSION 3
#define ipconfigIPERF_STACK_SIZE_IPERF_TASK 680
#define ipconfigIPERF_TX_BUFSIZE ( 8 * ipconfigTCP_MSS )
#define ipconfigIPERF_TX_WINSIZE ( 6 )
#define ipconfigIPERF_RX_BUFSIZE ( 8 * ipconfigTCP_MSS )
#define ipconfigIPERF_RX_WINSIZE ( 6 )
/* The iperf module declares a character buffer to store its send data. */
#define ipconfigIPERF_RECV_BUFFER_SIZE ( 2 * ipconfigTCP_MSS )
The above parameters are optimised for speed.
The iperf driver can be started by calling
vIPerfInstall() once after the network is up (
vApplicationIPNetworkEventHook() is called with eNetworkUp ).
Here is an example optimised for memory usage:
/* Defines for iperf, optimised for memory usage. */
#define ipconfigIPERFTXBUFSIZE ( 3 * ipconfigTCPMSS )
#define ipconfigIPERFTXWINSIZE ( 2 )
#define ipconfigIPERFRXBUFSIZE ( 3 * ipconfigTCPMSS )
#define ipconfigIPERFRXWINSIZE ( 2 )
Today I re-tested the
memcpy() mode: it still functions. Using zero-copy is especially profitable when the device is sending data.