TCP/IP Communication Protocol (2) – LwIP Memory Management

TCP/IP Communication Protocol (2) - LwIP Memory ManagementTCP/IP Communication Protocol (2) - LwIP Memory Management

5. LwIP Memory Management

1. What is Memory Management?

(1) Memory management refers to the techniques used for the allocation and utilization of computer memory resources during software execution. Its main purpose is to efficiently and quickly allocate memory and to release and reclaim memory resources at appropriate times (similar to the malloc and free functions in C language).

Memory Allocation: Large arrays, returning memory addresses upon completion.

Memory Release: Passing the memory address to the algorithm for release.

(2) LwIP Memory Management Strategies:

1. Memory Heap: Provides appropriately sized memory, returning the remaining memory to the heap.

2. Memory Pool: Only allows allocation of fixed-size memory, effectively preventing memory fragmentation.

3. C Library: The memory allocation strategy provided by the C runtime library (not recommended for use).

The LwIP memory pool and memory heap essentially operate directly on arrays.

(3) Applications of LwIP Memory Heap and Memory Pool

  • Receiving Data: MAC kernel array [both memory heap and memory pool can be used; the version used by ZC is the memory pool].

  • Sending Data: Users call LwIP API interfaces [LwIP generally uses the memory heap for memory allocation].

  • User Calls: Users can call LwIP memory pool and memory heap API interfaces to request memory.

  • Interface Control Blocks: netconn, socket, raw interfaces.

  • Building Messages: API messages, packet messages.

2. Introduction to LwIP Memory Heap

The LwIP memory heap is a variable-length allocation strategy that allows for the allocation of memory of any size. The LwIP memory heap uses the First Fit memory algorithm.

(1) First Fit Algorithm

Searches from low address space to high address space, cutting into appropriate blocks and returning the remaining part to the dynamic memory heap.

Advantages:

  • Minimal memory waste, relatively simple, suitable for small memory management.

  • Ensures sufficient memory in high address space.

  • Requires allocation of minimum values and merging of adjacent space blocks, effectively preventing memory fragmentation.

Disadvantages:

  • Frequent allocation and release can cause memory fragmentation.

  • Searching from low addresses during allocation and release can lead to inefficiency.

3. Analysis of LwIP Memory Heap Principles

TCP/IP Communication Protocol (2) - LwIP Memory Management

By opening up a memory heap, the memory allocation strategy simulates the IC runtime library to implement [large arrays].

(1) Structure for Managing Memory Blocks:

As shown in the following source code:

TCP/IP Communication Protocol (2) - LwIP Memory Management

(2) Minimum Memory Allocation

TCP/IP Communication Protocol (2) - LwIP Memory Management

To prevent memory fragmentation, the LwIP kernel defines a minimum allocation size, MIN_SIZE. When the memory requested by the user is less than the minimum allocation size, the system will allocate memory of size MIN_SIZE.

(3) Alignment Definition

TCP/IP Communication Protocol (2) - LwIP Memory Management

The SIZEOF_STRUCT_MEM macro is defined to ensure that memory sizes are aligned to 4 bytes, which not only greatly improves CPU access speed but also because certain hardware platforms can only fetch specific types of data from specific addresses.

(4) Defining Memory Heap Space

TCP/IP Communication Protocol (2) - LwIP Memory Management

Both the memory pool and memory heap operate on a large array. This large array is referred to as the ram_heap array, and its size is often defined as MEM_SIZE_ALIGNED + (2U * SIZEOF_STRUCT_MEM). This allows users to allocate memory of the appropriate size from this large array, reducing memory fragmentation.

(5) Operating Memory Heap Variables

TCP/IP Communication Protocol (2) - LwIP Memory Management

The LwIP kernel uses three pointers: ram pointer, ram_end pointer, and lfree pointer.

The ram pointer points to the starting address of the aligned total space of the ram_heap array.

The ram_end pointer points to the end address of the total space of the ram_heap array (close to the end of the total space).

The lfree pointer points to the lowest memory address of the free memory block in the ram_heap array.

During memory allocation, LwIP allocates memory based on the free memory pointed to by the lfree pointer, quickly finding available memory blocks and effectively allocating memory to the required tasks. The ram_end pointer is used to check if there is free memory in the total memory heap space for further memory allocation.

(6) Memory Initialization mem_init():

The following diagram shows the initialization of the heap space. After initialization, the lfree pointer points to the first memory block, which consists of a control block and available memory, while the ram_end pointer points to the end of the heap space to determine if there is available memory. If the lfree pointer points to the ram_end pointer, it indicates that there is no available memory for allocation in this heap space.

Control Block: Marks whether the memory is available.

Available Memory: The actual allocatable memory area.

TCP/IP Communication Protocol (2) - LwIP Memory Management

During the memory allocation process, the lfree pointer starts searching and partitioning memory from the low address until it reaches the address pointed to by the ram_end pointer. This means that the lfree pointer starts from the beginning of the heap space, traversing memory blocks one by one until it finds available memory or reaches the end of the heap space.

TCP/IP Communication Protocol (2) - LwIP Memory Management

(7) mem_malloc():

  1. void *mem_malloc(mem_size_t size_in){

  2. mem_size_t ptr, ptr2, size;

  3. struct mem *mem, *mem2;

  4. /******* First: Check if the user-requested memory block meets LWIP’s rules *******/

  5. /******* Second: Allocate the user’s memory block from the memory heap******/

  6. /* Find a sufficiently large free block, starting from the lowest free block.*/

  7. for (ptr = mem_to_ptr(lfree); ptr < MEM_SIZE_ALIGNED – size;ptr = ((struct mem *)(void*)&ram[ptr])->next)

  8. {

  9. mem = ptr_to_mem(ptr); /* Get its address */

  10. /* The space size must exclude the size of the memory block header */

  11. if ((!mem->used) &&

  12. (mem->next – (ptr + SIZEOF_STRUCT_MEM)) >= size) {

  13. /* Here we need to check if the remaining memory block can allocate the size memory block */

  14. if (mem->next – (ptr + SIZEOF_STRUCT_MEM) >= (size +SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED))

  15. {

  16. /* The above comments mainly indicate that the remaining memory may not even be able to hold a memory block header, in which case a new empty memory block cannot be created. Its index cannot be moved. */

  17. /* Point to the position after allocation, i.e., establish the header of the next unused memory block. That is, insert a new empty memory block */

  18. ptr2 = (mem_size_t)(ptr + SIZEOF_STRUCT_MEM + size);

  19. /* Create the mem2 structure starting from the Ptr2 address */

  20. mem2 = ptr_to_mem (ptr2);/* Call (struct mem *)(void *)&ram[ptr]; */

  21. mem2->used = 0;

  22. /* This is determined by the following if(mem2->next != MEM_SIZE_ALIGNED) */

  23. mem2->next = mem->next;

  24. mem2->prev = ptr; /* The previous free memory block points to the above allocated memory block */

  25. /* The previous memory block points to the newly established free memory block */

  26. mem->next = ptr2;

  27. mem->used = 1;/* Mark the currently allocated memory block as used */

  28. /* If the next memory block of mem2 is not the last memory block in the linked list (end address), then point its next memory block’s previous to mem2 */

  29. if (mem2->next != MEM_SIZE_ALIGNED)

  30. {

  31. ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2;

  32. }

  33. }

  34. else {

  35. /* Memory block too small will cause fragmentation */

  36. mem->used = 1;

  37. }

  38. /* Here we handle: when the allocated memory is exactly lfree, because this memory block has been allocated, we must modify lfree to point to the next previously released memory block */

  39. if (mem == lfree)

  40. {

  41. struct mem *cur = lfree;

  42. /* As long as the memory block is used and not at the end, continue searching */

  43. while (cur->used && cur != ram_end)

  44. {

  45. cur = ptr_to_mem(cur->next);/* Next memory block */

  46. }

  47. /* Point to the first released memory block found. If none is found above, lfree remains unchanged */

  48. lfree = cur;

  49. }

  50. /* Here return the address of the memory block space, excluding the memory block header */

  51. return (u8_t *)mem + SIZEOF_STRUCT_MEM + MEM_SANITY_OFFSET;

  52. }

  53. }

  54. return NULL;

  55. }

  56. }

4. Introduction to LwIP Memory Pool

(1) What is a Memory Pool?

The LwIP memory pool divides a contiguous memory pool into multiple equal-sized memory spaces, connected via a singly linked list. When a user requests memory, the system takes a memory block from the head of the singly linked list for allocation, and when releasing memory, it simply places the memory block back at the head of the list.

TCP/IP Communication Protocol (2) - LwIP Memory ManagementTCP/IP Communication Protocol (2) - LwIP Memory Management

Advantages of LwIP Memory Pool:

Fast allocation speed, prevents memory fragmentation, and easy recovery.

Disadvantages of LwIP Memory Pool:

Resource waste; when requesting large memory, it may fail.

Application Scenarios of LwIP Memory Pool:

In LwIP, there are various fixed-size data structures, characterized by known sizes that remain constant throughout their lifecycle. For example, when establishing a TCP connection, a TCP control block data structure is required, which has a fixed size. To meet the memory allocation needs of these data structures, LwIP creates a dynamic memory pool, POOL, during memory initialization, pre-allocating a certain number of memory blocks. This memory management approach helps improve the efficiency and performance of memory allocation.

(2) Files Implementing LwIP Memory Pool

For the dynamic memory pool in the memory heap, many complex macro definitions are utilized. Therefore, we will focus on these four key files: memp.c, memp.h, memp_std.h, and memp_priv.h.

i. memp_priv.h File

Defines the memp (linked memory blocks) and memp_desc (managing linked memory blocks) structures.

The memp structure connects memory pools of the same type in a linked list format.

The memp_desc structure is used to manage and describe various types of memory pools, including quantity, size, starting address of the memory pool, and pointers to free memory pools.

TCP/IP Communication Protocol (2) - LwIP Memory Management

The relationship between the memp structure and the memp_desc structure:

TCP/IP Communication Protocol (2) - LwIP Memory Management

As can be seen from the diagram: each memp_desc structure is used to manage a memory pool of the same type. These memory pools, or memory blocks, are interconnected in a linked list format.

ii. memp_std.h File

This file is the core definition of the LwIP memory pool, allocating the required memory pools. It uses macro definitions to determine whether to enable specific types of memory pools, such as TCP, UDP, DHCP, ICMP, etc.

TCP/IP Communication Protocol (2) - LwIP Memory Management

From the above code, it can be seen that different types of memory pools are enabled through corresponding macro definitions. The LWIP_MEMPOOL macro is used to initialize various types of memory pools.

iii. memp.h File

This file mainly defines the memp_t enumeration type, which is used to obtain the number of various memory pools, declaring macros and functions for external file use. Here, the previously mentioned LWIP_MEMPOOL macro is defined.

TCP/IP Communication Protocol (2) - LwIP Memory Management

According to the memory pool types enabled in the memp_std.h file, MEMP_MAX is calculated, which is the maximum number of various memory pools. The calculation method is as follows:

1. The LWIP_MEMPOOL macro points to MEMP_##name (## is the concatenation operator in C language).

2. By including the “lwip/priv/memp_std.h” file to enable the required memory pool types.

iv. memp.c File

In memp.h, we mentioned that LWIP_MEMPOOL points to the LWIP_MEMPOOL_DECLARE macro, while the const memp_pools[MEMP_MAX] array in the memp.c file is used to manage the descriptors of various memory pools.

TCP/IP Communication Protocol (2) - LwIP Memory Management

When the memp_std.h file only enables LWIP_RAW and LWIP_UDP types of memory pools, the expanded enumeration type is as follows:

TCP/IP Communication Protocol (2) - LwIP Memory Management

This code uses the LWIP_MEMPOOL_DECLARE macro to declare the description and management information of various memory pools. Specifically, it defines the memp_desc structure, for example:

memp_RAW_PCB: Used to describe the number, size, allocation memory address, and pointer to the free memory pool of this type of memory pool.

TCP/IP Communication Protocol (2) - LwIP Memory Management

memp_pools[MEMP_RAW_PCB], which takes the address of the memp_RAW_PCB variable. This is the variable we defined when we expanded the LWIP_MEMPOOL_DECLARE macro earlier.

v. memp_init function and memp_init_pool function

This function initializes the memory pool.

TCP/IP Communication Protocol (2) - LwIP Memory Management

Each type of descriptor is used to manage and describe that type of memory pool. These memory pools of the same type are internally linked together through pointers to the next node, forming a linked list. Through the second for loop statement, we can traverse these same type memory pools and link them in a linked list format.

TCP/IP Communication Protocol (2) - LwIP Memory Management

The memp_pool array contains descriptors for different types of memory pools, with each descriptor responsible for managing memory pools of the same type. These memory pools are linked into a singly linked list via pointers, facilitating management and access. Memory pools of the same type are allocated in the same array, and the base pointer can be used to find the starting address of that array. The tab pointer points to the first free memory pool, and when a user requests a memory pool, it will be allocated from the memory pool pointed to by the tab pointer. After allocation, the tab pointer will offset to the address of the next free memory pool for the next allocation.

vi. memp_malloc function and memp_malloc_pool function

Memory pools come in various types, so users need to clearly specify the type of memory pool they are requesting. The lwIP memory pool allocation function is memp_malloc.

TCP/IP Communication Protocol (2) - LwIP Memory Management

The memp_malloc function searches for the corresponding memory pool descriptor in the memp_pool array based on the memory pool type passed by the user, such as UDP_PCB. Once the corresponding descriptor is found, the function allocates memory for the user based on the tab pointer in the descriptor and offsets the tab pointer to the next free memory pool.

TCP/IP Communication Protocol (2) - LwIP Memory Management

vii. memp_free function and memp_free_pool function

The memory pool release function is relatively simple; it requires two parameters: the type of memory pool and the address of the memory pool to be released. With these two parameters, the lwIP kernel can determine the location of the memory pool descriptor of that type and the specific location of the memory pool to be released.

TCP/IP Communication Protocol (2) - LwIP Memory Management

The release function is straightforward; it simply offsets the tab pointer of the memory pool descriptor to the memory pool to be released. This way, the released memory block will be returned to the corresponding memory pool for subsequent use.

TCP/IP Communication Protocol (2) - LwIP Memory Management

Disclaimer: We respect originality and emphasize sharing; the text and images are copyrighted by the original authors. The purpose of reprinting is to share more information and does not represent the position of this account. If your rights are infringed, please contact us promptly, and we will delete it as soon as possible. Thank you!

Original link:

https://blog.csdn.net/m0_73409202/article/details/142637820

Leave a Comment