转自:https://blog.csdn.net/u010650845/article/details/72417083
/*
** ver : 2.52
** file : os_time.c
** brief : 内存管理相关操作 C 文件
*/
#ifndef OS_MASTER_FILE
#include "includes.h"
#endif
#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0)
/*
*******************************************************************************************
* 建立一个内存分区
*
* brief : 创建一大小固定的内存分区
*
* addr : 内存分区的起始地址
*
* nblks : 内存分区的总的内存块数量
*
* blksize : 每个内存块的字节数
*
* err : 错误信息
* Returns : 建立的内存分区的指针
*********************************************************************************************
*/
OS_MEM *OSMemCreate (void *addr, INT32U nblks, INT32U blksize, INT8U *err)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
OS_MEM *pmem;
INT8U *pblk;
void **plink;
INT32U i;
#if OS_ARG_CHK_EN > 0
if (addr == (void *)0) { /* 指针不能为空 */
*err = OS_MEM_INVALID_ADDR;
return ((OS_MEM *)0);
}
if (nblks < 2) { /* 每个分区至少有两个内存块 */
*err = OS_MEM_INVALID_BLKS;
return ((OS_MEM *)0);
}
if (blksize < sizeof(void *)) { /* 内存块大小至少能包含一个指针大小 */
*err = OS_MEM_INVALID_SIZE;
return ((OS_MEM *)0);
}
#endif
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; /* 将分区内的内存块链接 */
pblk = (INT8U *)addr + blksize;
for (i = 0; i < (nblks - 1); i++) {
*plink = (void *)pblk;
plink = (void **)pblk;
pblk = pblk + blksize;
}
*plink = (void *)0; /* 最后一个内存块 */
pmem->OSMemAddr = addr; /* 内存分区其实地址 */
pmem->OSMemFreeList = addr; /* 空内存块地址 */
pmem->OSMemNFree = nblks; /* 空内存块数目 */
pmem->OSMemNBlks = nblks; /* 内存块总数 */
pmem->OSMemBlkSize = blksize; /* 内存块大小 */
*err = OS_NO_ERR;
return (pmem);
}
/*$PAGE*/
/*
******************************************************************************************
* 获取内存块
*
* brief : 获取内存块
*
* pmem : 指向内存控制块的指针
*
* err : 指向错误代码的指针,可能取值为:
*
* OS_NO_ERR 成功
* OS_MEM_NO_FREE_BLKS 无剩余内存块可用
* OS_MEM_INVALID_PMEM 无效的内存控制块指针
******************************************************************************************
*/
void *OSMemGet (OS_MEM *pmem, INT8U *err)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
void *pblk;
#if OS_ARG_CHK_EN > 0
if (pmem == (OS_MEM *)0) { /* 无效的内存控制块指针 */
*err = OS_MEM_INVALID_PMEM;
return ((OS_MEM *)0);
}
#endif
OS_ENTER_CRITICAL();
if (pmem->OSMemNFree > 0) { /* 是否有空余内存块 */
pblk = pmem->OSMemFreeList; /* 取出内存块 */
pmem->OSMemFreeList = *(void **)pblk; /* 调整剩余内存块链表 */
pmem->OSMemNFree--; /* 内存块数减1 */
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
return (pblk);
}
OS_EXIT_CRITICAL();
*err = OS_MEM_NO_FREE_BLKS; /* 无可用内存控制块 */
return ((void *)0);
}
/*$PAGE*/
/*
****************************************************************************************
* 释放内存块
*
* breif : 释放内存块
*
* pmem : 指向内存控制块的指针
*
* pblk : 待释放的内存块的指针
*
* Returns : OS_NO_ERR 成功
* OS_MEM_FULL 分区已满
* OS_MEM_INVALID_PMEM 无效的内存控制块指针无效的内存块指针
*****************************************************************************************
*/
INT8U OSMemPut (OS_MEM *pmem, void *pblk)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
#if OS_ARG_CHK_EN > 0
if (pmem == (OS_MEM *)0) { /* 无效的内存控制块指针 */
return (OS_MEM_INVALID_PMEM);
}
if (pblk == (void *)0) { /* 内存块指针不能为空 */
return (OS_MEM_INVALID_PBLK);
}
#endif
OS_ENTER_CRITICAL();
if (pmem->OSMemNFree >= pmem->OSMemNBlks) { /* 内存分区已满 */
OS_EXIT_CRITICAL();
return (OS_MEM_FULL);
}
*(void **)pblk = pmem->OSMemFreeList; /* 插入内存块 */
pmem->OSMemFreeList = pblk;
pmem->OSMemNFree++; /* 内存块数加1 */
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
}
/*$PAGE*/
/*
****************************************************************************************
* 查询内存分区状态
*
* brief : 查询内存分区状态信息.
*
* pmem : 指向内存控制块的指针
*
* pdata : 指向保存内存分区信息的数据结构的指针
*
* Returns : OS_NO_ERR 成功.
* OS_MEM_INVALID_PMEM 无效的内存控制块指针
* OS_MEM_INVALID_PDATA 无效的数据结构指针
*****************************************************************************************
*/
#if OS_MEM_QUERY_EN > 0
INT8U OSMemQuery (OS_MEM *pmem, OS_MEM_DATA *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
#if OS_ARG_CHK_EN > 0
if (pmem == (OS_MEM *)0) { /* 无效的内存控制块指针 */
return (OS_MEM_INVALID_PMEM);
}
if (pdata == (OS_MEM_DATA *)0) { /* 无效的数据结构指针 */
return (OS_MEM_INVALID_PDATA);
}
#endif
OS_ENTER_CRITICAL();
pdata->OSAddr = pmem->OSMemAddr; /* 分区首地址 */
pdata->OSFreeList = pmem->OSMemFreeList; /* 内存块指针 */
pdata->OSBlkSize = pmem->OSMemBlkSize; /* 内存块大小 */
pdata->OSNBlks = pmem->OSMemNBlks; /* 内存块数目 */
pdata->OSNFree = pmem->OSMemNFree; /* 剩余内存块 */
OS_EXIT_CRITICAL();
pdata->OSNUsed = pdata->OSNBlks - pdata->OSNFree; /* 已使用内存块 */
return (OS_NO_ERR);
}
#endif
/*$PAGE*/
/*
**************************************************************************************
* 初始化内存分区管理
*
* brief : 被函数 OSInit() 调用,用户应用程序不应该调用该函数
*
**************************************************************************************
*/
void OS_MemInit (void)
{
#if OS_MAX_MEM_PART == 1 /* 仅有一个内存分区 */
OSMemFreeList = (OS_MEM *)&OSMemTbl[0];
OSMemFreeList->OSMemFreeList = (void *)0;
OSMemFreeList->OSMemAddr = (void *)0;
OSMemFreeList->OSMemNFree = 0;
OSMemFreeList->OSMemNBlks = 0;
OSMemFreeList->OSMemBlkSize = 0;
#endif
#if OS_MAX_MEM_PART >= 2 /* 多余一个内存分区 */
OS_MEM *pmem;
INT16U i;
pmem = (OS_MEM *)&OSMemTbl[0]; /* 指向第一个内存控制块 */
for (i = 0; i < (OS_MAX_MEM_PART - 1); i++) { /* 初始化成单向链表 */
pmem->OSMemFreeList = (void *)&OSMemTbl[i+1];
pmem->OSMemAddr = (void *)0;
pmem->OSMemNFree = 0;
pmem->OSMemNBlks = 0;
pmem->OSMemBlkSize = 0;
pmem++;
}
pmem->OSMemFreeList = (void *)0; /* 初始化最后一个内存控制块 */
pmem->OSMemAddr = (void *)0;
pmem->OSMemNFree = 0;
pmem->OSMemNBlks = 0;
pmem->OSMemBlkSize = 0;
OSMemFreeList = (OS_MEM *)&OSMemTbl[0]; /* 指向第一个空内存控制块 */
#endif
}
#endif