作为一个操作系统,必须有自己的内存管理方式,本系统主要参考ucOS2的内存管理,并实现自己的Malloc和Free函数便于动态分配内存。在ucOS2中,内存管理的核心思想是在RAM中先静态申请一块大的内存块,然后所有的堆的分配都通过调用Malloc来向这块堆中申请相应的大小的内存块,获得相应的指针来使用,当Free后,相当于这块内存块又连接到堆中,供下一次Malloc调用。
那么在系统中的实现就是首先申请一块静态全局变量,大小可以根据系统的实际RAM大小来确定。
这里主要介绍下如何将ucOS2中的实现方式移植到本系统中,首先,建立静态的全局变量数
u8 MemoryBuffer1[64][32];
这里申请全局变量MemoryBuffer来作为堆,一共有64块可供调用,每块的大小是32个字节,为了方便起见,这里每次申请的内存规定小于32个字节。然后初始化这个内存块,
MemoryTxBuf = OSMemCreate(MemoryBuffer1,64,32,&err);
MemoryTxBuf是这个内存块的指针。
然后实现Malloc和Free
void *Malloc(int size)
{
u8 err;
void *str;
if(size > 32)
return (void *)NULL;
str = OSMemGet(MemoryTxBuf,&err);
if(err != OS_NO_ERR)
return (void *)NULL;
else
return str;
}
u8 Free( void *pblk)
{
u8 err;
err = OSMemPut(MemoryTxBuf,pblk);
if(err == OS_NO_ERR)
return 0;
else
return 1;
}
这里OSMemCreate,OSMemGet,OSMemPut就是移植的ucos2的函数
TOS_MEM *OSMemCreate (void *addr, INT32U nblks, INT32U blksize, INT8U *err)
{
INT8U *pblk;
void **plink;
INT32U i;
TOS_MEM *pmem;
if (nblks < 2) {
*err = OS_MEM_INVALID_BLKS;
return ((TOS_MEM *)0);
}
if (blksize < sizeof(void *)) {
*err = OS_MEM_INVALID_SIZE;
return ((TOS_MEM *)0);
}
pmem = &TOSMemFreeList;
plink = (void **)addr;
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;
pmem->OSMemFreeList = addr;
pmem->OSMemNFree = nblks;
pmem->OSMemNBlks = nblks;
pmem->OSMemBlkSize = blksize;
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
return (pmem);
}
void *OSMemGet (TOS_MEM *pmem, INT8U *err)
{
void *pblk;
OS_ENTER_CRITICAL();
if (pmem->OSMemNFree > 0) {
pblk = pmem->OSMemFreeList;
pmem->OSMemFreeList = *((void **)pblk);
//pmem->OSMemFreeList += pmem->OSMemBlkSize;
pmem->OSMemNFree--;
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
return (pblk);
} else {
OS_EXIT_CRITICAL();
*err = OS_MEM_NO_FREE_BLKS;
return ((void *)0);
}
}
INT8U OSMemPut (TOS_MEM *pmem, void *pblk)
{
OS_ENTER_CRITICAL();
if (pmem->OSMemNFree >= pmem->OSMemNBlks) {
OS_EXIT_CRITICAL();
return (OS_MEM_FULL);
}
*(void **)pblk = pmem->OSMemFreeList;
pmem->OSMemFreeList = pblk;
pmem->OSMemNFree++;
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
}