📄 srallo.c
字号:
#ifdef __cplusplus
extern "C" {
#endif
#include "srallo.h"
/*********************************************************************
*Example:
* ----------
* | 0x7F | 0x200 Header Seg1 (not allocated)
* | |
* | |
* | |
* | |
* | |
* | |
* | 0x89 | 0x280 Header Seg2 (allocated)
* | |
* | |
* | 0x00 | 0x30A Header Seg3 (not allocated)
* | 0x73 | 0x30B Header Seg4 (not allocated)
* | |
* | |
* | |
* | |
* | |
* | |
* | 0x80 | 0x37F Tail
* ----------
********************************************************************/
/*********************************************************************
* Reserve the memory heap
********************************************************************/
USIGN8 _uDynamicHeap[MAX_HEAP_SIZE];
/*********************************************************************
* Private function declarations
********************************************************************/
static BOOL _SRAMmerge(SALLOC *pSegA);
/*********************************************************************
* Function: unsigned char * SRAMalloc(unsigned char length)
********************************************************************/
USIGN8 *SRAMalloc(USIGN8 nBytes)
{
SALLOC *pHeap;
SALLOC segHeader;
USIGN8 segLen;
SALLOC *temp;
ENTER_CRITICAL();
// Do not allow allocation above the max minus one bytes. Also, do
// not allow a zero length packet. Could cause problems.
if ((nBytes > _MAX_SEGMENT_SIZE)||(nBytes == 0))
goto end;
// Init the pointer to the heap
pHeap = (SALLOC *)_uDynamicHeap;
while (1)
{
// Get the header of the segment
segHeader = *pHeap;
// Extract the segment length from the segment
segLen = segHeader.bits.count;
// A null segment indicates the end of the table
if (segHeader.byte == 0x80)
break;
// If this segment is not allocated then attempt to allocate it
if (!(segHeader.bits.alloc))
{
// If the free segment is too small then attempt to merge
if (segLen < nBytes)
{
// If the merge fails them move on to the next segment
if (!(_SRAMmerge(pHeap)))
{
pHeap +=(USIGN16)segHeader.bits.count + 1;
}
// Fall through so we can check the newly created segment.
}
// If the segment length matches the request then allocate the
// header and return the pointer
else if (nBytes == segLen)
{
// Allocate the segment
pHeap->bits.alloc = 1;
// Return the pointer to the caller
EXIT_CRITICAL();
return ((unsigned char *)(pHeap + 1));
}
// Else create a new segment
else
{
// Reset the header to point to a new segment
pHeap->byte = nBytes + 0x80;
// Remember the pointer to the first segment
temp = pHeap + 1;
// Point to the new segment
pHeap += (USIGN16)nBytes + 1;
// Insert the header for the new segment
pHeap->byte = segLen - nBytes - 1;
// Return the pointer to the user
EXIT_CRITICAL();
return ((unsigned char *) temp);
}
}
// else set the pointer to the next segment header in the heap
else
{
pHeap += (USIGN16)segHeader.bits.count + 1;
}
}
end:
EXIT_CRITICAL();
return (NULL);
}
/*********************************************************************
* Function: void SRAMfree(unsigned char * pSRAM)
********************************************************************/
void SRAMfree(USIGN8 *pSRAM)
{
SALLOC *pHeap, *pNextBlock;
pHeap = (SALLOC *)_uDynamicHeap;
ENTER_CRITICAL();
while(pHeap->byte != 0x80)
{
pNextBlock = pHeap + (USIGN16)pHeap->bits.count + 1U;
if(pSRAM < (USIGN8 *)pNextBlock && pSRAM > (USIGN8 *)pHeap)
{
// Release the segment
pHeap->bits.alloc = 0;
break;
}
else
pHeap = pNextBlock;
}
EXIT_CRITICAL();
}
/*********************************************************************
* Function: void SRAMInitHeap(void)
********************************************************************/
void SRAMInitHeap(void)
{
USIGN8 * pHeap;
USIGN16 count;
pHeap = _uDynamicHeap;
count = _MAX_HEAP_SIZE;
while (1)
{
if (count > _MAX_SEGMENT_SIZE)
{
*pHeap = _MAX_SEGMENT_DATA_SIZE;
pHeap += _MAX_SEGMENT_SIZE;
count = count - _MAX_SEGMENT_SIZE;
}
else
{
*pHeap = count - 1;
*(pHeap + count) = 0x80; //add tail
return;
}
}
}
/*********************************************************************
* Function: unsigned char _SRAMmerge(SALLOC * pSegA)
********************************************************************/
static BOOL _SRAMmerge(SALLOC *pSegA)
{
SALLOC * pSegB;
SALLOC uSegA, uSegB, uSum;
// Init the pointer to the heap
pSegB = pSegA + (USIGN16)(pSegA->bits.count) + 1;
// Extract the headers for faster processing
uSegA = *pSegA;
uSegB = *pSegB;
// Quit if the tail has been found
if (uSegB.byte == 0x80)
{
return (FALSE);
}
// If either segment is allocated then do not merge
if (uSegA.bits.alloc || uSegB.bits.alloc)
{
return (FALSE);
}
// If the first segment is max then nothing to merge
if (uSegA.bits.count == _MAX_SEGMENT_DATA_SIZE)
{
return (FALSE);
}
// Get the sum of the two segments
uSum.byte = (uSegA.byte + 1) + (uSegB.byte + 1);
// If the sum of the two segments are > than the largest segment
// then create a new segment equal to the max segment size and
// point to the next segments
if ((uSum.byte) > _MAX_SEGMENT_SIZE)
{
pSegA->byte = _MAX_SEGMENT_DATA_SIZE;
pSegA += _MAX_SEGMENT_SIZE;
pSegA->byte = uSum.byte - _MAX_SEGMENT_SIZE - 1;
return (TRUE);
}
// Else combine the two segments into one segment and
// do not adjust the pointers to the next segment
else
{
pSegA->byte = uSum.byte - 1;
return (TRUE);
}
}
#ifdef __cplusplus
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -