FreeRTOS+UDP was removed from the FreeRTOS kernel download from FreeRTOS V10.1.0. See the FreeRTOS+TCP stack, which can be configured for UDP only use, as an alternative. |
![]() |
Porting FreeRTOS+UDP to a Different Microcontroller
Summary Bullet Points

stack and the embedded Ethernet hardware drivers
-
Only the network input and output functions are hardware dependent.
The effort in porting the IP stack is therefore limited to the
implementation of a network interface.
-
The network interface interfaces the IP stack to the embedded Ethernet
peripheral drivers. This page assumes Ethernet peripheral drivers
already exist, and are known to work.
-
FreeRTOS+UDP expects the network interface port layer to provide two
functions, one to initialise the Ethernet hardware, and another
to send data to the network.
-
FreeRTOS+UDP provides the network interface port layer with a
software interface that allows the network interface
to obtain Ethernet buffers to store raw Ethernet frames, and to
obtain network buffer descriptors that reference, and provide information
about, an Ethernet buffer.
-
Data received from the network is sent into the IP stack by the
network interface port layer on a standard
RTOS queue.
- A simple network interface can can be implemented with little or no modification to the Ethernet MAC peripheral drivers. A more efficient network interface can be implemented by modifying the Ethernet MAC peripheral drivers to enable Ethernet buffers to be passed into and out of the IP stack by reference (with no copying of data from one buffer to another).
On this page (intended to be read in order):
- Network buffer descriptors and Ethernet buffers
- Functions that must be implemented in the network interface port layer
- Interface functions provided by the IP stack
- Creating a simple network interface port layer
- Creating an efficient zero copy network interface port layer
Network Buffer Descriptors and Ethernet Buffers
Network buffer descriptors are structures typedef’ed to variables of type xNetworkBufferDescriptor_t. Most of the xNetworkBufferDescriptor_t structure members are for internal use by the IP stack, and must not be modified. Two structure members that can legitimately be modified by the network interface port layer are shown in the code snippet below:
|

The pucEthernetBuffer member points to the start of the Ethernet buffer.
The xDataLength member is set to the size of the Ethernet frame (excluding the CRC bytes).
Functions That Must Be Implemented By The Network Interface
The network interface must implement the following three functions (example implementations for both simple and zero copy implementations are provided on this page):
-
A function called xNetworkInterfaceInitialise()
xNetworkInterfaceInitialise() is responsible for initialising the Ethernet (or other network) hardware. Typically xNetworkInterfaceInitialise() will make calls into the Ethernet MAC peripheral driver library to configure the Ethernet interface, initialise DMA descriptors, and request the PHY auto-negotiates a network link.
xNetworkInterfaceInitialise() does not take any parameters, returns pdPASS if the initialisation was successful, and returns pdFAIL if the initialisation fails.
BaseType_t xNetworkInterfaceInitialise( void );
The xNetworkInterfaceInitialise() function prototype
-
A function called xNetworkInterfaceOutput()
xNetworkInterfaceOutput() is responsible for transmitting the data generated by the IP stack.
xNetworkInterfaceOutput() takes a pointer to a network buffer descriptor as a parameter, returns pdPASS if the Ethernet frame referenced by the network buffer descriptor was successfully sent to the network, and returns pdFAIL if the Ethernet frame referenced by the network buffer descriptor was not successfully sent to the network.
BaseType_t xNetworkInterfaceOutput
( xNetworkBufferDescriptor_t * const pxNetworkBuffer );
The xNetworkInterfaceOutput() function prototype
-
A function that sends received data to the IP stack
A network buffer descriptor must be allocated to reference Ethernet frames that have been filled by the Ethernet MAC hardware. The completed network buffer descriptors must then be posted to an RTOS queue for processing by the UDP/IP stack. Outline examples are provided on this page for reference. Complete examples can be found in the FreeRTOS+UDP distribution.
Interface Functions Provided by the IP Stack
The IP stack allows the creation of simple (as opposed to zero copy) network interface port layers by providing the following functions:- pxNetworkBufferGet()
- vNetworkBufferRelease()
- pxNetworkBufferGetFromISR() [not available when BufferAllocation_2.c is used]
- vNetworkBufferReleaseFromISR() [not available when BufferAllocation_2.c is used]
- eConsiderFrameForProcessing()
In addition to the functions provided to allow the creation of simple network
interfaces, the IP stack provides the following function to allow the creation
of more efficient zero copy network interfaces:
Creating a Simple Network Interface Port Layer
Simple network interfaces can be created by using existing Ethernet MAC driver libraries to copy Ethernet frames between buffers allocated by the IP stack and buffers allocated by the embedded Ethernet peripheral drivers. [A more efficient zero copy alternative is provided after the simple example.]A Simple xNetworkInterfaceInitialise() Implementation
|
A Simple xNetworkInterfaceOutput() Implementation
|
Passing Received Data to the IP Stack
Data that is received from the Ethernet (or other network) driver is placed into an Ethernet buffer, then passed into the IP stack on the network event queue called xNetworkEventQueue.The network event queue is a standard RTOS queue that holds variables of type xIPStackEvent_t.
|
Messages notifying the IP stack of Ethernet receive events have their eEventType member set to eEthernetRxEvent, and their pvData member set to point to the network buffer descriptor that references the received data.
The IP stack receives data without explicitly calling a receive function. The receive handler can therefore have any name and prototype deemed appropriate.
NOTE 1: If BufferAllocation_2.c is used then network buffer descriptors and Ethernet buffers cannot be allocated from inside an interrupt service routine (ISR). In this case the Ethernet MAC receive interrupt can defer the receive processing to a task. The task should be given a high priority relative to other tasks in the system to ensure it runs immediately after the ISR ends (contiguous in time, just as if all the processing had been performed by the interrupt itself). This is called deferred interrupt processing.
NOTE 2: If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1 in FreeRTOSIPConfig.h and the Ethernet hardware is not already filtering irrelevant Ethernet frames then eConsiderFrameForProcessing() can be called to determine if the received Ethernet frame can be safely dropped (rather than sent to the IP stack for processing).
|
Creating an Efficient Zero Copy Network Interface Port Layer
Please ensure to read the information about creating a simple network interface before reading this section.Simple network interfaces copy the data contained in Ethernet frames between buffers allocated by the IP stack and buffers allocated by the Ethernet (or other network) peripheral drivers. Copying the data between buffers in this manner normally allows the Ethernet peripheral driver library to be used with little or no modification. Zero copy network interfaces never copy data from one buffer to another, but instead pass only references to buffers between the peripheral driver library and the IP stack. Creating a zero copy network interface will necessitate edits to most standard Ethernet peripheral driver library implementations.
Most Ethernet MACs transmit data by using a Direct Memory Access (DMA) peripheral to move data from a memory buffer to the Ethernet MAC hardware, and receive data by using a DMA peripheral to move data from the Ethernet MAC hardware into one of a set of pre-allocated memory buffers. Typically the pre-allocated memory buffers will be referenced by a set of chained DMA descriptors (each descriptor points to the next, with the last descriptor pointing back to the first).

A chain of embedded Ethernet peripheral DMA descriptors pointing to pre-allocated DMA buffers
A Zero Copy xNetworkInterfaceInitialise() Implementation
xNetworkInterfaceInitialise() must ensure the buffers referenced by the received DMA descriptors are allocated using pucEthernetBufferGet(). It is not necessary to allocate buffers to the transmit DMA descriptors until data is actually being transmitted.
After initialisation, the Ethernet DMA Rx descriptors reference buffers allocated using pucEthernetBufferGet(),
and the Ethernet DMA Tx descriptors are initialised but don’t yet reference any Ethernet buffers.
A Zero Copy xNetworkInterfaceOutput() Implementation
xNetworkInterfaceOutput() updates an Ethernet DMA Tx descriptor so the descriptor points to the Ethernet buffer being transmitted.NOTE: The Ethernet buffer must be released after the data it contains has been transmitted. If BufferAllocation_2.c is used the Ethernet buffer cannot be released from the Ethernet Transmit End interrupt, so must be release by the xNetworkInterfaceOutput() function the next time the same DMA descriptor is used.
|
Passing Zero Copy Received Data to the IP Stack
If data that is received from the Ethernet (or other network) driver is DMA’ed into an Ethernet buffer then the data is not copied out of the DMA buffer. Instead the Ethernet Rx DMA descriptor that references the received data is updated to point to a new Ethernet buffer, and the Ethernet buffer that contains the data is passed by reference into the IP stack.All the notes regarding the implementation of the simple receive handler apply to the zero copy receive handler and are not repeated here.
|