📄 lib_mem.c
字号:
/*$PAGE*/
/*
*********************************************************************************************************
*********************************************************************************************************
* LOCAL FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* 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 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 size_tot;
/* 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). */
size_tot = mem_align_offset + ((blk_size + blk_align_offset) * (blk_nbr - 1)) + blk_size;
return (size_tot);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 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_POOL_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_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 size_tot;
CPU_SIZE_T size_rem;
CPU_CRITICAL_ENTER();
pmem_addr = (CPU_INT08U *)pmem_pool->SegAddrNextAvail;
mem_align = (CPU_SIZE_T )((CPU_ADDR)pmem_addr % align); /* Calc mem align. */
if (mem_align != 0) {
align_offset = align - mem_align;
} else {
align_offset = 0;
}
size_tot = align_offset + size;
size_rem = pmem_pool->SegSizeRem;
if (size_tot > size_rem) { /* If insufficiemt mem seg size rem, ... */
CPU_CRITICAL_EXIT();
return ((void *)0); /* ... rtn NULL. */
}
pmem_addr += align_offset; /* Adj mem addr align. */
pmem_pool->SegAddrNextAvail = pmem_addr + size; /* Adv next avail addr. */
pmem_pool->SegSizeRem -= size_tot; /* Adj rem mem seg size. */
CPU_CRITICAL_EXIT();
return ((void *)pmem_addr);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -