/*
** 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
uC/OS-II源碼解析(os_mem.c)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.