📄 lib_mem.c
字号:
*perr = LIB_MEM_ERR_POOL_EMPTY;
return ((void *)0);
}
if (pmem_pool->BlkIx > pmem_pool->BlkNbr) {
CPU_CRITICAL_EXIT();
*perr = LIB_MEM_ERR_INVALID_BLK_IX;
return ((void *)0);
}
/* ------------ GET MEM BLK FROM POOL ------------- */
pmem_pool->BlkIx--;
pmem_blk = pmem_pool->PoolPtrs[pmem_pool->BlkIx];
CPU_CRITICAL_EXIT();
*perr = LIB_MEM_ERR_NONE;
return (pmem_blk);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* Mem_PoolBlkFree()
*
* Description : Free a memory block to memory pool.
*
* Argument(s) : pmem_pool Pointer to memory pool to free memory block.
*
* pmem_blk Pointer to memory block address to free.
*
* perr Pointer to variable that will receive the return error code from this function :
*
* LIB_MEM_ERR_NONE Memory block successfully freed.
* LIB_MEM_ERR_POOL_FULL ALL memory blocks already available in
* memory pool.
*
* LIB_MEM_ERR_NULL_PTR Argument 'pmem_pool'/'pmem_blk' passed
* a NULL pointer.
* LIB_MEM_ERR_INVALID_POOL Invalid memory pool type.
* LIB_MEM_ERR_INVALID_BLK_ADDR Invalid memory block address.
* LIB_MEM_ERR_INVALID_BLK_ADDR_IN_POOL Memory block address already
* in memory pool.
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* Note(s) : none.
*********************************************************************************************************
*/
/*$PAGE*/
#if (LIB_MEM_CFG_ALLOC_EN == DEF_ENABLED)
void Mem_PoolBlkFree (MEM_POOL *pmem_pool,
void *pmem_blk,
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)
CPU_BOOLEAN addr_valid;
MEM_POOL_IX i;
#endif
/* ------------ VALIDATE MEM POOL FREE ------------ */
if (pmem_pool == (MEM_POOL *)0) {
*perr = LIB_MEM_ERR_NULL_PTR;
return;
}
if (pmem_blk == (void *)0) {
*perr = LIB_MEM_ERR_NULL_PTR;
return;
}
CPU_CRITICAL_ENTER();
if (pmem_pool->Type != LIB_MEM_TYPE_POOL) {
CPU_CRITICAL_EXIT();
*perr = LIB_MEM_ERR_INVALID_POOL;
return;
}
if (pmem_pool->BlkIx >= pmem_pool->BlkNbr) {
CPU_CRITICAL_EXIT();
*perr = LIB_MEM_ERR_POOL_FULL;
return;
}
#if (LIB_MEM_CFG_ARG_CHK_EXT_EN == DEF_ENABLED)
addr_valid = Mem_PoolBlkIsValidAddr(pmem_pool, pmem_blk);
if (addr_valid != DEF_OK) {
CPU_CRITICAL_EXIT();
*perr = LIB_MEM_ERR_INVALID_BLK_ADDR;
return;
}
for (i = 0; i < pmem_pool->BlkIx; i++) {
if (pmem_blk == pmem_pool->PoolPtrs[i]) {
CPU_CRITICAL_EXIT();
*perr = LIB_MEM_ERR_INVALID_BLK_ADDR_IN_POOL;
return;
}
}
#endif
/* ------------- FREE MEM BLK TO POOL ------------- */
pmem_pool->PoolPtrs[pmem_pool->BlkIx] = pmem_blk;
pmem_pool->BlkIx++;
CPU_CRITICAL_EXIT();
*perr = LIB_MEM_ERR_NONE;
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
*********************************************************************************************************
* LOCAL FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* Mem_PoolBlkIsValidAddr()
*
* Description : Calculates if a given memory block address is valid for the memory pool.
*
* Argument(s) : pmem_pool Pointer to memory pool structure to validate memory block address.
* --------- Argument validated in Mem_PoolBlkFree().
*
* pmem_blk Pointer to memory block address to validate.
* -------- Argument validated in Mem_PoolBlkFree().
*
* Return(s) : DEF_YES, if valid memory pool block address.
*
* DEF_NO, otherwise.
*
* Caller(s) : Mem_PoolBlkFree().
*
* Note(s) : none.
*********************************************************************************************************
*/
#if ((LIB_MEM_CFG_ALLOC_EN == DEF_ENABLED) && \
(LIB_MEM_CFG_ARG_CHK_EXT_EN == DEF_ENABLED))
static CPU_BOOLEAN Mem_PoolBlkIsValidAddr (MEM_POOL *pmem_pool,
void *pmem_blk)
{
CPU_INT08U *ppool_addr_first;
void *ppool_addr_start;
void *ppool_addr_end;
CPU_SIZE_T align_offset;
CPU_SIZE_T blk_align;
CPU_SIZE_T blk_align_offset;
CPU_SIZE_T blk_size;
CPU_SIZE_T mem_align;
CPU_SIZE_T mem_align_offset;
CPU_SIZE_T mem_diff;
CPU_BOOLEAN addr_valid;
ppool_addr_start = pmem_pool->PoolAddrStart;
ppool_addr_end = pmem_pool->PoolAddrEnd;
if ((pmem_blk < ppool_addr_start) ||
(pmem_blk > ppool_addr_end)) {
return (DEF_NO);
}
blk_align = (CPU_SIZE_T)pmem_pool->BlkAlign;
align_offset = (CPU_SIZE_T)((CPU_ADDR)ppool_addr_start % blk_align);
if (align_offset != 0) {
mem_align_offset = blk_align - align_offset;
} else {
mem_align_offset = 0;
}
blk_size = pmem_pool->BlkSize;
align_offset = blk_size % blk_align;
if (align_offset != 0) {
blk_align_offset = blk_align - align_offset;
} else {
blk_align_offset = 0;
}
ppool_addr_first = (CPU_INT08U *)((CPU_INT08U *)ppool_addr_start + mem_align_offset);
mem_diff = (CPU_SIZE_T )((CPU_INT08U *)pmem_blk - ppool_addr_first);
mem_align = (CPU_SIZE_T )( blk_size + blk_align_offset);
addr_valid = ((mem_diff % mem_align) == 0) ? DEF_YES : DEF_NO;
return (addr_valid);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* Mem_PoolSegCalcTotSize()
*
* Description : (1) Calculates total memory segment size for number of blocks with specific size & alignment :
*
*
* ----- ====================== ---
* ^ Mem Addr ---> | / / / / / / | ^
* | (see Note #1a) | / / / / / / /| | Mem Align Offset
* | |/ / / / / / / | | (see Notes #1e & #2a)
* | | / / / / / / | v
* | ====================== ---
* | | | ^
* | | | |
* | | Mem Blk #1 | | Blk Size
* | | | | (see Note #1c)
* | | | v
* | ---------------------- ---
* | | / / / / / / | ^
* | | / / / / / / /| | Blk Align Offset
* | |/ / / / / / / | | (see Notes #1f & #2b)
* | | / / / / / / | v
* | ====================== ---
* | . |
* Total Size | . |
* (see Note #2c) | . |
* ====================== ---
* | | | ^
* | | | |
* | | Mem Blk #N - 1 | | Blk Size
* | | | | (see Note #1c)
* | | | v
* | ---------------------- ---
* | | / / / / / / | ^
* | | / / / / / / /| | Blk Align Offset
* | |/ / / / / / / | | (see Notes #1f & #2b)
* | | / / / / / / | v
* | ====================== ---
* | | | ^
* | | | |
* | | Mem Blk #N | | Blk Size
* | | | | (see Note #1c)
* v | | v
* ----- ====================== ---
*
* where
*
* (a) Mem Addr Memory address of the beginning of the memory block ('pmem_addr')
*
* (b) N Number of memory blocks to allocate ('blk_nbr')
*
* (c) Blk Size Size of memory block to allocate ('blk_size')
*
* (d) Align Required block memory alignment ('blk_align')
*
* (e) Mem Align Offset Offset required to align first memory block
*
* (f) Blk Align Offset Offset required to align every memory block
*
*
* (2) The total size is calculated based on the following equations :
*
* { (1) Align - (Mem Addr % Align) , if memory address is not aligned
* (a) Mem Align Offset = {
* { (2) 0 , if memory address is aligned
*
*
* { (1) Align - (Size % Align) , if memory block is not aligned
* (b) Blk Align Offset = {
* { (2) 0 , if memory block is aligned
*
*
* (c) Total Size = Mem Align Offset
* + ((Blk Size + Blk Align Offset) * (N - 1))
* + Blk Size
*
*$PAGE*
* Argument(s) : pmem_addr Memory address of the beginning of the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -