TCP/IP Stack Network Buffers Allocation Schemes
and their implication on simplicity, CPU load, and throughput performance
Network Data Buffers
Data being sent to the network or received from the network is placed in
network buffers. Network buffer descriptors hold information about network
buffers. The descriptors are pre-allocated, whereas the network buffers
themselves are allocated as they are needed.
The total number of descriptors is set by the
constant in FreeRTOSIPConfig.h. Pre-allocating the descriptors allows
the application writer to limit the maximum number of network buffers
that can exist at any one time in order to prevent memory exhaustion.
Different buffer allocation schemes suite different embedded applications,
so FreeRTOS+TCP keeps the buffer allocation schemes as part of the TCP/IP
stack's portable layer. At the time of writing, two example buffer
allocation schemes are provided - each with different trade offs between
simplicity, RAM usage efficiency, and performance. The two schemes are
described on this page.
The C source files that implement the buffer allocation schemes are located
in the FreeRTOS-Plus/FreeRTOS_Plus_TCP/portable/BufferManagement
directory. Only one scheme can be used at a time.
Buffer Allocation Schemes
Scheme 1: Implemented by BufferAllocation_1.c
Ethernet buffers are statically allocated by the
embedded Ethernet peripheral driver (at compile time).
This ensures the buffers can be aligned as required
by the specific Ethernet hardware.
BufferAllocation_1.c calls vNetworkInterfaceAllocateRAMToBuffers(),
which must be provided by the peripheral driver.
Information detailing the requirements of this function
are provided in the
Functions That Must Be Provided By The Port Layer
section of the Embedded Ethernet Driver Porting
Fast run time performance.
Ethernet buffers can be allocated and freed from
interrupts, allowing for more efficient embedded
Ethernet peripheral drivers.
Inefficient use of RAM - all the buffers are the
same size making BufferAllocation_1.c unsuitable for
some RAM constrained embedded systems.
More complex to configure and tune than the scheme
implemented by BufferAllocation_2.
Simpler to achieve any special buffer alignment
requirements imposed by the embedded Ethernet
Requires support from the network interface driver
(see the description bullet points above).
defines both the total number of descriptors and the
total number of buffers.
The ipconfigNETWORK_MTU constant (defined
defines the size of each Ethernet buffer (the total
size being the defined MTU size plus the number of
bytes needed by the Ethernet header).
Scheme 2: Implemented by BufferAllocation_2.c
Ethernet buffers of exactly the required size are
dynamically allocated and freed as required. This
requires a fast memory allocation scheme that does not
suffer from fragmentation - at the time or writing it
is recommended that heap_4.c or heap_5.c
Extremely easy to use.
Dynamic allocation results in slower run time
performance when compared with the scheme implemented
Ethernet buffers cannot be allocated and freed from
interrupts, necessitating the use of deferred interrupt
handling tasks in embedded Ethernet peripheral
Very efficient RAM usage - only the exact amount of
RAM required is allocated making BufferAllocation_2.c
particularly suited for RAM constrained small embedded
Ethernet buffers are allocated from the
FreeRTOS heap. To avoid
memory fragmentation problems, BufferAllocation_2.c
can only be used reliably with a memory allocation
scheme that combines adjacent free blocks of heap memory
(a coalescence algorithm). The FreeRTOS memory allocation
schemes implemented in heap_4.c and heap_5.c are suitable.
The TCP/IP stack will recover from a failed attempt
to allocate a network buffer, however, as the standard
heap implementation is used such a failure will result
in the malloc failed hook being called (if
configUSE_MALLOC_FAILED_HOOK is set to 1 in