📄 lib_mem.c
字号:
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;
}
pmem_blk_end = (void *)((CPU_INT08U *)pmem_pool->PoolAddrEnd - pmem_pool->BlkSize + 1);
#if 0 /* !!!! */
if ((pmem_addr < pmem_pool->PoolAddrStart) ||
(pmem_addr > pmem_blk_end)) {
CPU_CRITICAL_EXIT();
*perr = LIB_MEM_ERR_INVALID_ADDR;
return;
}
#endif
#if (LIB_MEM_CFG_ARG_CHK_EXT_EN == DEF_ENABLED)
if (Mem_PoolBlkCalcValidAddr(pmem_pool, pmem_addr) == DEF_FALSE) {
CPU_CRITICAL_EXIT();
*perr = LIB_MEM_ERR_INVALID_ADDR;
return;
}
for (i = 0; i < pmem_pool->BlkIx; i++) {
if (pmem_pool->PoolPtrs[i] == pmem_addr) {
CPU_CRITICAL_EXIT();
*perr = LIB_MEM_ERR_INVALID_ADDR;
return;
}
}
#endif
pmem_pool->PoolPtrs[pmem_pool->BlkIx] = pmem_addr;
pmem_pool->BlkIx++;
CPU_CRITICAL_EXIT();
*perr = LIB_ERR_NONE;
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
*********************************************************************************************************
* LOCAL FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* Mem_PoolSegGetBlkSize()
*
* Description : (1) Calculates total memory segment size for number of blocks with specific size and 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 computed based on the following expressions :
*
* { (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 + ((Size + Blk Align Offset) * (N - 1)) + Size
*
*$PAGE*
* Argument(s) : pmem_addr Memory address of the beginning of the memory block.
*
* blk_nbr Number of memory blocks to allocate.
*
* blk_size Size of memory block to allocate.
*
* blk_align Required block memory alignment (in octets).
* --------- Argument validated in Mem_PoolCreate().
*
* Return(s) : Total size of memory segment used to allocate the number of blocks.
*
* Caller(s) : Mem_PoolCreate().
*
* Note(s) : none.
*********************************************************************************************************
*/
#if (LIB_MEM_CFG_POOL_EN == DEF_ENABLED)
static CPU_SIZE_T Mem_PoolSegCalcTotSize (void *pmem_addr,
CPU_SIZE_T blk_nbr,
CPU_SIZE_T blk_size,
CPU_SIZE_T blk_align)
{
CPU_SIZE_T align_offset;
CPU_SIZE_T mem_align_offset;
CPU_SIZE_T blk_align_offset;
CPU_SIZE_T tot_size;
/* Calc mem align (see Note #2a). */
align_offset = (CPU_ADDR)pmem_addr % blk_align;
if (align_offset != 0) {
mem_align_offset = blk_align - align_offset;
} else {
mem_align_offset = 0;
}
/* Calc blk align (see Note #2b). */
align_offset = blk_size % blk_align;
if (align_offset != 0) {
blk_align_offset = blk_align - align_offset;
} else {
blk_align_offset = 0;
}
/* Calc tot size (see Note #2c). */
tot_size = mem_align_offset + ((blk_size + blk_align_offset) * (blk_nbr - 1)) + blk_size;
return (tot_size);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* Mem_PoolBlkCalcValidAddr()
*
* 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_addr Pointer to memory block address to validate.
* --------- Argument validated in Mem_PoolBlkFree()
*
* Return(s) : DEF_TRUE, if NO errors.
*
* DEF_FALSE, otherwise.
*
* Caller(s) : Mem_PoolBlkFree().
*
* Note(s) : only available if LIB_MEM_CFG_ARG_CHK_EXT_EN is enabled.
*********************************************************************************************************
*/
#if (LIB_MEM_CFG_POOL_EN == DEF_ENABLED) && \
(LIB_MEM_CFG_ARG_CHK_EXT_EN == DEF_ENABLED)
static CPU_SIZE_T Mem_PoolBlkCalcValidAddr (MEM_POOL *pmem_pool,
void *pmem_addr)
{
CPU_INT08U *pmem_start;
CPU_INT08U *pmem_pool_addr;
CPU_SIZE_T align_offset;
CPU_SIZE_T mem_diff;
CPU_SIZE_T mem_align;
CPU_SIZE_T mem_align_offset;
CPU_SIZE_T blk_align;
CPU_SIZE_T blk_align_offset;
CPU_SIZE_T blk_size;
if (pmem_pool->PoolAddrStart > pmem_addr) {
return (DEF_FALSE);
}
blk_align = (CPU_SIZE_T )pmem_pool->BlkAlign;
pmem_pool_addr = (CPU_INT08U *)pmem_pool->PoolAddrStart;
align_offset = (CPU_ADDR )pmem_pool_addr % 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;
}
pmem_start = pmem_pool_addr + mem_align_offset;
mem_align = blk_size + blk_align_offset;
mem_diff = (CPU_INT08U *)pmem_addr - pmem_start;
if ((mem_diff % mem_align) == 0) {
return (DEF_TRUE);
} else {
return (DEF_FALSE);
}
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* Mem_PoolSegAlloc()
*
* Description : Allocates memory from specific segment.
*
* Argument(s) : pmem_pool Pointer to memory pool structure containing segment information.
* --------- Argument validated in Mem_PoolCreate()
*
* size Size of memory to allocate.
* ---- Argument validated in Mem_PoolCreate()
*
* align Required starting memory alignment (in octets).
* ----- Argument validated in Mem_PoolCreate()
*
* Return(s) : Pointer to allocated memory, if NO errors.
*
* Pointer to NULL, otherwise.
*
* Caller(s) : Mem_PoolCreate().
*
* Note(s) : (1) Allocated memory from the specific segment is NEVER freed after allocation.
*********************************************************************************************************
*/
#if (LIB_MEM_CFG_POOL_EN == DEF_ENABLED)
static void *Mem_PoolSegAlloc (MEM_POOL *pmem_pool,
CPU_SIZE_T size,
CPU_SIZE_T align)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
CPU_SR cpu_sr;
#endif
CPU_INT08U *pmem_addr;
CPU_SIZE_T mem_align;
CPU_SIZE_T align_offset;
CPU_SIZE_T tot_size;
CPU_SIZE_T size_rem;
CPU_CRITICAL_ENTER();
pmem_addr = (CPU_INT08U *)pmem_pool->SegAddrNextAvail; /* Get next avail addr in mem seg. */
mem_align = ((CPU_ADDR)pmem_addr) % align; /* Calc mem align. */
if (mem_align != 0) {
align_offset = align - mem_align;
} else {
align_offset = 0;
}
tot_size = align_offset + size;
size_rem = pmem_pool->SegSizeRem;
if (tot_size > size_rem) { /* Do not alloc if size extends beyond mem seg. */
CPU_CRITICAL_EXIT();
return ((void *)0);
}
pmem_addr += align_offset; /* Adj mem addr align. */
pmem_pool->SegAddrNextAvail = pmem_addr + size; /* Advance next avail addr depending on alloc size. */
pmem_pool->SegSizeRem -= tot_size; /* Adj rem mem seg size. */
CPU_CRITICAL_EXIT();
return ((void *)pmem_addr);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -