STM32F407/STM32F417 microcontrollers feature a high-quality 10/100 Mbit/s Ethernet
peripheral that supports both Media Independent Interface (MII) and Reduced Media
Independent Interface (RMII) to interface with the Physical Layer (PHY).
When working with an Ethernet communication interface, a TCP/IP stack is mostly used to
communicate over a local or a wide area network.
This application note presents a demonstration package built on top of the LwIP
(Lightweight IP) TCP/IP stack which is an open source stack intended for embedded
devices.
This demonstration package contains nine applications running on top of the LwIP stack:
●Applications running in standalone mode (without an RTOS):
–A Web server
–A TFTP server
–A TCP echo client application
–A TCP echo server application
–A UDP echo client application
–A UDP echo server application
●Applications running with the FreeRTOS operating system:
–A Web server based on netconn API
–A Web server based on socket API
–A TCP/UDP echo server application based on netconn API
LwIP is a free TCP/IP stack developed by Adam Dunkels at the Swedish Institute of
Computer Science (SICS) and licensed under a modified BSD license.
The focus of the LwIP TCP/IP implementation is to reduce the RAM use while still having a
full scale TCP/IP stack. This makes LwIP suitable for use in embedded systems.
LwIP comes with the following protocols:
●IPv4 and IPv6 (Internet Protocol v4 and v6)
●ICMP (Internet Control Message Protocol) for network maintenance and debugging
●IGMP (Internet Group Management Protocol) for multicast traffic management
●UDP (User Datagram Protocol)
●TCP (Transmission Control Protocol)
●DNS (Domain Name Server)
●SNMP (Simple Network Management Protocol)
●DHCP (Dynamic Host Configuration Protocol)
●PPP (Point to Point Protocol)
●ARP (Address Resolution Protocol)
LwIP has three application programming interface (API) sets:
●Raw API is the native API of LwIP. It enables the development of applications using
event callbacks. This API provides the best performance and code size, but adds some
complexity for application development.
●Netconn API is a high-level sequential API that requires the services of a real-time
operating system (RTOS). The Netconn API enables multi-threaded operations.
●BSD Socket API: Berkeley-like Socket API (developed on top of the Netconn API)
The source code for the LwIP stack can be downloaded at the following link:
http://savannah.nongnu.org/projects/LwIP
Note:This application note is based on LwIP v1.3.2
6/47Doc ID 022105 Rev 1
AN3966LwIP stack overview
2.2 Folder organization of the LwIP stack
When unzipped, the LwIP stack files can be found under “\Utilities\Third_Party\LwIP_v1.3.2”
as shown in Figure 1.
Figure 1.LwIP folder organization
●doc: documentation text files
●port/STM32F4x7: files implementing the LwIP port to STM32F4x7
–arch: STM32 architecture port files (used data types,...)
–FreeRTOS: LwIP port to STM32F4x7 using FreeRTOS
–Standalone: LwIP port to STM32F4x7 in Standalone mode
●src: source files of the LwIP stack
–api: Netconn and Socket API files
–core: LwIP core files
–include: LwIP include files
–netif: Network interface files
2.3 LwIP API overview
As mentioned above, three types of APIs are offered by LwIP stack:
●Raw API
●Netconn API
●Socket API
2.3.1 Raw API
The Raw API is based on the native API of LwIP. It is used to develop callback-based
applications.
When initializing the application, the user needs to register callback functions to different
core events (such as TCP_Sent, TCP_error,...) . The callback functions will be called from
the LwIP core layer when the corresponding event occurs.
Doc ID 022105 Rev 17/47
LwIP stack overviewAN3966
Ta bl e 1 provides a summary of the Raw API functions for TCP applications.
Table 1.TCP Raw API functions
API functionDescription
TCP connection
setup
Sending TCP data
Receiving TCP data
Application polling
tcp_new
tcp_bind
tcp_listen
tcp_accept
tcp_accepted
tcp_connect
tcp_write
tcp_sent
tcp_output
tcp_recv
tcp_recved
tcp_poll
Creates a new TCP PCB (protocol control block).
Binds a TCP PCB to a local IP address and port.
Starts the listening process on the TCP PCB.
Assigns a callback function that will be called when a
new TCP connection arrives.
Informs the LwIP stack that an incoming TCP
connection has been accepted.
Connects to a remote TCP host.
Queues up data to be sent.
Assigns a callback function that will be called when sent
data is acknowledged by the remote host.
Forces queued data to be sent.
Sets the callback function that will be called when new
data arrives.
Must be called when the application has processed the
incoming data packet (for TCP window management).
Assigns a callback functions that will be called
periodically. It can be used by the application to check if
there is remaining application data that needs to be sent
or if there are connections that need to be closed.
Closes a TCP connection with a remote host.
Assigns a callback function for handling connections
aborted by the LwIP due to errors (such as memory
shortage errors).
Aborts a TCP connection.
Closing and aborting
connections
tcp_close
tcp_err
tcp_abort
Ta bl e 2 provides a summary of the Raw API functions for UDP applications.
Table 2.UDP Raw API functions
API functionDescription
udp_new
udp_remove
udp_bind
udp_connect
udp_disconnect
udp_send
udp_recv
Creates a new UDP PCB.
Removes and de-allocates a UDP PCB.
Binds a UDP PCB with a local IP address and port.
Sets up a UDP PCB remote IP address and port.
Removes a UDP PCB remote IP and port.
Sends UDP data.
Specifies a callback function which is called when a datagram is received.
8/47Doc ID 022105 Rev 1
AN3966LwIP stack overview
2.3.2 Netconn API
The Netconn API is a high-level sequential API which has a model of execution based on
the blocking open-read-write-close paradigm.
To function correctly, this API must run in a multi-threaded operation mode where there is a
separate thread for the LwIP TCP/IP stack and one or multiple threads for the application.
Ta bl e 3 provides a summary of the Netconn API functions.
Table 3.Netconn API functions
API functionDescription
netconn_new
netconn_delete
netconn_bind
netconn_connect
netconn_send
netconn_recv
netconn_listen
netconn_accept
netconn_write
netconn_close
2.3.3 Socket API
LwIP offers the standard BSD socket API. This is a sequential API which is internally built on
top of the netconn.
Ta bl e 3 provides a summary of the main socket API functions.
Table 4.Socket API functions
Creates a new connection.
Deletes an existing connection.
Binds a connection to a local IP address and port.
Connects to a remote IP address and port.
Sends data to the currently connected remote IP/port (not applicable for
TCP connections).
Receives data from a netconn.
Sets a TCP connection into a listening mode.
Accepts an incoming connection on a listening TCP connection.
Sends data on a connected TCP netconn.
Closes a TCP connection without deleting it.
API functionDescription
socket
bind
listen
connect
accept
read
write
close
Creates a new socket.
Binds a socket to an IP address and port.
Listens for socket connections.
Connects a socket to a remote host IP address and port.
Accepts a new connection on a socket.
Reads data from a socket.
Writes data on a socket.
Closes a socket (socket is deleted).
Doc ID 022105 Rev 19/47
LwIP stack overviewAN3966
next
payload
len
tot_len
flags
ref
Room for packet headers
next pbuf structure
MS18173V1
2.4 LwIP buffer management
2.4.1 Packet buffer structure
LwIP manages packet buffers using a data structure called pbuf. The pbuf structure enables
the allocation of a dynamic memory to hold a packet content and lets packets reside in the
static memory.
Pbufs can be linked together in a chain. This enables packets to span over several pbufs.
Figure 2.Pbuf structure
●next: pointer to next pbuf in a pbuf chain
●payload: pointer to packet data payload
●len: length of the data content of the pbuf
●tot_len: sum of pbuf len plus all the len fields of the next pbufs in the chain
●ref: (on 4 bits) reference count that indicates the number of pointers that reference the
pbuf. A pbuf can be released from memory only when its reference count is zero.
●flags: (on 4 bits) indicate the type of pbuf.
LwIP defines three types of pbufs, depending on the allocation type:
●PBUF_POOL: pbuf allocation is performed from a pool of statically pre-allocated pbufs
that have a predefined size. Depending on the data size that needs to be allocated, one
or multiple chained pbufs are allocated.
●PBUF_RAM: pbuf is dynamically allocated in memory (one contiguous chunk of
memory for the full pbuf)
●PBUF_ROM: there is no allocation for memory space for user payload, the pbuf
payload pointer points to data in the ROM memory (it can be used only for sending
constant data).
For packet reception, the suitable pbuf type is PBUF_POOL; it allows to rapidly allocate
memory for the received packet from the pool of pbufs. Depending on the size of the
received packet, one or multiple chained pbufs are allocated. The PBUF_RAM is not
suitable for packet reception because dynamic allocation takes some delay. It may also lead
to memory fragmentation.
For packet transmission, depending on the data to be transmitted, the user can choose the
most suitable pbuf type.
10/47Doc ID 022105 Rev 1
AN3966LwIP stack overview
2.4.2 API for managing pbufs
LwIP has a specific API for working with pbufs. This API is implemented in the pbuf.c core
file.
Table 5.Pbuf API functions
API functionDescription
pbuf_alloc
pbuf_realloc
pbuf_ref
pbuf_free
pbuf_clen
pbuf_cat
pbuf_chain
pbuf_dechain
pbuf_copy_partial
pbuf_take
pbuf_coalesce
Allocates a new pbuf.
Resizes a pbuf (shrink size only).
Increments the reference count field of a pbuf.
Decrements the pbuf reference count. If it reaches zero, the pbuf is deallocated.
Returns the count number of pbufs in a pbuf chain.
Chains two pbufs together (but does not change the reference count of
the tail pbuf chain).
Chains two pbufs together (tail chain reference count is incremented).
Unchains the first pbuf from its succeeding pbufs in the chain.
Copies (part of) the contents of a packet buffer to an application
supplied buffer.
Copies application supplied data into a pbuf.
Creates a single pbuf out of a queue of pbufs.
Note:1“pbuf” can be a single pbuf or a chain of pbufs.
2When working with the Netconn API, netbufs (network buffers) are used for
sending/receiving data.
3A netbuf is simply a wrapper for a pbuf structure. It can accommodate both allocated and
referenced data.
4A dedicated API (implemented in file netbuf.c) is provided for managing netbufs (allocating,
freeing, chaining, extracting data,...).
2.5 Interfacing LwIP to STM32F4x7 Ethernet network interface
The port of LwIP stack to STM32F4x7 is located in folder “/port/STM32F4x7”.
This demonstration package provides two implementations:
●Implementation without RTOS (standalone)
●Implementation with an RTOS using FreeRTOS (http://www.freertos.org/)
For both implementations, the ethernet_if.c file is used to link the LwIP stack to the
STM32F4x7 Ethernet network interface.
Doc ID 022105 Rev 111/47
LwIP stack overviewAN3966
Ta bl e 6 provides a summary of the ethernet_if.c functions.
Table 6.ethernet_if.c functions description
FunctionDescription
low_level_init
Calls the Ethernet driver functions to initialize the STM32F4x7 Ethernet
peripheral.
low_level_outputCalls the Ethernet driver functions to send an Ethernet packet.
low_level_inputCalls the Ethernet driver functions to receive an Ethernet packet.
ethernetif_init
Calls low_level_init to initialize the Ethernet peripheral and network
interface structure (netif).
ethernet_inputCalls low_level_input to receive a packet and provide it to the LwIP stack.
In case of an RTOS implementation, an additional file is used (sys_arch.c). This file
implements an emulation layer for the RTOS services (message passing through RTOS
mailbox, semaphores,etc.). This file should be tailored according to the current RTOS, which
is FreeRTOS in this package.
12/47Doc ID 022105 Rev 1
AN3966STM32F4x7 low level driver overview
3 STM32F4x7 low level driver overview
The STM32F4x7 Ethernet low level driver is located in the
\Libraries\STM32F4x7_ETH_Driver\ folder.
The set of functions provided in the driver can be divided into the following categories:
Ta bl e 1 5 provides a summary of the Global Ethernet MAC/DMA functions used for the
configuration of the media access control (MAC) and direct memory access (DMA) features.
Table 7.Global Ethernet MAC/DMA functions
FunctionDescription
ETH_DeInitResets the Ethernet peripheral.
ETH_StructInitFills a configuration structure for an Ethernet peripheral with the
default config (see below).
ETH_InitInitializes the Ethernet peripheral (MAC/DMA) registers with the
required configuration.
ETH_StartStarts the Ethernet MAC/DMA operation.
ETH_MACTransmissionCmdEnables or disables MAC transmission.
ETH_MACReceptionCmdEnables or disables MAC reception.
ETH_GetFlowControlBusyStatusChecks flow control Busy flag.
ETH_InitiatePauseControlFrameInitiates a Pause frame (full-duplex only).
ETH_BackPressureActivationCmdEnables or disables Back pressure mechanism (half duplex mode).
ETH_GetMACFlagStatusGets MAC flags status.
ETH_GetMACITStatusGets MAC interrupts status.
ETH_MACITConfigConfigures MAC interrupts.
ETH_MACAddressConfigConfigures a MAC address.
ETH_GetMACAddressGets configured MAC address.
ETH_MACAddressPerfectFilterCmdEnables or disables MAC perfect filtering for a selected MAC
address.
ETH_MACAddressFilterConfigConfigures the MAC address filtering mode.
ETH_MACAddressMaskBytesFilterConf
ig
Selects MAC address bytes on which filtering will be performed.
Doc ID 022105 Rev 113/47
STM32F4x7 low level driver overviewAN3966
3.1.1 Ethernet MAC/DMA configuration parameters
The configuration structure for an Ethernet MAC/DMA is ETH_InitTypeDef.This
structure is composed of the following MAC and DMA configuration parameters.
Table 8.MAC configuration parameters of an ETH_InitTypeDef structure
ParameterDescriptionDefault value*
ETH_AutoNegotiationEnables PHY Auto-Negotiation.
ETH_AutoNegotiation_Ena
ble
Enables or disables Watchdog timer during
frame reception.
ETH_Watchdog
– When enabled, the MAC allows no more than
2048 bytes to be received.
ETH_Watchdog_Enable
– When disabled, the MAC can receive up to
16384 bytes.
– When enabled, the MAC allows no more than
ETH_Jabber
2048 bytes to be sent.
– When disabled, the MAC can send up to 16384
ETH_Jabber_Enable
bytes.
ETH_InterFrameGap
Selects the minimum IFG between frames during
transmission.
ETH_InterFrameGap_96Bit
ETH_CarrierSenseEnables the Carrier Sense.ETH_CarrierSense_Enable
ETH_SpeedSets the Ethernet speed: 10/100 MbpsETH_Speed_100M
Enables the ReceiveOwn.
ETH_ReceiveOwn
ReceiveOwn enables the reception of frames
when the TX_EN signal is asserted in Half-
ETH_ReceiveOwn_Enable
Duplex mode.
ETH_LoopbackModeEnables the internal MAC MII Loopback mode.
ETH_Mode
Selects the MAC duplex mode: Half-Duplex or
Full-Duplex mode
Enables the IPv4 checksum checking for
ETH_ChecksumOffload
received frame payloads for TCP/UDP/ICMP
packets.
ETH_RetryTransmission
Enables the MAC attempt retries transmission
when a collision occurs (Half-Duplex mode).
ETH_LoopbackMode_Disabl
e
ETH_Mode_FullDuplex
ETH_ChecksumOffload_Dis
able
ETH_RetryTransmission_E
nable
ETH_AutomaticPadCRCStri
p
Enables the Automatic MAC Pad/CRC Stripping.
ETH_AutomaticPadCRCStri
p_Disable
ETH_BackOffLimitSelects the BackOff limit value.ETH_BackOffLimit_10
ETH_DeferralCheck
ETH_ReceiveAll
Enables the deferral check function (Half-Duplex
mode).
Enables the reception of all frames by the MAC
(No filtering).