📄 lib_mem.c
字号:
* LIB_MEM_ERR_NULL_PTR Argument 'pmem_pool' passed a NULL pointer.
* LIB_MEM_ERR_INVALID_POOL Invalid memory pool type.
* LIB_MEM_ERR_INVALID_MEM_ALIGN Invalid memory alignment.
*
* Return(s) : Remaining heap memory size (in octets), if NO error(s).
*
* 0, otherwise.
*
* Caller(s) : Application.
*
* Note(s) : none.
*********************************************************************************************************
*/
#if (LIB_MEM_CFG_ALLOC_EN == DEF_ENABLED)
CPU_SIZE_T Mem_HeapGetSizeRem (CPU_SIZE_T align,
LIB_ERR *perr)
{
CPU_SIZE_T size_rem;
size_rem = Mem_SegGetSizeRem(&Mem_PoolHeap, align, perr);
return (size_rem);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* Mem_SegGetSizeRem()
*
* Description : Get memory pool's remaining segment size available to allocate.
*
* Argument(s) : pmem_pool Pointer to a memory pool structure.
*
* align Desired word boundary alignment (in octets) to return remaining memory size from.
*
* perr Pointer to variable that will receive the return error code from this function :
*
* LIB_MEM_ERR_NONE Memory segment remaining size successfully
* returned.
* LIB_MEM_ERR_NULL_PTR Argument 'pmem_pool' passed a NULL pointer.
* LIB_MEM_ERR_INVALID_POOL Invalid memory pool type.
* LIB_MEM_ERR_INVALID_MEM_ALIGN Invalid memory alignment.
*
* Return(s) : Remaining memory segment size (in octets) [see Note #1], if NO error(s).
*
* 0, otherwise.
*
* Caller(s) : Application.
*
* Note(s) : (1) Remaining size of memory segment returned from either :
*
* (a) Segment's configured dedicated memory, if any
* (b) Heap memory pool, otherwise
*
* (2) 'pmem_pool' variables MUST ALWAYS be accessed exclusively in critical sections.
*********************************************************************************************************
*/
/*$PAGE*/
#if (LIB_MEM_CFG_ALLOC_EN == DEF_ENABLED)
CPU_SIZE_T Mem_SegGetSizeRem (MEM_POOL *pmem_pool,
CPU_SIZE_T align,
LIB_ERR *perr)
{
MEM_POOL *pmem_seg;
MEM_POOL *pmem_seg_size;
CPU_SIZE_T size_rem;
CPU_SIZE_T size_rem_mod;
CPU_SIZE_T seg_addr_mod;
CPU_ADDR seg_addr;
CPU_SR_ALLOC();
#if (LIB_MEM_CFG_ARG_CHK_EXT_EN == DEF_ENABLED)
/* --------------- VALIDATE RTN ERR PTR --------------- */
if (perr == (LIB_ERR *)0) {
CPU_SW_EXCEPTION(0u);
}
/* ---------------- VALIDATE MEM ALIGN ---------------- */
if (align < 1) {
*perr = LIB_MEM_ERR_INVALID_MEM_ALIGN;
return (0u);
}
if (align > DEF_ALIGN_MAX_NBR_OCTETS) {
*perr = LIB_MEM_ERR_INVALID_MEM_ALIGN;
return (0u);
}
/* ---------------- VALIDATE MEM POOL ----------------- */
if (pmem_pool == (MEM_POOL *)0) { /* Validate mem ptr. */
*perr = LIB_MEM_ERR_NULL_PTR;
return (0u);
}
#endif
CPU_CRITICAL_ENTER();
#if (LIB_MEM_CFG_ARG_CHK_EXT_EN == DEF_ENABLED)
switch (pmem_pool->Type) { /* Validate mem pool type. */
case LIB_MEM_TYPE_HEAP:
case LIB_MEM_TYPE_POOL:
break;
case LIB_MEM_TYPE_NONE:
default:
CPU_CRITICAL_EXIT();
*perr = LIB_MEM_ERR_INVALID_POOL;
return (0u); /* Prevent 'break NOT reachable' compiler warning. */
}
#endif
/* ------------- GET REM'ING MEM SEG SIZE ------------- */
pmem_seg = pmem_pool->SegHeadPtr; /* Get mem pool's head seg. */
pmem_seg_size = (pmem_seg->SegAddr != (void *)0)
? pmem_seg : &Mem_PoolHeap; /* See Note #1. */
size_rem = pmem_seg_size->SegSizeRem; /* Get mem seg's rem'ing mem size. */
seg_addr = (CPU_ADDR)pmem_seg_size->SegAddrNextAvail;
CPU_CRITICAL_EXIT();
if (align > 1) { /* If align > 1 octet, ... */
seg_addr_mod = seg_addr % align;
size_rem_mod = (seg_addr_mod > 0u) ? (align - seg_addr_mod) : 0u;
size_rem -= size_rem_mod; /* ... adj rem'ing size by offset to align'd seg addr. */
}
*perr = LIB_MEM_ERR_NONE;
return (size_rem);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* Mem_PoolClr()
*
* Description : Clear a memory pool (see Note #1).
*
* Argument(s) : pmem_pool Pointer to a memory pool structure to clear (see Note #2).
*
* perr Pointer to variable that will receive the return error code from this function :
*
* LIB_MEM_ERR_NONE Memory pool successfully cleared.
* LIB_MEM_ERR_NULL_PTR Argument 'pmem_pool' passed a NULL pointer.
*
* Return(s) : none.
*
* Caller(s) : Application,
* Mem_PoolCreate().
*
* Note(s) : (1) (a) Mem_PoolClr() ONLY clears a memory pool structure's variables & should ONLY be
* called to initialize a memory pool structure prior to calling Mem_PoolCreate().
*
* (b) Mem_PoolClr() does NOT deallocate memory from the memory pool or deallocate the
* memory pool itself & MUST NOT be called after calling Mem_PoolCreate() since
* this will likely corrupt the memory pool management.
*
* (2) Assumes 'pmem_pool' points to a valid memory pool (if non-NULL).
*********************************************************************************************************
*/
#if (LIB_MEM_CFG_ALLOC_EN == DEF_ENABLED)
void Mem_PoolClr (MEM_POOL *pmem_pool,
LIB_ERR *perr)
{
#if (LIB_MEM_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* -------------- VALIDATE RTN ERR PTR --------------- */
if (perr == (LIB_ERR *)0) {
CPU_SW_EXCEPTION(;);
}
#endif
/* -------------- VALIDATE MEM POOL PTR --------------- */
if (pmem_pool == (MEM_POOL *)0) {
*perr = LIB_MEM_ERR_NULL_PTR;
return;
}
pmem_pool->Type = (LIB_MEM_TYPE)LIB_MEM_TYPE_NONE;
pmem_pool->SegHeadPtr = (MEM_POOL *)0;
pmem_pool->SegPrevPtr = (MEM_POOL *)0;
pmem_pool->SegNextPtr = (MEM_POOL *)0;
pmem_pool->PoolPrevPtr = (MEM_POOL *)0;
pmem_pool->PoolNextPtr = (MEM_POOL *)0;
pmem_pool->PoolAddrStart = (void *)0;
pmem_pool->PoolAddrEnd = (void *)0;
pmem_pool->PoolPtrs = (void **)0;
pmem_pool->PoolSize = (CPU_SIZE_T )0u;
pmem_pool->BlkAlign = (CPU_SIZE_T )0u;
pmem_pool->BlkSize = (CPU_SIZE_T )0u;
pmem_pool->BlkNbr = (CPU_SIZE_T )0u;
pmem_pool->BlkIx = (MEM_POOL_IX )0u;
pmem_pool->SegAddr = (void *)0;
pmem_pool->SegAddrNextAvail = (void *)0;
pmem_pool->SegSizeTot = (CPU_SIZE_T )0u;
pmem_pool->SegSizeRem = (CPU_SIZE_T )0u;
*perr = LIB_MEM_ERR_NONE;
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* Mem_PoolCreate()
*
* Description : (1) Create a memory pool :
*
* (a) Create memory pool from heap or dedicated memory
* (b) Allocate memory pool memory blocks
* (c) Update memory pool table
* (d) Configure memory pool
*
*
* (2) Memory pools are indexed by the Memory Segments they use.
*
* (a) The memory pool table is composed by a two-dimensional list :
*
* (1) Memory segments manage the following memory segment/pool information :
*
* (A) Memory segment base address
* (B) Memory segment next available address
* (C) Memory segment total size
* (D) Memory segment remaining size
*
* (2) Memory pools share memory from memory segments but do NOT manage any memory
* segment information. To access the memory segment information, the head
* memory segment must be accessed via each memory pool's 'SegHeadPtr'.
*
* (b) In the diagram below, memory pools in vertical columns represent they share the same
* memory segment for the memory blocks they have. The heads of the memory pool are
* linked horizontally to form a memory pool table.
*
* (1) 'Mem_PoolTbl' points to the head of the Memory Pool table.
*
* (2) Memory Pools' 'SegPrevPtr' & 'SegNextPtr' doubly-link each memory segment to
* form the list of memory segments.
*
* (3) Memory Pools' 'PoolPrevPtr' & 'PoolNextPtr' doubly-link the memory pools of
* each memory segment.
*
* (c) New memory pools, which do not share a memory segment, are inserted in the Memory
* Segments Primary List. The point of insertion is such to keep ascended order by
* memory segment base address.
*
* (d) Memory pool pointers to memory blocks 'PoolPtrs' must be allocated for each created
* memory pool. These pointers are stored in the memory pool heap segment 'Mem_PoolHeap'.
*
* (1) A memory pool can also have its memory blocks allocated from the memory pool heap.
* 'pmem_base_addr' must be set to NULL & 'mem_size' must be set to (0) to create the
* memory pool.
*
*
* | |
* |<----------------------- Memory Segments ----------------------->|
* | (see Note #2a1) |
*
* Lowest Memory Segment Highest Memory Segment
* Base Address Base Address
* (see Note #2c) (see Note #2c)
*
* | SegNextPtr Heap Memory Pool |
* | (see Note #2b2) (see Note #2d) |
* | | |
* v | | v
* | v
* --- Head of Memory ------- ------- v ------- ------- -------
* ^ Pool Table --->| |------->| |------->| |------->| |------->| |
* | (see Note #2b1) | | | | | | | H | | |
* | | |<-------| |<-------| |<-------| E |<-------| |
* | | | | | ^ | | | A | | |
* | | | | | | | | | P | | |
* | | | | | | | | | | | |
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -