Red Point

十年饮冰 , 热血难凉 ; 山高万仞 , 只登一步

  博客园 :: 首页 :: 博问 :: 闪存 :: :: :: :: 管理 ::

https://www.codeleading.com/article/85491893264/

 

对于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中,内存池的大小为:

1 static u8_t memp_memory [ MEM_ALIGNMENT - 1
2 #define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) )
3 #include "lwip/memp_std.h"
4 ];

这两段代码存在于lwip的memp.c中。看到这个memp_memory数组,是不是在怀疑自己的眼睛?这到底是不是一个数组呢?定义的数组里竟然还有两个关键字(include和define)?作者这是在干嘛呢?

不过在整理脉络之后,你不得不佩服lwip作者写代码的能力。现在我们就来尝试理解一下这个memp_memory数组。

LWIP_MEMPOOL宏是在数组中定义的,那么在数组中定义的宏和在全局定义的宏有什么不同呢?是作用域不同还是有其他什么差别?

其实,宏定义的作用域是同文件内从定义开始起作用,直到取消定义(undef)为止。那么mem_memroy数组等价于:

1 #define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) )
2 static u8_t memp_memory [ MEM_ALIGNMENT - 1
3 #include "lwip/memp_std.h"
4 ];

这里的 LWIP_MEMPOOL(name,num,size,desc) 定义成了 + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) )

include关键字其实就是把lwip/memp_std.h包含进数组。我们来看看memp_std.h中的部分代码:

 1 #if LWIP_RAW
 2 LWIP_MEMPOOL(RAW_PCB,        MEMP_NUM_RAW_PCB,         sizeof(struct raw_pcb),        "RAW_PCB")
 3 #endif /* LWIP_RAW */
 4  
 5 #if LWIP_UDP
 6 LWIP_MEMPOOL(UDP_PCB,        MEMP_NUM_UDP_PCB,         sizeof(struct udp_pcb),        "UDP_PCB")
 7 #endif /* LWIP_UDP */
 8  
 9 #if LWIP_TCP
10 LWIP_MEMPOOL(TCP_PCB,        MEMP_NUM_TCP_PCB,         sizeof(struct tcp_pcb),        "TCP_PCB")
11 LWIP_MEMPOOL(TCP_PCB_LISTEN, MEMP_NUM_TCP_PCB_LISTEN,  sizeof(struct tcp_pcb_listen), "TCP_PCB_LISTEN")
12 LWIP_MEMPOOL(TCP_SEG,        MEMP_NUM_TCP_SEG,         sizeof(struct tcp_seg),        "TCP_SEG")
13 #endif /* LWIP_TCP */
14  
15 #undef LWIP_MEMPOOL

我们将这段代码用include包含到 memp_memory 数组中,即:

1 #define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) )
2 static u8_t memp_memory [ MEM_ALIGNMENT - 1
3 + (LWIP_MEMPOOL(RAW_PCB, MEMP_NUM_RAW_PCB, sizeof(struct raw_pcb),  "RAW_PCB"))
4 + (LWIP_MEMPOOL(UDP_PCB,  MEMP_NUM_UDP_PCB, sizeof(struct udp_pcb),  "UDP_PCB"))
5 + ...
6 ];
7 #undef LWIP_MEMPOOL

这样就能清晰的看到memp_memory数组的大小了。在mem_memory数组之前用define定义了LWIP_MEMPOOL,在memp_memory数组定义后,用undef取消了LWIP_MEMPOOL的定义。

同理,memp_get_memorysize函数可以展开为

 1 #define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) )
 2 u32_t memp_get_memorysize(void)
 3 {
 4   u32_t length=0;
 5     length=(
 6          MEM_ALIGNMENT-1
 7         + (LWIP_MEMPOOL(RAW_PCB, MEMP_NUM_RAW_PCB,  sizeof(struct raw_pcb), "RAW_PCB"))
 8         + (LWIP_MEMPOOL(UDP_PCB, MEMP_NUM_UDP_PCB,   sizeof(struct udp_pcb), UDP_PCB"))
 9         + ...
10       );
11     return length;
12 }
13 #undef LWIP_MEMPOOL

所以宏定义的作用域是同文件内从定义开始起作用,直到取消定义(undef)为止。可见lwip的作者写代码是多么的牛逼啊~

  1.  
posted on 2023-05-04 16:02  Red_Point  阅读(256)  评论(0)    收藏  举报