LwIP之动态内存池
生活随笔
收集整理的這篇文章主要介紹了
LwIP之动态内存池
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
先看memp_t,這是一個枚舉體,定義了所有內存池的類型。
typedef enum { #define LWIP_MEMPOOL(name,num,size,desc) MEMP_##name, #include "lwip/memp_std.h"MEMP_MAX } memp_t;枚舉體包含了一個頭文件,對頭文件進行展開
typedef enum { #define LWIP_MEMPOOL(name,num,size,desc) MEMP_##name,......#if LWIP_RAW LWIP_MEMPOOL(RAW_PCB, MEMP_NUM_RAW_PCB, sizeof(struct raw_pcb), "RAW_PCB") #endif#if LWIP_UDP LWIP_MEMPOOL(UDP_PCB, MEMP_NUM_UDP_PCB, sizeof(struct udp_pcb), "UDP_PCB") #endif#if LWIP_TCP LWIP_MEMPOOL(TCP_PCB, MEMP_NUM_TCP_PCB, sizeof(struct tcp_pcb), "TCP_PCB") LWIP_MEMPOOL(TCP_PCB_LISTEN, MEMP_NUM_TCP_PCB_LISTEN, sizeof(struct tcp_pcb_listen), "TCP_PCB_LISTEN") LWIP_MEMPOOL(TCP_SEG, MEMP_NUM_TCP_SEG, sizeof(struct tcp_seg), "TCP_SEG") #endif......#undef LWIP_MEMPOOL......MEMP_MAX } memp_t;進一步,對宏LWIP_MEMPOOL進行展開,最終得到memp_t類型如下
typedef enum {MEMP_RAW_PCB,MEMP_UDP_PCB,MEMP_TCP_PCB,MEMP_TCP_PCB_LISTEN,MEMP_TCP_SEG,......MEMP_MAX } memp_t;按照上面的原理,編譯的時候,會建立起來幾個全局變量
/* 各個內存池單元大小 */ const u16_t memp_sizes[MEMP_MAX] = { #define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEM_ALIGN_SIZE(size), #include "lwip/memp_std.h" }; 展開后 const u16_t memp_sizes[MEMP_MAX] = {LWIP_MEM_ALIGN_SIZE(sizeof(struct raw_pcb)),LWIP_MEM_ALIGN_SIZE(sizeof(struct udp_pcb)),LWIP_MEM_ALIGN_SIZE(sizeof(struct tcp_pcb)),LWIP_MEM_ALIGN_SIZE(sizeof(struct tcp_pcb_listen)),LWIP_MEM_ALIGN_SIZE(sizeof(struct tcp_seg)),... }; /* 各個內存池單元個數數組 */ static const u16_t memp_num[MEMP_MAX] = { #define LWIP_MEMPOOL(name,num,size,desc) (num), #include "lwip/memp_std.h" }; 展開后 static const u16_t memp_num[MEMP_MAX] = {MEMP_NUM_RAW_PCB,MEMP_NUM_UDP_PCB,MEMP_NUM_TCP_PCB,MEMP_NUM_TCP_PCB_LISTEN,MEMP_NUM_TCP_SEG,... }; /* 所有內存池空間 */ static u8_t memp_memory[MEM_ALIGNMENT - 1 #define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) ) #include "lwip/memp_std.h" ]; 展開后 static u8_t memp_memory[MEM_ALIGNMENT - 1 + (MEMP_NUM_RAW_PCB) * (MEMP_SIZE + MEMP_ALIGN_SIZE(sizeof(struct raw_pcb)))+ (MEMP_NUM_UDP_PCB) * (MEMP_SIZE + MEMP_ALIGN_SIZE(sizeof(struct udp_pcb)))+ (MEMP_NUM_TCP_PCB) * (MEMP_SIZE + MEMP_ALIGN_SIZE(sizeof(struct tcp_pcb)))+ (MEMP_NUM_TCP_PCB_LISTEN) * (MEMP_SIZE + MEMP_ALIGN_SIZE(sizeof(struct tcp_pcb_listen)))+ (MEMP_NUM_TCP_SEG) * (MEMP_SIZE + MEMP_ALIGN_SIZE(sizeof(struct tcp_seg))) ];接下來再看一個結構體,這個結構體用于將內存池單元連接成鏈表
/* 內存池單元結構體 */ struct memp {struct memp *next; };而下面這個數組用于指向各個內存池鏈表中的第一個空閑單元
static struct memp *memp_tab[MEMP_MAX];?
接下來看一下內存池相關的API
/* 初始化內存池 */ void memp_init(void) {struct memp *memp;u16_t i, j;/* 內存池所在內存地址 */memp = LWIP_MEM_ALIGN(memp_memory);/* 將內存分割成各個內存池 */for (i = 0; i < MEMP_MAX; ++i) {/* 將各個內存池單元連接成鏈表 */memp_tab[i] = NULL;for (j = 0; j < memp_num[i]; ++j) {memp->next = memp_tab[i];memp_tab[i] = memp;memp = (struct memp *)((u8_t *)memp + MEMP_SIZE + memp_sizes[i]);}} }初始化完成之后,內存池空間被組織成如下結構?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
/* 申請一個內存池單元 */ void *memp_malloc(memp_t type) {struct memp *memp;/* 內存池空閑單元指針 */memp = memp_tab[type];/* 鏈表頭部取出一個單元 */if (memp != NULL) {memp_tab[type] = memp->next;memp = (struct memp *)((u8_t *)memp + MEMP_SIZE);}/* 返回內存地址 */return memp; } /* 釋放一個內存池單元 */ void memp_free(memp_t type, void *mem) {struct memp *memp;if (mem == NULL) {return;}/* 將內存地址轉換為內存池單元指針 */memp = (struct memp *)((u8_t*)mem - MEMP_SIZE);/* 將內存池單元插入相應鏈表頭部 */memp->next = memp_tab[type]; memp_tab[type] = memp; }?
總結
以上是生活随笔為你收集整理的LwIP之动态内存池的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 三相电路
- 下一篇: uboot启动第二阶段——start_a