搜索
bottom↓
回复: 26

LwIP的学习总结

[复制链接]

出0入0汤圆

发表于 2009-8-28 10:21:53 | 显示全部楼层 |阅读模式
学习RT-Thread和lwip有近一个月了,学习过程颇有波折,就做了一些总结,现在整理,先发部分上来。
个人水平比较菜,希望看官留情。未经同意,不得转载。

点击此处下载 ourdev_475429.pdf(文件大小:291K) (原文件名:第二章 基础组件.pdf)

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2009-8-28 11:31:03 | 显示全部楼层
内存管理
LwIP内存管理部分(mem.h mem.c)比较灵活,支持多种分配策略,有运行时库自带的内存分配(MEM_LIBC_MALLOC),有内存池分配(MEM_USE_POOLS),有动态内存堆分配,这些分配策略可以通过宏定义来更改。在嵌入式系统里面,C运行时库自带的内存分配一般情况下很少用,更多的是后面二者,下面就这两种分配策略进行简单的分析:
动态内存堆分配
其原理就是在一个事先定义好大小的内存块中进行管理,其内存分配的策略是采用最快合适(First Fit )方式,只要找到一个比所请求的内存大的空闲块,就从中切割出合适的块,并把剩余的部分返回到动态内存堆中。在分配的内存块前大约有12字节会存放内存分配器管理用的私有数据,该数据区不能被用户程序修改,否则导致致命问题。
内存释放的过程是相反的过程,但分配器会查看该节点前后相邻的内存块是否空闲,如果空闲则合并成一个大的内存空闲块。
采用这种分配策略,其优点就是内存浪费小,比较简单,适合用于小内存的管理,其缺点就是如果频繁的动态分配和释放,可能会造成严重的内存碎片,如果在碎片情况严重的话,可能会导致内存分配不成功。对于动态内存的使用,比较推荐的方法就是分配->释放->分配->释放,这种使用方法能够减少内存碎片。
mem_init( ) 内存堆的初始化,主要是告知内存堆的起止地址,以及初始化空闲列表,由lwip初始化时自己调用,该接口为内部私有接口,不对用户层开放。
mem_malloc( ) 申请分配内存。将总共需要的字节数作为参数传递给该函数,返回值是指向最新分配的内存的指针,而如果内存没有分配好,则返回值是NULL,分配的空间大小会收到内存对齐的影响,可能会比申请的略大。返回的内存是“没有“初始化的。这块内存可能包含任何随机的垃圾,你可以马上用有效数据或者至少是用零来初始化这块内存。内存的分配和释放,不能在中断函数里面进行。内存堆是全局变量,因此内存的申请、释放操作做了线程安全保护,如果有多个线程在同时进行内存申请和释放,那么可能会因为信号量的等待而导致申请耗时较长。
mem_calloc( ) 是对mem_malloc( )函数的简单包装,他有两个参数,分别为元素的数目和每个元素的大小,这两个参数的乘积就是要分配的内存空间的大小,与mem_malloc()不同的是它会把动态分配的内存清零。有经验的程序员更喜欢使用mem_malloc (),因为这样的话新分配内存的内容就不会有什么问题,调用mem_malloc ()肯定会清0,并且可以避免调用memset()。
mem_realloc( )  函数
Opt.h文件的宏MEM_SIZE 是表示初始内存堆的大小。
动态内存池分配
说实话,我也不知道这个说法对不对,反正从源代码里面看,前者叫heap,后者叫pool。欢迎专家指正。
动态内存分配方式只能在内存池与内存堆中二选一。他们对外部的接口都是一样,只不过内部工作原理不太一样。动态内存池分配部分底层实现是在memp.c,memp.h 文件里面实现。
采用内存池进行内存管理可以有效防止内存碎片的产生,而且相比之下内存的分配、释放效率更高,不过,他会浪费部分内存。
需要启用宏MEM_USE_POOLS 和 MEM_USE_CUSTOM_POOLS,另外还要做类似如下定义:
LWIP_MALLOC_MEMPOOL_START
LWIP_MALLOC_MEMPOOL(20, 256)
LWIP_MALLOC_MEMPOOL(10, 512)
LWIP_MALLOC_MEMPOOL(5, 1512)
LWIP_MALLOC_MEMPOOL_END
上面的意思就是分配20个256字节长度的内存块,10个512字节的内存块,5个1512字节的内存块。内存池管理会根据以上的宏自动在内存中静态定义一个大片内存用于内存池。在内存分配申请的时候,自动根据所请求的大小,选择最适合他长度的池里面去申请,如果启用宏 MEM_USE_POOLS_TRY_BIGGER_POOL,那么,如果上述的最适合长度的池中没有空间可以用了,分配器将从更大长度的池中去申请,不过这样会浪费更多的内存。
此外,LwIP为内部的一些结构设计了专用的内存池,比如netconn,协议控制块,数据包等,这些都是在memp.c/memp.h里用内存池进行管理的。
这个模块里面LwIP把C语言的宏用到了极致,它大量采用了C语言的宏特性,设计上面也非常的精妙,看上去也很优雅,不过对于初学者来说猛的看上去很头大,下面就且听我给你介绍,我们先看几个静态变量数组:
memp_memory[]
这是内存池容器,他的大小由编译期决定,他是各个组件的结构用量的累加。
我们来看代码:

这是内存池的具体定义,通过147行,我们可以看出内存池的大小由各个组件的 num*size的累加。如下图所示,每个组件的num 就是下列阴影区的宏定义(在memp_std.h文件)

size的大小就是各个结构的大小,如下图阴影区所示。

整个内存池的大小又可以根据组件的需要而调整,比如,如果你不需要UDP,那么只要把LWIP_UDP定义为0。用宏定义来实现用起来方便,改起来容易,就是看起来头大。
memp_num
这个静态数组用于保存各个组件的成员数目,与memp_memory类似也是用宏实现的。
memp_sizes
这个静态数组用于保存各个组件的结构大小,与memp_memory类似也是用宏实现的。

memp_init
内存池的初始化,主要是为每种内存池建立链表memp_tab,其链表是逆序的,此外,如果有统计功能使能的话,也把记录了各种内存池的数目。
memp_malloc
如果相应的memp_tab链表还有空闲的节点,则从中切出一个节点返回,否则返回空。
memp_free
把释放的节点添加到相应的链表memp_tab头上。

pbuf
pbuf是lwIP包的内部表示,被设计为最小化栈的特殊需要。pbufs类似于BSD实现中的mbufs。pbuf结构支持为包内容动态分配内存和让包数据驻留在静态内存中。pbufs能被一个称为pbuf链的链接到一个链表中,以至一个包能跨越多个pbufs。

出0入0汤圆

发表于 2009-8-29 10:36:21 | 显示全部楼层
支持一下LZ。继续.

出0入0汤圆

发表于 2009-8-29 11:57:19 | 显示全部楼层
不错

出0入0汤圆

发表于 2009-8-29 12:05:13 | 显示全部楼层
马克之

出0入168汤圆

发表于 2009-8-29 13:03:59 | 显示全部楼层
不错,学习。

出0入0汤圆

发表于 2010-5-1 22:47:14 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-5-2 12:04:13 | 显示全部楼层
支持一下LZ。继续^

出0入0汤圆

发表于 2010-5-11 17:05:29 | 显示全部楼层
支持!再多上传点有关这方面的资料就好了!

出0入0汤圆

发表于 2010-12-20 19:14:46 | 显示全部楼层
只有第二章吗

出0入0汤圆

发表于 2010-12-20 21:58:27 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-2-23 00:07:11 | 显示全部楼层
支持!关注

出0入0汤圆

发表于 2011-2-23 09:03:50 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-2-26 20:28:57 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-6-27 22:07:53 | 显示全部楼层
路过

出0入0汤圆

发表于 2012-10-15 15:51:22 | 显示全部楼层
正在学习这好家货。

出0入0汤圆

发表于 2012-10-15 15:58:50 | 显示全部楼层
留着学习备用

出0入0汤圆

发表于 2013-4-1 01:10:09 | 显示全部楼层
很是感谢能分享心得的前辈

出0入0汤圆

发表于 2013-4-3 09:47:17 | 显示全部楼层
mark good.

出0入0汤圆

发表于 2013-4-4 13:22:52 来自手机 | 显示全部楼层
支持…
来自:amoBBS 阿莫电子论坛 Windows Phone 7 客户端

出0入0汤圆

发表于 2013-4-16 16:19:07 | 显示全部楼层
这个太简单了吧 没什么用

出0入0汤圆

发表于 2013-8-11 00:54:03 | 显示全部楼层
mark......
顶一个...

出0入0汤圆

发表于 2014-2-17 13:40:59 | 显示全部楼层
二楼的东西有点用

出0入0汤圆

发表于 2014-2-17 13:48:17 | 显示全部楼层
虽然不懂,但是还是支持LZ,LZ加油

出0入0汤圆

发表于 2014-4-21 16:18:25 | 显示全部楼层
mark, thanks

出0入0汤圆

发表于 2014-5-5 20:23:15 | 显示全部楼层
非常感谢楼主,正好也要研究研究这个协议栈呢

出0入0汤圆

发表于 2014-6-9 19:08:09 | 显示全部楼层
支持一下,日后学习
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-20 07:04

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表