|
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周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|