首先弄两个关于memp感觉比较好的链接:
(1)LWIP使用经验(作者RimeLink)
(2)
《LwIP协议栈源码详解——TCP/IP协议的实现》动态内存管理
(作者老衲五木)
(3)LWIP协议栈源码详解PDF版的第4章PBUF的释放的最后部分有讲解MEMP初始化。
稍微总结一下:
(1)memp.C相比mem.c而言比较简单一点(但是不见得很简单,即便是adam也犯了不少错误,老衲在他的新浪博客指出来的,不过不是memp和mem相关的bug)。
(2)memp_init/memp_malloc/memp_free,在memp.C总共就这三个函数。
memp_init里面弄个单向链表。引用LWIP使用经验(作者RimeLink)这里的一个图,如下:
为了说的更清晰一点,举个例子说明一下,图如下:
这个例子中:
编译代码后,如下----------------------------------------
有3种type分别为type0 type1 type2,
typedef enum {
type0=0
type1=1
type2=2
MEMP_MAX
} memp_t;
MEMP_MAX=3
static uint8_tmemp_memory[32] = {0};
const uint16_t memp_num[MEMP_MAX] = {3,3,2};
const uint16_t memp_sizes[MEMP_MAX] = {4,4,4};
struct memp*memp_tab[MEMP_MAX];
运行函数memp_init后,如下--------------------------------
memp_tab[0]=0x20000008
memp_tab[1]=0x20000014
memp_tab[2]=0x2000001C
运行memp_malloc(type0)后,如下---------------
memp_tab[0]=0x20000004
memp_tab[1]=0x20000014
memp_tab[2]=0x2000001C
------------------------------------------------------------
************************************************************************************************
在memp_std.h中,比如针对udp,如下
#if LWIP_UDP
LWIP_MEMPOOL(UDP_PCB, MEMP_NUM_UDP_PCB, sizeof(struct udp_pcb), "UDP_PCB")
#endif /* LWIP_UDP */
在lwipopts.h里面有,如下
/* MEMP_NUM_UDP_PCB:the number of UDP protocol control blocks. One
per active UDP "connection". */
#defineMEMP_NUM_UDP_PCB 6
经验证如果调用的udp_new的次数小于等于6则运行正常,
那么如果超过了6个会如何呢?
写程序试验一下,在ST官网例子里面
struct udp_pcb*upcb_Snd = NULL;
voidudp_echoserver_init(void)
{
err_t err;
/* Create a new UDP control block */
upcb_Snd = udp_new();
upcb_Snd = udp_new();
upcb_Snd = udp_new();
upcb_Snd = udp_new();
upcb_Snd = udp_new();
upcb_Snd = udp_new();
upcb_Snd = udp_new();//第7个
if (upcb_Snd)
{
/* Bind the upcb to the UDP_PORT port */
/* Using IP_ADDR_ANY allow the upcb to beused by any local interface */
err = udp_bind(upcb_Snd, IP_ADDR_ANY,UDP_SERVER_PORT);
if(err == ERR_OK)
{
/* Set a receive callback for the upcb*/
udp_recv(upcb_Snd,udp_echoserver_receive_callback, NULL);
}
else
{
udp_remove(upcb_Snd);
printf("can not bind pcb");
}
}
else
{
printf("can not create pcb");
}
}
然后打开memp的调试宏定义,即 #define MEMP_DEBUG LWIP_DBG_ON
于是串口打印如下:
memp_malloc: out ofmemory in pool UDP_PCB
can not create pcb
************************************************************************************************************
另外在memp_std.h里面,我目前观察有两种宏定义,
一种是LWIP_MEMPOOL,这种是可选的,比如可以让LWIP_RAW设置为0,让raw_pcb不参与编译。如下:
#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 */
另一种是LWIP_PBUF_MEMPOOL,并且这种是强制性的,就是必须存在的。如下
/*
* A list of pools of pbuf's used by LWIP.
*
* LWIP_PBUF_MEMPOOL(pool_name, number_elements, pbuf_payload_size, pool_description)
* creates a pool name MEMP_pool_name. description is used in stats.c
* This allocates enough space for the pbuf struct and a payload.
* (Example: pbuf_payload_size=0 allocates only size for the struct)
*/
LWIP_PBUF_MEMPOOL(PBUF, MEMP_NUM_PBUF, 0, "PBUF_REF/ROM")
LWIP_PBUF_MEMPOOL(PBUF_POOL, PBUF_POOL_SIZE, PBUF_POOL_BUFSIZE, "PBUF_POOL"