您的位置 首页 应用

μC/OS-II的内存办理

我们知道,在ANSIC中可以用malloc()和free()两个函数动态地分配内存和释放内存。但是,在嵌入式实时操作系统中,多次这样做会把原来很大的一块连续内

咱们知道,在ANSIC中能够用malloc()和free()两个函数动态地分配内存和开释内存。但

是,在嵌入式实时操作体系中,屡次这样做会把本来很大的一块接连内存区域,逐渐地分割成

许多十分小并且互相又不相邻的内存区域,也便是内存碎片。由于这些碎片的很多存在,使得

程序到后来连十分小的内存也分配不到。在4.02节的使命仓库中,咱们讲到过用malloc()函

数来分配仓库时,从前讨论过内存碎片的问题。别的,由于内存办理算法的原因,malloc()和

free()函数执行时间是不确定的。

在μC/OS-II中,操作体系把接连的大块内存按分区来办理。每个分区中包括有整数个巨细相同

的内存块,好像图F7.1。运用这种机制,μC/OS-II对malloc()和free()函数进行了改善,使

得它们能够分配和开释固定巨细的内存块。这样一来,malloc()和free()函数的执行时间也是

固定的了。

如图F7.2,在一个体系中能够有多个内存分区。这样,用户的应用程序就能够从不同的内存

分区中得到不同巨细的内存块。可是,特定的内存块在开释时有必要从头放回它以前所归于的内

存分区。明显,选用这样的内存办理算法,上面的内存碎片问题就得到了处理。

图F7.1内存分区——Figure7.1

图F7.2多个内存分区——Figure7.2

内存操控块

为了便于内存的办理,在μC/OS-II中运用内存操控块(memorycONtrolblocks)的数据结构来盯梢每一个内存分区,体系中的每个内存分区都有它自己的内存操控块。程序清单L7.1是内存操控块的界说。

程序清单L7.1内存操控块的数据结构

typedefSTruct{

void*OSMemAddr;

void*OSMemFreeList;

INT32UOSMemBlkSize;

INT32UOSMemNBlks;

INT32UOSMemNFree;

}OS_MEM;

.OSMemAddr是指向内存分区开始地址的指针。它在树立内存分区[见7.1节,树立一个内存分区,OSMemCreate()]时被初始化,在此之后就不能更改了。

.OSMemFreeList是指向下一个闲暇内存操控块或许下一个闲暇的内存块的指针,详细意义要根据该内存分区是否现已树立来决议[见7.1节]。

.OSMemBlkSize 是内存分区中内存块的巨细,是用户树立该内存分区时指定的[见7.1节]。

.OSMemNBlks是内存分区中总的内存块数量,也是用户树立该内存分区时指定的[见7.1节]。

.OSMemNFree是内存分区中当时能够得闲暇内存块数量。

假如要在μC/OS-II中运用内存办理,需要在OS_CFG.H文件中将开关量OS_MEM_EN设置为1。这样μC/OS-II在启动时就会对内存办理器进行初始化[由OSInit()调用OSMemInit()完结]。该初始化首要树立一个图F7.3所示的内存操控块链表,其间的常数OS_MAX_MEM_PART(见文件OS_CFG.H)界说了最大的内存分区数,该常数值至少应为2。

图F7.3闲暇内存操控块链表——Figure7.3

树立一个内存分区,OSMemCreate()在运用一个内存分区之前,有必要先树立该内存分区。这个操作能够经过调用OSMemCreate()函数来完结。程序清单L7.2阐明了怎么树立一个含有100个内存块、每个内存块32字节的内存分区。

程序清单L7.2树立一个内存分区

OS_MEM*CommTxBuf;

INT8UCommTxPart[100][32];

voidmain(void)

{

INT8Uerr;

OSInit();

.

.

CommTxBuf=OSMemCreate(CommTxPart,100,32,err);

.

.

OSStart();

}

程序清单L7.3是OSMemCreate()函数的源代码。该函数共有4个参数:内存分区的开始地址、分区内的内存块总块数、每个内存块的字节数和一个指向错误信息代码的指针。假如OSMemCreate()操作失利,它将回来一个NULL指针。不然,它将回来一个指向内存操控块的指针。对内存办理的其它操作,象OSMemGet(),OSMemPut(),OSMemQuery()函数等,都要经过该指针进行。

每个内存分区有必要含有至少两个内存块[L7.3(1)],每个内存块至少为一个指针的巨细,由于同一分区中的一切闲暇内存块是由指针串联起来的[L7.3(2)]。接着,OSMemCreate()从体系中的闲暇内存操控块中获得一个内存操控块[L7.3(3)],该内存操控块包括相应内存分区的运转信息。OSMemCreate()有必要在有闲暇内存操控块可用的情况下才干树立一个内存分区[L7.3(4)]。在上述条件均得到满意时,所要树立的内存分区内的一切内存块被链接成一个单向的链表[L7.3(5)]。然后,在对应的内存操控块中填写相应的信息[L7.3(6)]。完结上述各动作后,OSMemCreate()回来指向该内存块的指针。该指针在今后对内存块的操作中运用[L7.3(6)]。

程序清单L7.3OSMemCreate()

OS_MEM*OSMemCreate(void*addr,INT32Unblks,INT32Ublksize,INT8U*err)

{

OS_MEM*pmem;

INT8U*pblk;

void**plink;

INT32Ui;

if(nblks2){(1)

*err=OS_MEM_INVALID_BLKS;

return((OS_MEM*)0);

}

if(blksize

*err=OS_MEM_INVALID_SIZE;

return((OS_MEM*)0);

}

OS_ENTER_CRITICAL();

pmem=OSMemFreeList;(3)

if(OSMemFreeList!=(OS_MEM*)0){

OSMemFreeList=(OS_MEM*)OSMemFreeList->OSMemFreeList;

}

OS_EXIT_CRIT%&&&&&%AL();

if(pmem==(OS_MEM*)0){(4)

*err=OS_MEM_INVALID_PART;

return((OS_MEM*)0);

}

plink=(void**)addr;(5)

pblk=(INT8U*)addr+blksize;

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/yingyong/297975.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部