📄 lib_mem.c
字号:
if (Mem_PoolTbl == (MEM_POOL *)0) {
*perr = LIB_MEM_ERR_HEAP_NOT_FOUND;
return;
}
if (pmem_base_addr != (void *)0) {
if (mem_size < 1) {
*perr = LIB_MEM_ERR_INVALID_SEG_SIZE;
return;
}
}
pmem_pool_heap = (MEM_POOL *)&Mem_PoolHeap;
CPU_CRITICAL_ENTER();
/* ------------------ MEM POOL CREATE ----------------- */
if (pmem_base_addr == (void *)0) { /* If no base addr, cfg mem pool from heap. */
pmem_pool_prev = pmem_pool_heap;
pmem_pool_next = pmem_pool_heap;
pmem_pool_blk = pmem_pool_heap;
/* Get next avail addr in mem seg. */
pmem_addr_ptrs = (CPU_INT08U *)pmem_pool_heap->SegAddrNextAvail;
/* Calc tot mem size for mem pool ptrs. */
tot_size_ptrs = Mem_PoolSegCalcTotSize((void *)pmem_addr_ptrs,
(CPU_SIZE_T)blk_nbr,
(CPU_SIZE_T)sizeof(void *),
(CPU_SIZE_T)sizeof(void *));
pmem_addr_pool = pmem_addr_ptrs + tot_size_ptrs; /* Adj next avail addr for mem pool blks. */
/* Calc tot mem usage for mem blks. */
tot_size_pool = Mem_PoolSegCalcTotSize((void *)pmem_addr_ptrs,
(CPU_SIZE_T)blk_nbr,
(CPU_SIZE_T)blk_size,
(CPU_SIZE_T)blk_align);
tot_size = tot_size_ptrs + tot_size_pool;
size_rem = pmem_pool_heap->SegSizeRem;
if (tot_size > size_rem) {
CPU_CRITICAL_EXIT();
*perr = LIB_MEM_ERR_HEAP_FULL;
if (poctets_reqd != (CPU_SIZE_T *)0) {
*poctets_reqd = tot_size - size_rem;
}
return;
}
} else {
/* Srch mem seg tbl prim list to find insertion pnt. */
pmem_pool_blk = (MEM_POOL *)0;
pmem_pool_prev = (MEM_POOL *)0;
pmem_pool_next = Mem_PoolTbl;
while (pmem_pool_next != (MEM_POOL *)0) {
/* Seg found. */
if ((pmem_base_addr == pmem_pool_next->SegAddr) &&
(mem_size == pmem_pool_next->SegSizeTot)) {
pmem_pool_prev = pmem_pool_next;
pmem_pool_blk = pmem_pool_next; /* Store pool ptr with seg info. */
break;
} else {
pmem_base_addr_start = (CPU_INT08U *)pmem_base_addr;
pmem_base_addr_end = (CPU_INT08U *)pmem_base_addr + mem_size - 1;
pmem_seg_addr_start = (CPU_INT08U *)pmem_pool_next->SegAddr;
pmem_seg_addr_end = (CPU_INT08U *)pmem_pool_next->SegAddr + pmem_pool_next->SegSizeTot - 1;
/* Seg not found. */
if (pmem_base_addr_end < pmem_seg_addr_start) {
break;
/* New seg extends over prev def seg. */
} else if ((pmem_base_addr_start <= pmem_seg_addr_start) &&
(pmem_base_addr_end >= pmem_seg_addr_start)) {
CPU_CRITICAL_EXIT();
*perr = LIB_MEM_ERR_SEG_OVERLAP;
return;
/* New seg overlaps end of prev def seg. */
} else if ((pmem_base_addr_start >= pmem_seg_addr_start) &&
(pmem_base_addr_start <= pmem_seg_addr_end)) {
CPU_CRITICAL_EXIT();
*perr = LIB_MEM_ERR_SEG_OVERLAP;
return;
}
}
pmem_pool_prev = pmem_pool_next;
pmem_pool_next = pmem_pool_next->SegPrimListNextPtr;
}
if (pmem_pool_blk == (MEM_POOL *)0) { /* If seg not found, write seg info into new pool. */
pmem_pool_blk = pmem_pool;
pmem_pool->SegAddr = pmem_base_addr;
pmem_pool->SegAddrNextAvail = pmem_base_addr;
pmem_pool->SegSizeTot = mem_size;
pmem_pool->SegSizeRem = mem_size;
}
/* Get next avail addr in heap. */
pmem_addr_ptrs = (CPU_INT08U *)pmem_pool_heap->SegAddrNextAvail;
/* Calc tot mem size for mem pool ptrs. */
tot_size_ptrs = Mem_PoolSegCalcTotSize((void *)pmem_addr_ptrs,
(CPU_SIZE_T)blk_nbr,
(CPU_SIZE_T)sizeof(void *),
(CPU_SIZE_T)sizeof(void *));
size_rem = pmem_pool_heap->SegSizeRem;
if (tot_size_ptrs > size_rem) {
CPU_CRITICAL_EXIT();
*perr = LIB_MEM_ERR_HEAP_FULL;
if (poctets_reqd != (CPU_SIZE_T *)0) {
*poctets_reqd = tot_size_ptrs - size_rem;
}
return;
}
/* Get next avail addr in mem seg. */
pmem_addr_pool = (CPU_INT08U *)pmem_pool_blk->SegAddrNextAvail;
/* Calc tot mem size for mem blks. */
tot_size_pool = Mem_PoolSegCalcTotSize((void *)pmem_addr_pool,
(CPU_SIZE_T)blk_nbr,
(CPU_SIZE_T)blk_size,
(CPU_SIZE_T)blk_align);
size_rem = pmem_pool_blk->SegSizeRem;
if (tot_size_pool > size_rem) {
CPU_CRITICAL_EXIT();
*perr = LIB_MEM_ERR_SEG_FULL;
if (poctets_reqd != (CPU_SIZE_T *)0) {
*poctets_reqd = tot_size_pool - size_rem;
}
return;
}
}
/* ------------------- MEM BLK ALLOC ------------------ */
size_pool_ptrs = blk_nbr * sizeof(void *);
/* Alloc stk of ptrs for mem blks from heap. */
ppool_ptr = (void **)Mem_PoolSegAlloc((MEM_POOL *)pmem_pool_heap,
(CPU_SIZE_T)size_pool_ptrs,
(CPU_SIZE_T)sizeof(void *));
/* Alloc mem blks from blk seg ptr. */
for (i = 0; i < blk_nbr; i++) {
pmem_blk = (void *)Mem_PoolSegAlloc(pmem_pool_blk, blk_size, blk_align);
if (pmem_blk == (void *)0) {
CPU_CRITICAL_EXIT();
*perr = LIB_MEM_ERR_SEG_FULL;
return;
}
ppool_ptr[i] = pmem_blk;
}
/* ------------------- MEM POOL TBL ------------------- */
if (pmem_pool_prev == pmem_pool_next) { /* Add new mem pool to sec list. */
pmem_pool_next = pmem_pool_blk->SegSecListNextPtr;
pmem_pool->SegSecListPrevPtr = pmem_pool_blk;
pmem_pool->SegSecListNextPtr = pmem_pool_next;
pmem_pool_blk->SegSecListNextPtr = pmem_pool;
if (pmem_pool_next != (MEM_POOL *)0) {
pmem_pool_next->SegSecListPrevPtr = pmem_pool;
}
} else { /* Add new mem pool to prim list. */
pmem_pool->SegPrimListPrevPtr = pmem_pool_prev;
pmem_pool->SegPrimListNextPtr = pmem_pool_next;
if (pmem_pool_prev != (MEM_POOL *)0) { /* Update prev mem pool link. */
pmem_pool_prev->SegPrimListNextPtr = pmem_pool;
} else {
Mem_PoolTbl = pmem_pool; /* Update Mem_PoolTbl for new head of link list. */
}
if (pmem_pool_next != (MEM_POOL *)0) { /* Update next mem pool link. */
pmem_pool_next->SegPrimListPrevPtr = pmem_pool;
}
}
/* ------------------- MEM POOL INFO ------------------ */
pmem_pool->Type = (LIB_MEM_TYPE)LIB_MEM_TYPE_POOL;
pmem_pool->PoolAddrStart = (void *) pmem_addr_pool;
pmem_pool->PoolAddrEnd = (void *)(pmem_addr_pool + tot_size_pool - 1);
pmem_pool->PoolPtrs = (void **) ppool_ptr;
pmem_pool->PoolSize = (CPU_SIZE_T ) tot_size_pool;
pmem_pool->BlkAlign = (CPU_SIZE_T ) blk_align;
pmem_pool->BlkSize = (CPU_SIZE_T ) blk_size;
pmem_pool->BlkNbr = (CPU_SIZE_T ) blk_nbr;
pmem_pool->BlkIx = (MEM_POOL_IX ) blk_nbr;
CPU_CRITICAL_EXIT();
*perr = LIB_ERR_NONE;
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* Mem_PoolBlkGet()
*
* Description : Retrieve a memory block from memory pool.
*
* Argument(s) : pmem_pool Pointer to memory pool to get memory block from.
*
* mem_size Size of requested memory (in octets).
*
* perr Pointer to variable that will receive the return error code from this function :
*
* LIB_ERR_NONE Memory block retrieved successfully.
*
* Return(s) : Pointer to memory block, if NO errors.
*
* Pointer to NULL, otherwise.
*
* Caller(s) : various.
*
* Note(s) : none.
*********************************************************************************************************
*/
#if (LIB_MEM_CFG_POOL_EN == DEF_ENABLED)
void *Mem_PoolBlkGet (MEM_POOL *pmem_pool,
CPU_SIZE_T size,
LIB_ERR *perr)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
CPU_SR cpu_sr;
#endif
void *pmem_blk;
if (pmem_pool == (MEM_POOL *)0) {
*perr = LIB_MEM_ERR_NULL_PTR;
return ((void *)0);
}
CPU_CRITICAL_ENTER();
if (pmem_pool->Type != LIB_MEM_TYPE_POOL) {
CPU_CRITICAL_EXIT();
*perr = LIB_MEM_ERR_INVALID_POOL;
return ((void *)0);
}
if (size > pmem_pool->BlkSize) {
CPU_CRITICAL_EXIT();
*perr = LIB_MEM_ERR_INVALID_BLK_SIZE;
return ((void *)0);
}
if (pmem_pool->BlkIx == 0) {
CPU_CRITICAL_EXIT();
*perr = LIB_MEM_ERR_NONE_AVAIL;
return ((void *)0);
}
if (pmem_pool->BlkIx > pmem_pool->BlkNbr) {
CPU_CRITICAL_EXIT();
*perr = LIB_MEM_ERR_INVALID_IX;
return ((void *)0);
}
pmem_pool->BlkIx--;
pmem_blk = pmem_pool->PoolPtrs[pmem_pool->BlkIx];
CPU_CRITICAL_EXIT();
*perr = LIB_ERR_NONE;
return (pmem_blk);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* Mem_PoolBlkFree()
*
* Description : Return a memory block to memory pool.
*
* Argument(s) : pmem_pool Pointer to memory pool.
*
* pmem_addr Pointer to memory block address to free.
*
* perr Pointer to variable that will receive the return error code from this function :
*
* LIB_ERR_NONE Memory block successfully freed.
*
* Return(s) : Pointer to memory block, if NO errors.
*
* Pointer to NULL, otherwise.
*
* Caller(s) : various.
*
* Note(s) : none.
*********************************************************************************************************
*/
#if (LIB_MEM_CFG_POOL_EN == DEF_ENABLED)
void Mem_PoolBlkFree (MEM_POOL *pmem_pool,
void *pmem_addr,
LIB_ERR *perr)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
CPU_SR cpu_sr;
#endif
#if (LIB_MEM_CFG_ARG_CHK_EXT_EN == DEF_ENABLED)
MEM_POOL_IX i;
#endif
void *pmem_blk_end;
if (pmem_pool == (MEM_POOL *)0) {
*perr = LIB_MEM_ERR_NULL_PTR;
return;
}
if (pmem_addr == (void *)0) {
*perr = LIB_MEM_ERR_NULL_PTR;
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -