📄 lib_mem.c
字号:
* other validation or function handling in case of any error(s).
*********************************************************************************************************
*/
/*$PAGE*/
#if (LIB_MEM_CFG_ALLOC_EN == DEF_ENABLED)
void *Mem_HeapAlloc (CPU_SIZE_T size,
CPU_SIZE_T align,
CPU_SIZE_T *poctets_reqd,
LIB_ERR *perr)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
CPU_SR cpu_sr;
#endif
MEM_POOL *pmem_pool_heap;
void *pmem_addr;
void *pmem_blk;
CPU_SIZE_T size_rem;
CPU_SIZE_T size_req;
/* Init octets req'd for err (see Note #1). */
if (poctets_reqd != (CPU_SIZE_T *)0) {
*poctets_reqd = (CPU_SIZE_T )0;
}
/* ------------ VALIDATE HEAP MEM ALLOC ----------- */
if (size < 1) {
*perr = LIB_MEM_ERR_INVALID_MEM_SIZE;
return ((void *)0);
}
if (align < 1) {
align = 1;
}
/* -------------- ALLOC HEAP MEM BLK -------------- */
pmem_pool_heap = &Mem_PoolHeap;
CPU_CRITICAL_ENTER();
pmem_addr = pmem_pool_heap->SegAddrNextAvail;
size_rem = pmem_pool_heap->SegSizeRem;
size_req = Mem_PoolSegCalcTotSize((void *)pmem_addr,
(CPU_SIZE_T)1, /* Alloc for single mem blk from heap. */
(CPU_SIZE_T)size,
(CPU_SIZE_T)align);
if (size_req > size_rem) { /* If req'd size > rem heap size, ... */
CPU_CRITICAL_EXIT();
*perr = LIB_MEM_ERR_HEAP_EMPTY;
if (poctets_reqd != (CPU_SIZE_T *)0) {
*poctets_reqd = size_req - size_rem; /* ... rtn add'l heap size needed. */
}
return ((void *)0);
}
pmem_blk = Mem_PoolSegAlloc(pmem_pool_heap, size, align);
if (pmem_blk == (void *)0) { /* If mem blk NOT avail from heap, ... */
CPU_CRITICAL_EXIT();
*perr = LIB_MEM_ERR_HEAP_EMPTY;
if (poctets_reqd != (CPU_SIZE_T *)0) {
*poctets_reqd = size_req; /* ... rtn add'l heap size needed. */
}
return ((void *)0);
}
CPU_CRITICAL_EXIT();
*perr = LIB_MEM_ERR_NONE;
return (pmem_blk);
}
#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.
*
* (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 | | |
* | | | | | | | | | | | |
* | ------- ------- | ------- ------- -------
* | | ^ | | ^
* | | | SegPrevPtr | |
* | v | (see Note #2b2) v |
* | ------- -------
* | | | |
* Memory Pools | | | |
* (see Note #2a2) | | | |
* | | | |
* | | | | |
* | ------- -------
* | | ^
* | PoolNextPtr ---> | | <--- PoolPrevPtr
* | (see Note #2b3) v | (see Note #2b3)
* | -------
* | | |
* | | |
* | | |
* | | |
* v | |
* --- -------
*
*$PAGE*
* Argument(s) : pmem_pool Pointer to a memory pool structure to create (see Note #3).
*
* pmem_base_addr Memory pool base address :
*
* (a) Null address Memory pool allocated from general-purpose heap.
* (b) Non-null address Memory pool allocated from dedicated memory
* specified by its base address.
*
* mem_size Size of memory pool segment (in octets).
*
* blk_nbr Number of memory pool blocks to create.
*
* blk_size Size of memory pool blocks to create (in octets).
*
* blk_align Alignment of memory pool blocks to create (in octets).
*
* poctets_reqd Pointer to a variable to ... :
*
* (a) Return the number of octets required to successfully
* allocate the memory pool, if any errors;
* (b) Return 0, otherwise.
*
* perr Pointer to variable that will receive the return error code from this function :
*
* LIB_MEM_ERR_NONE Memory pool successfully created.
* LIB_MEM_ERR_NULL_PTR Argument 'pmem_pool' passed a NULL
* pointer.
*
* LIB_MEM_ERR_HEAP_NOT_FOUND Heap segment NOT found.
* LIB_MEM_ERR_HEAP_EMPTY Heap segment empty; NO available memory
* from heap.
* LIB_MEM_ERR_SEG_EMPTY Memory segment empty; NO available memory
* from segment for memory pools.
*
* LIB_MEM_ERR_INVALID_SEG_SIZE Invalid memory segment size.
* LIB_MEM_ERR_INVALID_SEG_OVERLAP Memory segment overlaps other memory
* segment(s) in memory pool table.
* LIB_MEM_ERR_INVALID_BLK_NBR Invalid memory pool number of blocks.
* LIB_MEM_ERR_INVALID_BLK_SIZE Invalid memory pool block size.
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* Note(s) : (3) 'pmem_pool' MUST be passed a pointer to the address of a declared 'MEM_POOL' variable.
*
* (4) Pointers to variables that return values MUST be initialized to return PRIOR to all
* other validation or function handling in case of any error(s).
*********************************************************************************************************
*/
#if (LIB_MEM_CFG_ALLOC_EN == DEF_ENABLED)
void Mem_PoolCreate (MEM_POOL *pmem_pool,
void *pmem_base_addr,
CPU_SIZE_T mem_size,
CPU_SIZE_T blk_nbr,
CPU_SIZE_T blk_size,
CPU_SIZE_T blk_align,
CPU_SIZE_T *poctets_reqd,
LIB_ERR *perr)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
CPU_SR cpu_sr;
#endif
MEM_POOL *pmem_pool_heap;
MEM_POOL *pmem_pool_prev;
MEM_POOL *pmem_pool_next;
MEM_POOL *pmem_pool_blk;
void **ppool_ptr;
void *pmem_blk;
CPU_INT08U *pmem_addr_ptrs;
CPU_INT08U *pmem_addr_pool;
CPU_INT08U *pmem_base_addr_start;
CPU_INT08U *pmem_base_addr_end;
CPU_INT08U *pmem_seg_addr_start;
CPU_INT08U *pmem_seg_addr_end;
CPU_SIZE_T size_tot;
CPU_SIZE_T size_tot_ptrs;
CPU_SIZE_T size_tot_pool;
CPU_SIZE_T size_rem;
CPU_SIZE_T size_pool_ptrs;
CPU_SIZE_T i;
/*$PAGE*/
/* Init octets req'd for err (see Note #4). */
if (poctets_reqd != (CPU_SIZE_T *)0) {
*poctets_reqd = (CPU_SIZE_T )0;
}
/* ----------- VALIDATE MEM POOL CREATE ----------- */
if (pmem_pool != (MEM_POOL *)0) {
/* Init mem pool for err (see Note #4). */
pmem_pool->Type = (LIB_MEM_TYPE)LIB_MEM_TYPE_NONE;
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 )0;
pmem_pool->BlkAlign = (CPU_SIZE_T )0;
pmem_pool->BlkSize = (CPU_SIZE_T )0;
pmem_pool->BlkNbr = (CPU_SIZE_T )0;
pmem_pool->BlkIx = (MEM_POOL_IX )0;
pmem_pool->SegAddr = (void *)0;
pmem_pool->SegAddrNextAvail = (void *)0;
pmem_pool->SegSizeTot = (CPU_SIZE_T )0;
pmem_pool->SegSizeRem = (CPU_SIZE_T )0;
} else {
*perr = LIB_MEM_ERR_NULL_PTR;
return;
}
if (pmem_base_addr != (void *)0) {
if (mem_size < 1) {
*perr = LIB_MEM_ERR_INVALID_SEG_SIZE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -