1 LWIP内存管理知识汇总-德赢Vwin官网 网
0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

LWIP内存管理知识汇总

Q4MP_gh_c472c21 2018-03-06 10:01 次阅读

一LWIP内存管理

LWIP的内存管理使用了2种方式:内存池memp和内存堆mem,如图1所示。

内存池的特点是预先开辟多组固定大小的内存块组织成链表,实现简单,分配和回收速度快,不会产生内存碎片,但是大小固定,并且需要预估算准确。

内存堆的本质是对一个事先定义好的内存块进行合理有效的组织和管理,主要用于任意大小的内存分配,实现较复杂,分配需要查找,回收需要合并,容易产生内存碎片,需要合理估算内存堆的总大小。

图1内存池与内存堆

1. 数据包管理

数据包管理结构pbuf共有四种类型,它们的特点和使用场合如表1所示。

表1 pbuf类型与特点

每一种pbuf分配内存的方式都不一样,如图2所示。

图2四种数据包管理结构

只有选择合适的pbuf类型才能发挥LWIP的最大性能,一个数据包可能是多种pbuf的组合,用链表连接起来,如图3所示。

图3 pbuf链表

2. 设置内存大小

为LWIP开辟一个专用的内存堆是应该的,这样一来LWIP的mem_alloc()和mem_free()都将基于该堆内存进行分配和回收,不影响其他系统内存的使用。如图1左所示,lwipopt.h文件中宏MEM_SIZE定义了堆区的大小,对于一个负荷较重的系统堆区需要分配较大。

图4堆和PBUF_ROM内存区

LWIP使用PBUF_ROM类型的内存池来发送“只读”数据(处于ROM中或者其他进程中不可修改),宏MEMP_NUM_PBUF定义了该缓冲池的个数,如图2右所示。

在ISR(中断服务程序中)经常需要快速分配一部分内存进行数据存储,这是通过PBUF_POOL类型的缓冲区实现的。为此需要定义两个宏:PBUF_POOL_SIZE定义缓冲池的个数,PBUF_POOL_BUFSIZE定义单个缓冲区的大小,如图5所示。

图5PBUF_POOL内存区

3宏编译开关

若定义MEM_LIBC_MALLOC=1,直接使用C库中的malloc、free来分配动态内存;否则使用LWIP自带的mem_malloc、mem_free等函数。

若定义MEMP_MEM_MALLOC=1,则memp.c中的全部内容不会被编译,用内存堆来实现内存池分配,使用这种方式得考虑是否能忍受内存堆分配带来的时间延迟。

若定义MEM_USE_POOLS=1,则mem.c中的全部内容不会被编译,用内存池来实现内存堆的分配,使用这种方式得考虑是否能忍受因为POOL内存固定大小而带来的内存浪费。此外用户需要定义宏MEM_USE_CUSTOM_POOLS=1,还需要额外实现一个头文件lwippools.h,并在其中开辟一些用于内存堆分配函数的内存池POOL,开辟空间的格式如下:

LWIP_MALLOC_MEMPOOL_START

LWIP_MALLOC_MEMPOOL(20, 256)

LWIP_MALLOC_MEMPOOL(10, 512)

LWIP_MALLOC_MEMPOOL_END

二LWIP启动时序

图6展示了LWIP启动时序,大部分函数都是LWIP自带的,主要的移植代码是eth_init()实现初始化以太网接口,启动程序会创建2个线程:tcpip_thread负责LWIP的绝大部分工作(主要是协议栈的解析和系统运行),ethernetif_thread负责从网口接收数据包再交付给tcpip_thread线程进行处理。

图6LWIP启动函数

三LWIP运行逻辑

1接收数据包

图7接收数据包

当以太网口接收到一个数据包后,EMAC_IRQ中断服务程序通过信号量通知ethernetif线程,ethernetif线程调用low_level_input()接收该数据包并通过邮箱交付给tcpip_thread线程,tcpip_thread根据该数据包的类型进行相应处理。它是建立在消息传递的基础上的,如图8所示。

图8数据包消息的产生和处理

2 SequentialAPI函数调用

API设计的核心在于让用户进程负责尽可能多的工作,例如数据的计算、拷贝等;而协议栈进程只负责简单的通信工作,这是很合理的,因为系统可能存在多个应用程序,它们都使用协议栈进程提供的通信服务,保证内核进程的高效性和实时性是提高系统性能的重要保障。进程之间通信使用IPC技术,包括邮箱、信号量和共享内存,如图9所示。

图9协议栈API实现

以函数netconn_bind()为例看API是如何实现的,首先用户程序中调用函数netconn_bind()绑定一个连接,则这个函数实现时,是通过向内核进程发送一个TCPIP_MSG_API类型的消息,告诉内核进程执行do_bind函数:在消息发送后,函数阻塞在信号量上,等待内核处理该消息;内核在处理消息时,会根据消息内容调用do_bind,而do_bind会根据连接的类型调用内核函数udp_bind、tcp_bind或raw_bind;当do_bind执行完后,它会释放信号量,这使被阻塞的netconn_bind得以继续执行,整个过程如图10所示。

图10API函数实现

四TCP/IP核心知识点

1. 滑动窗口

图11滑动窗口

接收窗口相关的字段中,rcv_nxt是自己期望收到的下一个字节编号,rcv_wnd表示接收窗口的大小,rcv_ann_wnd表示将向对方通告的窗口大小值,这个值在报文发送时会被填在首部中的窗口大小字段,rcv_ann_right_edge记录了上一次窗口通告时窗口右边界取值。上面这四个字段都会随着数据的发送和接收动态地改变,如图12所示。

图12接收窗口

发送窗口中,lastack记录了被接收方确认的最高序列号,snd_nxt表示自己将要发送的下一个数据的起始编号,snd_wnd记录了当前的发送窗口大小,它常被设置为接收方通告的接收窗口值,snd_lbb记录了下一个被应用程序缓存的数据的起始编号,如图10所示。

上面这四个字段的值也是动态变化的,每当收到接收方的一个有效ACK后,lastack的值就做相应的增加,指向下一个待确认数据的编号,当发送一个报文后,snd_nxt的值就做相应的增加,指向下一个待发送数据,snd_nxt和lastack之间的差值不能超过snd_wnd的大小。

由于实际数据发送时是按照报文段的形式组织的,因此可能存在这样的情况:即使发送窗口允许,但并不是窗口内的所有数据都能发送以填满窗口,如图13中编号为11~13的数据,可能因为它们太小不能组织成一个有效的报文段,因此不会被发送。发送方会等到新的确认到来,从而使发送窗口向右滑动,使得更多的数据被包含在窗口中,这样再启动下一个报文段的发送。

图13发送窗口

2. 三次握手

图14连接建立过程

3. 断开连接

图15连接断开过程

4.TCP状态转换

图16 TCP状态转换图

5. 同时打开

图17双方同时打开

6. 同时关闭

图18双方同时关闭

五正确使用LWIP

一般说来LWIP协议栈是比较稳定的,尤其像V1.3.2经历过业界广泛使用和工程应用,完全可以应用于嵌入式产品。那为什么还是有很多人反映LWIP不稳定呢?主要是以下几个方面的原因:

1. 网络硬件驱动确保EMAC口接收与发送稳定可靠

2. 移植LWIP基于OS的移植代码正确稳定

3. 配置LWIP根据设备RAM尺寸进行合理配置

1) 值(PBUF_POOL_SIZE * PBUF_POOL_BUFSIZE)必须大于TCP_SND_BUF和TCP_WND,否则容易引起错误;

2) 当内存有限时TCP发送不能太快(具体值依赖于分配内存的大小),否则引起tcp_enqueue()逻辑错误;

4. 调用LWIP的API函数正确使用API函数,特别防止内存泄露。

5. 资源不足打开报警提醒,当资源不够时提醒设计者

六LWIP常见问题

1. 网卡驱动程序

首先,必须将协议栈完全初始化才能打开网络接收功能,接收中断必须将数据封装在PBUF中,然后交会给协议栈内核处理。其次,LWIP的全局变量(arp_table,netif_list,udp_pcbs等)确保赋初值0,否则容易一运行就崩溃。

2. 内存泄露

第一个原则(责任制):谁分配内存,谁就负责回收。

第二个原则(对称性):分配内存者与回收内存者一一对应构成闭环。

另外,需要特别注意一些系统函数的调用,它们也会带来内存泄露,如:

例1

newconn = netconn_accept(conn);

do_something_for(newconn);

netconn_close(newconn);

netconn_delete(newconn);/*一定要释放newconn否则将导致内存泄露*/

例2

inbuf = netconn_recv(conn);

do_something_for(inbuf);

netbuf_delete(inbuf);/*一定要释放inbuf否则将导致内存泄露*/

3.PC机无法与LWIP建立TCP连接

问题:PC机能够与LWIP设备PING操作成功,但是无法建立TCP连接。

原因:通过代码跟踪,发现LWIP发出了SYN+ACK数据包,但是PC机无法接收该握手数据包,该数据包为60字节,小于以太网的最小长度(64字节),而LWIP设备的EMAC没有设置短小数据包填充功能,导致PC机无法接收该短数据包。

解决:使能EMAC的短小数据包填充功能。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表德赢Vwin官网 网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内存
    +关注

    关注

    8

    文章

    3019

    浏览量

    74001

原文标题:收藏!嵌超全的LWIP内存管理经验总结

文章出处:【微信号:gh_c472c2199c88,微信公众号:嵌入式微处理器】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    #硬声创作季 #LWIPLWIP-08 LWIP内存管理-1

    LwIP
    水管工
    发布于 :2022年11月11日 14:39:47

    Linux 内存管理知识学习经验总结

    现在的服务器大部分都是运行在Linux上面的,所以,作为一个程序员有必要简单地了解一下系统是如何运行的。对于内存部分需要知道:地址映射内存管理的方式缺页异常先来看一些基本的知识,在进程
    发表于 02-25 17:08

    LwIP 内存配置

    还是opt.h进行修改,都必须保证是在已经对你所改动的内容足够的了解的情况下进行,所做的改动是正确的,否则有可能导致协议栈 不能正常工作,或者效率低下。LwIP内存管理机制在进行内存
    发表于 08-23 16:10

    请问战舰LWIP移植是怎么实现内存管理的?

    如题,最近在移植LWIP,参考原子战舰V3,由于我的系统没实现内存管理,因此,涉及到malloc的函数我全部使用全局数据区来开辟空间(暂时先这么粗略地实现),但对内存池的
    发表于 09-02 04:36

    嵌入式Linux内存管理知识

    这个内存管理知识点还真的需要我们专门的去理解一下,今天大家一起来学习学习嵌入式Linux内存管理知识
    发表于 02-03 06:30

    嵌入式Linux内存管理知识

    这个内存管理知识点还真的需要我们专门的去理解一下,今天大家一起来学习学习嵌入式Linux内存管理知识
    发表于 03-04 06:22

    文件管理知识汇总,错过绝对后悔

    文件管理知识汇总,错过绝对后悔
    发表于 12-23 06:31

    危险化学品安全管理知识竞赛题

    危险化学品安全管理知识竞赛题  ⒈《危险化学品安全管理条例》自 起施行。    A.2002年1月15日 B.2002年2月15日    C.2002年3月15日 D. 2002年4月15日 
    发表于 12-31 23:01 14次下载

    品质管理知识教程

    品质管理知识教程
    发表于 01-29 15:41 42次下载

    无线电管理知识竞答试题

    无线电管理知识竞答试题 姓      名_______________身份证号码_________________
    发表于 04-16 18:58 1762次阅读

    电池车间生产管理知识培训——5S管理

    电池车间生产管理知识培训——5S管理 什么是5S管理 5S管理就是整理(SEIRI)、整顿(SEITON
    发表于 10-22 11:26 2089次阅读

    LwIP内存管理

    wIP(Light weight IP)是瑞士计算机科学院Adam Dunkels等开发的一套用于嵌入式系统的开放源代码TCP/IP协议栈。LwIP可以移植到操作系统上,
    发表于 05-10 11:46 3968次阅读
    <b class='flag-5'>LwIP</b>的<b class='flag-5'>内存</b><b class='flag-5'>管理</b>

    嵌入式Linux内存管理知识汇总

    这个内存管理知识点还真的需要我们专门的去理解一下,今天大家一起来学习学习嵌入式Linux内存管理知识
    发表于 04-09 05:58 1022次阅读
    嵌入式Linux<b class='flag-5'>内存</b><b class='flag-5'>管理</b>的<b class='flag-5'>知识</b><b class='flag-5'>汇总</b>

    Linux内存管理的基础知识科普

    ,为什么还要看你这一篇,这正是我写此文的原因,网上碎片化的相关知识点大都是东拼西凑,先不说正确性与否,就连基本的逻辑都没有搞清楚,我可以负责任的说Linux内存管理只需要看此文一篇就可以让你入Linux内核的大门,省去你东找西找
    的头像 发表于 06-08 15:24 2106次阅读

    科普|电源管理知识

    科普|电源管理知识
    的头像 发表于 10-17 16:31 603次阅读
    科普|电源<b class='flag-5'>管理知识</b>