OS_MEM *OSMemCreate (void *addr, INT32U nblks, INT32U blksize, INT8U *err)
{
OS_MEM *pmem;
INT8U *pblk;
void **plink;
INT32U i;
if (nblks < 2) { //内存的分区数必须大于2
*err = OS_MEM_INVALID_BLKS;
return ((OS_MEM *)0);
}
if (blksize < sizeof(void *)) { //每个内存块至少为一个指针的大小
*err = OS_MEM_INVALID_SIZE;
return ((OS_MEM *)0);
}
OS_ENTER_CRITICAL();
pmem = OSMemFreeList; //空闲内存控制块中取获取一个内存控制块
if (OSMemFreeList != (OS_MEM *)0) { //如果成功获取则原列表指向下一个内存控制块
OSMemFreeList = (OS_MEM *)OSMemFreeList->OSMemFreeList;
}
OS_EXIT_CRITICAL();
if (pmem == (OS_MEM *)0) { //内存控制块不能为空,即有内存控制块可用
*err = OS_MEM_INVALID_PART;
return ((OS_MEM *)0);
}
plink = (void **)addr; //addr是指向内存分区起始地址的一维指针,plink是一个二维指针,
//为保证赋值,将addr也强转成二维指针。操作后plink内存放的是addr的值
//和addr指向相同的地址
pblk = (INT8U *)addr + blksize; //取得下一个内存分区块的起始地址(指针加整数:如INT8U类型占一
//条内存地址,而INT32U类型占4条内存地址,所以指针加整数的值
//为-------指针地址+(INT8U占内存地址数)×blksize
for (i = 0; i < (nblks - 1); i++) {
*plink = (void *)pblk; //*plink是一个void类型指针,为保证赋值,将pblk强转成void类型指针,
//操作后*plink指向下一个分区块的起始地址,即addr指向的地址的内存块
//内存放下一个内存分区块的起始地址
plink = (void **)pblk; //此时将plink改为指向下一个内存分区块的起始地址,以便对下一个内存分区
//块内的值进行赋值操作
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);
}
10-27
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交