对于lwip中内存池的大小,不同的lwip版本定义的方式不一样,但都大同小异。
在lwip_1.4.1中,通过一个static函数获取内存池大小:
u32_t memp_get_memorysize(void)
{
u32_t length=0;
length=(
MEM_ALIGNMENT-1
#define LWIP_MEMPOOL(name,num,size,desc) + ((num)*(MEMP_SIZE+MEMP_ALIGN_SIZE(size)))
#include \"lwip/memp_std.h\"
);
return length;
}
在lwip_2.0中,内存池的大小为:
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"
];
这两段代码存在于lwip的memp.c中。看到这个memp_memory数组,是不是在怀疑自己的眼睛?这到底是不是一个数组呢?定义的数组里竟然还有两个关键字(include和define)?作者这是在干嘛呢?
不过在整理脉络之后,你不得不佩服lwip作者写代码的能力。现在我们就来尝试理解一下这个memp_memory数组。
LWIP_MEMPOOL宏是在数组中定义的,那么在数组中定义的宏和在全局定义的宏有什么不同呢?是作用域不同还是有其他什么差别?
其实,宏定义的作用域是同文件内从定义开始起作用,直到取消定义(undef)为止。那么mem_memroy数组等价于:
#define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) )
static u8_t memp_memory [ MEM_ALIGNMENT - 1
#include "lwip/memp_std.h"
];
这里的 LWIP_MEMPOOL(name,num,size,desc) 定义成了 + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) )
include关键字其实就是把lwip/memp_std.h
包含进数组。我们来看看memp_std.h
中的部分代码:
#if LWIP_RAW
LWIP_MEMPOOL(RAW_PCB, MEMP_NUM_RAW_PCB, sizeof(struct raw_pcb), "RAW_PCB")
#endif /* LWIP_RAW */
#if LWIP_UDP
LWIP_MEMPOOL(UDP_PCB, MEMP_NUM_UDP_PCB, sizeof(struct udp_pcb), "UDP_PCB")
#endif /* LWIP_UDP */
#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 /* LWIP_TCP */
#undef LWIP_MEMPOOL
我们将这段代码用include包含到 memp_memory 数组中,即:
#define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) )
static u8_t memp_memory [ MEM_ALIGNMENT - 1
+ (LWIP_MEMPOOL(RAW_PCB, MEMP_NUM_RAW_PCB, sizeof(struct raw_pcb), "RAW_PCB"))
+ (LWIP_MEMPOOL(UDP_PCB, MEMP_NUM_UDP_PCB, sizeof(struct udp_pcb), "UDP_PCB"))
+ ...
];
#undef LWIP_MEMPOOL
这样就能清晰的看到memp_memory数组的大小了。在mem_memory数组之前用define定义了LWIP_MEMPOOL,在memp_memory数组定义后,用undef取消了LWIP_MEMPOOL的定义。
同理,memp_get_memorysize函数可以展开为:
#define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) )
u32_t memp_get_memorysize(void)
{
u32_t length=0;
length=(
MEM_ALIGNMENT-1
+ (LWIP_MEMPOOL(RAW_PCB, MEMP_NUM_RAW_PCB, sizeof(struct raw_pcb), "RAW_PCB"))
+ (LWIP_MEMPOOL(UDP_PCB, MEMP_NUM_UDP_PCB, sizeof(struct udp_pcb), UDP_PCB"))
+ ...
);
return length;
}
#undef LWIP_MEMPOOL
所以宏定义的作用域是同文件内从定义开始起作用,直到取消定义(undef)为止。可见lwip的作者写代码是多么的牛逼啊~