搜索
bottom↓
回复: 2

嵌入式TCP/IP学习笔记-缓存控制块链表POOL【恢复】

[复制链接]

出0入0汤圆

发表于 2008-12-19 10:32:41 | 显示全部楼层 |阅读模式
TCPIPmem.C 

//============================================================== 

//  嵌入式 TCP/IP 协议栈 MSC51 专用版 

// TCPIPMEM.C 

//  作     者:南开大学-李章林 

//  日     期:2008 年4 月 

//  注     释:李清林 

//  声     明:英文注释由作者李章林添加,中文注释由■李清林■添加。 

//        转载时请保留上述信息。 

//  成都理工学院/应用数字系/应用数学专业 

//============================================================== 

#include "..\GloblDef\GloblDef.h" 

#include "..\TCPIP\TCPIPmem.h" 

 

/* buf for all tcpip packet */ 

//  缓存区域 

static BYTE DT_XDATA TCPIPBuf[TCPIP_BUF_SIZE]; 

/* end of the chain */ 

//  指向缓存区域的尾控制块指针 

static struct SMemHead DT_XDATA * DT_XDATA MemHeadEnd; 

//  指向缓存区域的首控制块指针 

static struct SMemHead DT_XDATA * DT_XDATA MemHeadStart; 

/* free memsize can use */ 

//  空闲缓存尺寸 

static WORD DT_XDATA FreeSize; 

 

//============================================================================= 

//  日     期:2008 年4 月 

//  注     释:李清林 

//  注     意:所有的英文注释为原作者添加,中文注释为■李清林添加。 

//  程序名称:MemInit=内存缓冲控制块初始化子程序 

//  功     能:整个缓存区域被分配给一个控制块,其中首指针 MemHeadStart 

//            指向整个缓存区域首地址,尾指针 MemHeadEnd  指向整个缓存区 

//            域结束地址,净负荷(空闲空间)=缓存区域-内存控制块结构 

//            体占用尺寸。 

//  入口参数: 

//        无 

//  出口参数: 

//      无 

//============================================================================= 

void MemInit() REENTRANT_MUL 

{ 

  //  指向缓存区域的首控制块指针 

  MemHeadEnd = (struct SMemHead DT_XDATA *)(TCPIPBuf + TCPIP_BUF_SIZE); 

  //  指向缓存区域的尾控制块指针 

  MemHeadStart = (struct SMemHead DT_XDATA *)TCPIPBuf; TCPIPmem.C 

 

  /* at inital there is only a buf block. value in 

  mem head is as following */ 

  //  仅仅将缓存区域初始化成一个存控制块 

  //   首控制块指针的 pNext  域指向尾控制块指针 

  MemHeadStart->pNext = MemHeadEnd; 

  //   首控制块指针的 pPre  域指向首控制块指针 

  MemHeadStart->pPre  = MemHeadStart; 

  //   首控制块指针标记为未使用 

  MemHeadStart->used = FALSE; 

  //  空闲尺寸=缓存区域-每个缓存控制块结构体占用尺寸 

  FreeSize = TCPIP_BUF_SIZE  - sizeof(struct SMemHead); 

} 

 

//============================================================================= 

/* allocate a buffer size of size, and set pStart to the start of buffer,pEnd 

to end of buffer.Also decrease FreeSize. */ 

//  日     期:2008 年3 月 

//  注     释:李清林 

//  注     意:所有的英文注释为原作者添加,中文注释为■李清林添加。 

//  程序名称:MemAllocate=缓冲控制块分配内存空间子程序 

//  功     能: 

//  入口参数: 

//       size=分配空间尺寸 

//  出口参数: 

//      SMemHead=分配空间的缓存控制块指针 

//---------------------------------------------------------------------------- 

// MemPlayloadSize = (BYTE DT_XDATA *)(MemHead->pNext) - 

//                   (BYTE DT_XDATA *)MemHead  - sizeof(struct SMemHead)) 

//  分析:由于在嵌入式系统中缓存区域必须是一段连续的空间,因此缓存初始化 

//  后,整个缓存区域被分配给一个控制块,此时首指针 MemHeadStart  指向整个 

//  缓存区域首地址,尾指针 MemHeadEnd  指向整个缓存区域结束地址。首指针的 

// pNext  域指向尾指针,因此通过(BYTE DT_XDATA *)(MemHead->pNext) - 

// (BYTE DT_XDATA *)MemHead-sizeof(struct SMemHead))即可知道缓存链表净 

//  负荷。 

//---------------------------------------------------------------------------- 

//  注:本 TCP/IP 协议栈采用的内存分配方法完全类似于 MSDOS 操作系统的 MCB。 

//  即所有的内存由内存控制块串连起来,。 

//---------------------------------------------------------------------------- 

//好象 MemHead =  大的缓存控制块分解后的分配的缓存控制块指针 

//    NewMemHead =  大的缓存控制块分解后的剩余缓存控制块指针 

//============================================================================= 

struct SMemHead DT_XDATA *MemAllocate(WORD size) REENTRANT_SIG 

{ 

  struct SMemHead DT_XDATA *MemHead;    //  缓存控制块临时指针 TCPIPmem.C 

  struct SMemHead DT_XDATA *NewMemHead;   //  缓存控制块分配指针 

  WORD MemPlayloadSize;                   //  内存净负荷 

 

  /* search though the mem blocks */ 

  //  循环遍历缓存控制块 

  for (MemHead = MemHeadStart ; MemHead != MemHeadEnd;) 

  { 

    /* if unused and mem playload size> size, select it. */ 

//--------------------------------------------------------------------------- 

// (1). MemHead->pNext = 

// (2). MemHead = 

// (3). sizeof(struct SMemHead) =  结构体占用尺寸 

//  如果链表当前项标记=未使用 AND  链表当前项的净负荷>=  待分配尺寸 

//--------------------------------------------------------------------------- 

    if (MemHead->used == FALSE && (MemPlayloadSize = (BYTE DT_XDATA *) 

       (MemHead->pNext) - (BYTE DT_XDATA *)MemHead - 

       sizeof(struct SMemHead))>= size) 

    { 

      /* if MemPalyloadSize  - size> sizeof(struct SMemHead) create 

      a new SMemHead at the excess memory leaving for later usage */ 

      //-------------------------------------------------------------- 

      //  如果链表当前项分配完 szie  后还有剩余 

      //-------------------------------------------------------------- 

      if (MemPlayloadSize - size> sizeof(struct SMemHead)) 

      { 

        //  缓存控制块分配指针 NewMemHead  指向分配空间的首址(跳过 

        //  结构体自身占用的尺寸),由于采用控制块形式的链表,因此 

        //  分配 size 尺寸的内存时,必须至少需要 

        // size+sizeof(struct SMemHead)长度。 

        //--------------------------------------------------------- 

        // 

        //--------------------------------------------------------- 

        NewMemHead = (struct SMemHead DT_XDATA *) ((BYTE DT_XDATA *) 

              MemHead + sizeof(struct SMemHead) + size ); 

        /* link into link chain */ 

        NewMemHead->pNext = MemHead->pNext; 

        MemHead->pNext    = NewMemHead; 

        NewMemHead->pPre  = MemHead; 

        if (NewMemHead->pNext != MemHeadEnd) 

          NewMemHead->pNext->pPre = NewMemHead; 

        /* set new mem as unused */ 

        //  新分配内存控制块标记=未使用 

        NewMemHead->used = FALSE; 

        /* decrease FreeSize: playload of MemHead and the head of NewMemHead */ 

        FreeSize -= (BYTE DT_XDATA *)(MemHead->pNext) - TCPIPmem.C 

              (BYTE DT_XDATA *)MemHead; 

      } 

      //-------------------------------------------------------------- 

      //如果链表当前项分配完 szie  后刚好合适 

      //-------------------------------------------------------------- 

      else 

      { 

        /* decrease: playload of MemHead */ 

        FreeSize -= (BYTE DT_XDATA *)(MemHead->pNext) - 

          (BYTE DT_XDATA *)MemHead - sizeof(struct SMemHead); 

      } 

      /* set pStart */ 

      MemHead->pStart = (BYTE DT_XDATA *)MemHead + sizeof(struct SMemHead); 

      MemHead->pEnd  = MemHead->pStart + size; 

      /* set as used */ 

      MemHead->used = TRUE; 

      return MemHead; 

    } 

  } 

  return NULL; 

} 

 

//============================================================== 

//  嵌入式 TCP/IP 协议栈 MSC51 专用版 

// TCPIPMEM.C 

//  作     者:南开大学-李章林 

//  日     期:2008 年4 月 

//  注     释:李清林 

//  声     明:英文注释由作者李章林添加,中文注释由■李清林添加。 

//        转载时请保留上述信息。 

//  成都理工学院/应用数字系/应用数字专业 

//  程序名称:MemFreeSize=回收内存缓存控制块到链表 

//  功     能:本子程序采用操作系统的回收方式,回收内存缓存控制块。 

//  入口参数: 

//       MemHead=内存缓存控制块指针 

//  出口参数: 

//      无 

//============================================================== 

void MemFree(struct SMemHead DT_XDATA * MemHead) REENTRANT_SIG 

{ 

  //  内存缓存控制块临时指针(待合并指针的前一指针) 

  struct SMemHead DT_XDATA * MemHeadMergePre; 

  //  内存缓存控制块临时指针(待合并指针的后一指针) 

  struct SMemHead DT_XDATA * MemHeadMergeNext; 

 TCPIPmem.C 

  /* set used flag to false */ 

  MemHead->used = FALSE;   //   标记 MemHead=未使用 

  /* inc FreeSize the size of playload of 'MemHead'*/ 

  //  空闲尺寸+= ????????????????????? 

  FreeSize += (BYTE DT_XDATA *)(MemHead->pNext) -  (BYTE DT_XDATA *)MemHead 

      - sizeof(struct SMemHead); 

  /* if pNext or pPre is a unused memblock, merge with it */ 

  /* find the two MemHead going to merge */ 

  //  如果 MemHead  的前驱指针未使用,则将前驱缓存控制块合并成一块。 

  //  如果 MemHead  的后驱指针未使用,则将后驱缓存控制块合并成一块。 

  if (MemHead->pPre->used == FALSE) //  如果 MemHead  的前驱指针未使用 

  { 

  /* note: if MemHead == TCPBuf, MemHead->pPre == MemHead, but it is not a problom */ 

    //  内存缓存控制块临时指针指向 MemHead  的前驱缓存控制块 

    MemHeadMergePre = MemHead->pPre; 

  } 

  else 

  { 

    //  内存缓存控制块临时指针指向 MemHead  自身 

    MemHeadMergePre = MemHead; 

  } 

  //  如果 MemHead  的后驱指针未指向结尾指针 AND  后驱指针未使用 

  if (MemHead->pNext != MemHeadEnd && MemHead->pNext->used == FALSE) 

  { 

    //  内存缓存控制块临时指针指向 MemHead  的后驱缓存控制块 

    MemHeadMergeNext = MemHead->pNext; 

    /* MemHead of 'MemHead->pNext' will be free. Free size inc*/ 

    FreeSize += sizeof(struct SMemHead); 

  } 

  else 

  { 

    MemHeadMergeNext = MemHead; 

  } 

  /* merge is necessary? */ 

  if(MemHeadMergePre != MemHeadMergeNext) 

  { 

    /* merge. that is del MemHeadMergeNext from the chain */ 

    MemHeadMergePre->pNext = MemHeadMergeNext->pNext; 

    if(MemHeadMergeNext->pNext != MemHeadEnd) 

      MemHeadMergeNext->pNext->pPre = MemHeadMergePre; 

    /* will MemHead of 'MemHead' will be free? */ 

    if (MemHead != MemHeadMergePre) 

      FreeSize += sizeof(struct SMemHead); 

  } 

} TCPIPmem.C 

 

//============================================================== 

//  嵌入式 TCP/IP 协议栈 MSC51 专用版 

// TCPIPMEM.C 

//  作     者:南开大学-李章林 

//  日     期:2008 年4 月 

//  注     释:李清林 

//  声     明:英文注释由作者李章林添加,中文注释由■李清林添加。 

//        转载时请保留上述信息。 

//  成都理工学院/应用数字系/应用数字专业 

//  程序名称:MemFreeSize=获取内存缓存控制块空闲尺寸子程序 

//  入口参数: 

//        无 

//  出口参数: 

//     FreeSize=内存缓冲控制块空闲尺寸 

//============================================================== 

WORD MemFreeSize() REENTRANT_SIG 

{ 

  return FreeSize; 

} 

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

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

出0入0汤圆

 楼主| 发表于 2008-12-19 10:39:20 | 显示全部楼层
有关缓存控制块方面的知识参照:清华大学 严蔚敏著的《数据结构》有关“动态存储管理”方面的知识。





   --------

   |       |

   | 头指针|----->-------------------                    ----------------

   ---------      |   内存控制块     |------> ... -----> | 内存控制块   | 

                  --------------------                   -----------------

                  |                   |                  |              |

                  |    内存存储区域   |                  |  内存存储区域|

                  |--------------------                  -----------------
头像被屏蔽

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-5-21 00:00

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

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