📄 lib_mem.c
字号:
pmem_08_dest = ( CPU_INT08U *)pmem_align_dest + sizeof(CPU_ALIGN) - 1;
pmem_08_src = (const CPU_INT08U *)pmem_align_src + sizeof(CPU_ALIGN) - 1;
}
}
while (size_rem > 0) { /* For unaligned mem bufs or trailing octets, ... */
*pmem_08_dest-- = *pmem_08_src--; /* ... copy psrc to pdest by octets. */
size_rem -= sizeof(CPU_INT08U);
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* Mem_Cmp()
*
* Description : Verify that ALL data octets in two memory buffers are identical in sequence.
*
* Argument(s) : p1_mem Pointer to first memory buffer.
*
* p2_mem Pointer to second memory buffer.
*
* size Number of data buffer octets to compare (see Note #1).
*
* Return(s) : DEF_YES, if 'size' number of data octets are identical in both memory buffers.
*
* DEF_NO, otherwise.
*
* Caller(s) : Application.
*
* Note(s) : (1) Null compares allowed (i.e. zero-length compares); 'DEF_YES' returned to indicate
* identical null compare.
*
* (2) Many memory buffer comparisons vary ONLY in the least significant octets -- e.g.
* network address buffers. Consequently, memory buffer comparison is more efficient
* if the comparison starts from the end of the memory buffers which will abort sooner
* on dissimilar memory buffers that vary only in the least significant octets.
*
* (3) For best CPU performance, optimized to compare data buffers using 'CPU_ALIGN'-sized
* data words.
*
* (a) Since many word-aligned processors REQUIRE that multi-octet words be accessed on
* word-aligned addresses, 'CPU_ALIGN'-sized words MUST be accessed on 'CPU_ALIGN'd
* addresses.
*
* (4) Modulo arithmetic is used to determine whether a memory buffer starts on a 'CPU_ALIGN'
* address boundary.
*
* Modulo arithmetic in ANSI-C REQUIREs operations performed on integer values. Thus
* address values MUST be cast to an appropriately-sized integer value PRIOR to any
* 'mem_align_mod' arithmetic operation.
*********************************************************************************************************
*/
/*$PAGE*/
CPU_BOOLEAN Mem_Cmp (const void *p1_mem,
const void *p2_mem,
CPU_SIZE_T size)
{
CPU_SIZE_T size_rem;
CPU_ALIGN *p1_mem_align;
CPU_ALIGN *p2_mem_align;
const CPU_INT08U *p1_mem_08;
const CPU_INT08U *p2_mem_08;
CPU_DATA i;
CPU_DATA mem_align_mod_1;
CPU_DATA mem_align_mod_2;
CPU_BOOLEAN mem_aligned;
CPU_BOOLEAN mem_cmp;
if (size < 1) { /* See Note #1. */
return (DEF_YES);
}
if (p1_mem == (void *)0) {
return (DEF_NO);
}
if (p2_mem == (void *)0) {
return (DEF_NO);
}
mem_cmp = DEF_YES; /* Assume mem bufs are identical until cmp fails. */
size_rem = size;
/* Start @ end of mem bufs (see Note #2). */
p1_mem_08 = (const CPU_INT08U *)p1_mem + size;
p2_mem_08 = (const CPU_INT08U *)p2_mem + size;
/* See Note #4. */
mem_align_mod_1 = (CPU_INT08U)((CPU_ADDR)p1_mem_08 % sizeof(CPU_ALIGN));
mem_align_mod_2 = (CPU_INT08U)((CPU_ADDR)p2_mem_08 % sizeof(CPU_ALIGN));
mem_aligned = (mem_align_mod_1 == mem_align_mod_2) ? DEF_YES : DEF_NO;
if (mem_aligned == DEF_YES) { /* If mem bufs' alignment offset equal, ... */
/* ... optimize cmp for mem buf alignment. */
if (mem_align_mod_1 != 0u) { /* If trailing octets avail, ... */
i = mem_align_mod_1;
while ((mem_cmp == DEF_YES) && /* ... cmp mem bufs while identical & ... */
(size_rem > 0) && /* ... start mem buf cmp with trailing octets ... */
(i > 0)) { /* ... until next CPU_ALIGN word boundary. */
p1_mem_08--;
p2_mem_08--;
if (*p1_mem_08 != *p2_mem_08) { /* If ANY data octet(s) NOT identical, cmp fails. */
mem_cmp = DEF_NO;
}
size_rem -= sizeof(CPU_INT08U);
i--;
}
}
if (mem_cmp == DEF_YES) { /* If cmp still identical, cmp aligned mem bufs. */
p1_mem_align = (CPU_ALIGN *)p1_mem_08; /* See Note #3a. */
p2_mem_align = (CPU_ALIGN *)p2_mem_08;
while ((mem_cmp == DEF_YES) && /* Cmp mem bufs while identical & ... */
(size_rem >= sizeof(CPU_ALIGN))) { /* ... mem bufs aligned on CPU_ALIGN word boundaries. */
p1_mem_align--;
p2_mem_align--;
if (*p1_mem_align != *p2_mem_align) { /* If ANY data octet(s) NOT identical, cmp fails. */
mem_cmp = DEF_NO;
}
size_rem -= sizeof(CPU_ALIGN);
}
p1_mem_08 = (CPU_INT08U *)p1_mem_align;
p2_mem_08 = (CPU_INT08U *)p2_mem_align;
}
}
while ((mem_cmp == DEF_YES) && /* Cmp mem bufs while identical ... */
(size_rem > 0)) { /* ... for unaligned mem bufs or trailing octets. */
p1_mem_08--;
p2_mem_08--;
if (*p1_mem_08 != *p2_mem_08) { /* If ANY data octet(s) NOT identical, cmp fails. */
mem_cmp = DEF_NO;
}
size_rem -= sizeof(CPU_INT08U);
}
return (mem_cmp);
}
/*$PAGE*/
/*
*********************************************************************************************************
* Mem_HeapAlloc()
*
* Description : Allocate a memory block from the heap memory pool.
*
* Argument(s) : size Size of memory block to allocate (in octets).
*
* align Alignment of memory block to specific word boundary (in octets).
*
* poctets_reqd Optional pointer to a variable to ... :
*
* (a) Return the number of octets required to successfully
* allocate the memory block, if any error(s);
* (b) Return 0, otherwise.
*
* perr Pointer to variable that will receive the return error code from this function :
*
* LIB_MEM_ERR_NONE Memory block successfully returned.
* LIB_MEM_ERR_INVALID_MEM_SIZE Invalid memory size.
* LIB_MEM_ERR_INVALID_MEM_ALIGN Invalid memory alignment.
* LIB_MEM_ERR_HEAP_EMPTY Heap segment empty; NOT enough available
* memory from heap.
* LIB_MEM_ERR_HEAP_OVF Requested memory overflows heap memory.
*
* Return(s) : Pointer to memory block, if NO error(s).
*
* Pointer to NULL, otherwise.
*
* Caller(s) : Application.
*
* Note(s) : (1) Pointers to variables that return values MUST be initialized PRIOR to all other
* validation or function handling in case of any error(s).
*
* (2) 'pmem_pool' variables MUST ALWAYS be accessed exclusively in critical sections.
*********************************************************************************************************
*/
/*$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)
{
MEM_POOL *pmem_pool_heap;
void *pmem_addr;
void *pmem_blk;
CPU_SIZE_T octets_reqd_unused;
CPU_SIZE_T size_rem;
CPU_SIZE_T size_req;
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((void *)0);
}
#endif
/* ------------ VALIDATE RTN OCTETS PTR ----------- */
if (poctets_reqd == (CPU_SIZE_T *) 0) { /* If NOT avail, ... */
poctets_reqd = (CPU_SIZE_T *)&octets_reqd_unused; /* ... re-cfg NULL rtn ptr to unused local var. */
(void)&octets_reqd_unused; /* Prevent possible 'variable unused' warning. */
}
*poctets_reqd = 0u; /* Init octets req'd for err (see Note #1). */
#if (LIB_MEM_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* ------------ VALIDATE HEAP MEM ALLOC ----------- */
if (size < 1) {
*perr = LIB_MEM_ERR_INVALID_MEM_SIZE;
return ((void *)0);
}
if (align < 1) {
*perr = LIB_MEM_ERR_INVALID_MEM_ALIGN;
return ((void *)0);
}
#endif
/* -------------- 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_SegCalcTotSize(pmem_addr,
1u, /* Calc alloc for single mem blk from heap. */
size,
align);
#if (LIB_MEM_CFG_ARG_CHK_EXT_EN == DEF_ENABLED)
if (size_req < 1) { /* If req'd size ovf, ... */
CPU_CRITICAL_EXIT();
*poctets_reqd = size; /* ... rtn add'l heap size needed. */
*perr = LIB_MEM_ERR_HEAP_OVF;
return ((void *)0);
}
#endif
if (size_req > size_rem) { /* If req'd size > rem heap size, ... */
CPU_CRITICAL_EXIT();
*poctets_reqd = size_req - size_rem; /* ... rtn add'l heap size needed. */
*perr = LIB_MEM_ERR_HEAP_EMPTY;
return ((void *)0);
}
pmem_blk = Mem_SegAlloc(pmem_pool_heap, size, align);
if (pmem_blk == (void *)0) { /* If mem blk NOT avail from heap, ... */
CPU_CRITICAL_EXIT();
*poctets_reqd = size_req; /* ... rtn add'l heap size needed. */
*perr = LIB_MEM_ERR_HEAP_EMPTY;
return ((void *)0);
}
CPU_CRITICAL_EXIT();
*perr = LIB_MEM_ERR_NONE;
return (pmem_blk);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* Mem_HeapGetSizeRem()
*
* Description : Get remaining heap memory size available to allocate.
*
* Argument(s) : 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 :
*
* ---- RETURNED BY Mem_PoolGetSizeRem() : ----
* LIB_MEM_ERR_NONE Heap memory pool remaining size successfully
* returned.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -