您的位置:首页 > 其它

uCOS-II内核之内存管理

2016-12-11 11:17 316 查看
uCOS-II内核之内存管理

为了消除内存碎片,uCOS-II把连续的大块内存按分区来管理。每个分区中包含有整数个大小相同的内存块。

类似每个任务对应一个任务控制块,每个事件对应一个事件控制块,uCOS-II里每个内存块也是对应一个内存控制块。

内存控制块是一个数据结构,定义如下:

typedef struct {
void   *OSMemAddr;
void   *OSMemFreeList;
INT32U  OSMemBlkSize;
INT32U  OSMemNBlks;
INT32U  OSMemNFree;
} OS_MEM;

typedef struct {
void   *OSMemAddr;
void   *OSMemFreeList;
INT32U  OSMemBlkSize;
INT32U  OSMemNBlks;
INT32U  OSMemNFree;
} OS_MEM;


.OSMemAddr是指向内存分区起始地址的指针。它在建立内存分区OSMemCreate()时被初始化,在此之后就不能更改了。

.OSMemFreeList是指向下一个空闲内存控制块或者下一个空闲的内存块的指针,具体含义要根据该内存分区是否已经建立来决定。

.OSMemBlkSize是内存分区中内存块的大小,是用户建立该内存分区时指定的。

.OSMemNBlks是内存分区中总的内存块数量,也是用户建立该内存分区时指定的。

.OSMemNFree是内存分区中当前可以得空闲内存块数量。

完整地使用内存,需要经过以下步骤:

1、建立一个内存分区(OSMemCreate())。

2、调用OSMemGet()函数从已经建立的内存分区中申请内存块。

3、当用户应用程序不再使用一个内存块时,调用OSMemPut()释放内存。

4、在这过程中可以调用OSMemQuery()查询一个内存分区的状态。

建立一个内存分区需要使用uCOS-II系统函数OSMemCreate()。实现过程如下:

OS_MEM *OSMemCreate (void *addr, INT32U nblks, INT32U blksize, INT8U *err)
{
OS_MEM  *pmem;
INT8U   *pblk;
void   **plink;
INT32U   i;

if (nblks < 2) {                                                   //(1)
*err = OS_MEM_INVALID_BLKS;
return ((OS_MEM *)0);
}

if (blksize < sizeof(void *)) {                                    //(2)
*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_CRITICAL();

if (pmem == (OS_MEM *)0) {                                         //(4)
*err = OS_MEM_INVALID_PART;
return ((OS_MEM *)0);
}

plink = (void **)addr;                                             //(5)
pblk  = (INT8U *)addr + blksize;

for (i = 0; i < (nblks - 1); i++) {
*plink = (void *)pblk;
plink  = (void **)pblk;
pblk   = pblk + blksize;
}

*plink = (void *)0;
OS_ENTER_CRITICAL();

pmem->OSMemAddr     = addr;                                        //(6)
pmem->OSMemFreeList = addr;
pmem->OSMemNFree    = nblks;
pmem->OSMemNBlks    = nblks;
pmem->OSMemBlkSize  = blksize;

OS_EXIT_CRITICAL();
*err   = OS_NO_ERR;

return (pmem);                                                     //(7)


该函数共有4个参数:内存分区的起始地址、分区内的内存块总块数、每个内存块的字节数和一个指向错误信息代码的指针。如果OSMemCreate()操作失败,它将返回一个NULL指针。否则,它将返回一个指向内存控制块的指针。对内存管理的其它操作,象OSMemGet(),OSMemPut(),OSMemQuery()函数等,都要通过该指针进行。

以上程序,简单来说,主要执行以下两大步骤,一是从空闲内存控制块中获取一个内存控制块,二是初始化这块内存控制块。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息