Dynamic loading in embedded sytem
来源:互联网 发布:刺客信条2优化怎么样 编辑:程序博客网 时间:2024/05/22 13:40
参考代码来源于《嵌入式系统开发之道》P378-381,对其中的注释进行了修改。另外,需要指出的是,源代码中对control table和相应的存储block的申请和释放,考虑了要和相邻块尽可能的进行合并,这样可以减少碎片。
#define TBL_WIDTH 8 /* the occupied byte numbers in a item of the control Table */
unsigned char *ansi_ucStartAlloc; /* allocate area, start address */
unsigned char *ansi_ucEndAlloc; /* allocate area, end address*/
unsigned char *ansi_ucNxtAlcP; /* next allocate address*/
unsigned char *ansi_ucTblPtr; /* next address for table*/
unsigned long ansi_ulRow; /* table count*/
/* Control Table */
typedef struct {
unsigned long ulAddrTbl;
unsigned long ulSizeTbl;
} sTable;
/* calculate pointer and size consider boundary size */
#define _BOUND(siz) ((siz + _BOUNDARY - 1) & (~(_BOUNDARY-1)))
/* shift the item to high address by one unit */
extern void ANSI_SFTR1ROW(unsigned long address, unsigned long count);
/* function : ansi_InitMalloc() */
int ansi_InitMalloc( unsigned long ulStartAlloc, unsigned long count )
{
/* allocate start address, 4 bytes boundary */
ansi_ucStartAlloc= (unsigned char *)((ulStartAlloc +3) & 0xfffffffc);
/* allocate end address, 4 bytes boundary */
ansi_ucEndAlloc= (unsigned char *)((ulEndAlloc + 3) & 0xfffffffc);
if ( ansi_ucStartAlloc + TBL_WIDTH + 8 > ansi_ucEndAlloc)
{
return -1;
}
ansi_ucNxtAlcP= ansi_ucStartAlloc; /* next allocate address */
ansi_ucTblPtr = ansi_ucEndAlloc - TBL_WIDTH; /* the start address of the control table */
ansi_ulRow = 0;
return 0;
}
/* function: malloc */
void * malloc(size_t tdsiz)
{
sTable *stTblPtr;
unsigned long ulSizeWk;
unsigned long ulAddrWk;
unsigned long ulTemp;
unsigned long ulAddrTmp;
int iErrors = 0;
int iCount;
int iRow;
if (tdsiz == 0)
{
return (void*)NULL;
}
/* table start address, now point to the last item */
stTblPtr = (sTable*)(ansi_ucEndAlloc - TBL_WIDTH);
/* the left space from the allocated memory to the control table is not enough for a TBL_WIDTH */
if(((ansi_ucTblPtr) - ansi_ucNxtAlcP ) < TBL_WIDTH)
{
errno = ENOMEM;
return (void*)NULL;
}
/* table check, top to bottom ----------------------------------*/
for ( iCount = 0; iCount < ansi_ulRow; iCount++, stTblPtr--)
{
ulTemp = stTblPtr->ulSizeTbl & 0x00000001;
// this block has not been used
if ( ulTemp == 0)
{
// this block is free area
if ( stTblPtr->ulSizeTbl >= _BOUND(tdSiz))
{
/* check memory space */
ulSizeWk = stTblPtr->ulSizeTbl - _BOUND(tdSiz);
/* reset memory size, and set the used flag to this allocated block */
stTblPtr->ulSizeTbl = _BOUND(tdSiz) | 0x1;
ulAddrWk = stTblPtr->ulAddrTbl; /* allocated address */
/* rest data size is not zero, and in fact it adds a new block */
if ( ulSizeWk > 0 )
{
ulAddrTmp = (unsigned long)(ansi_ucTblPtr);
iRow = ansi_ulRow - iCount - 1;
/* shift table data */
ANSI_SFTR1ROW( ulAddrTmp, iRow );
stTblPtr--;
stTblPtr->ulSizeTbl= ulSizeWk; /* entry, rest size */
stTblPtr->ulAddrTbl= ulAddrWk + _BOUND(tdsiz);
ansi_ucTblPtr -= TBL_WIDTH;
ansi_ulRow++;
}
return (void*)ulAddrWk;/* normal end */
}
/* memory space are insufficient, continue next row line */
}
/* not memory space, continue next row line */
}
/* the left space is not enough for a required block */
if ((ansi_ucTblPtr - ansi_ucNxtAlcP) < (_BOUND(tdsiz)+TBL_WIDTH))
{
errno = ENOMEM;
return (void*)NULL;/* can not allocate memory */
}
else
{
/* entry, new row line */
ulAddrWk = (unsigned long)ansi_ucNxtAlcP; /* allocated top address */
stTblPtr->ulAddrTbl= ulAddrWk; /* store the top addr to the control table */
stTblPtr->ulSizeTbl= _BOUND(tdsiz)| 0X1; /* store the size of the allocated block and set the used flag */
ansi_ucNxtAlcP= ansi_ucNxtAlcP + _BOUND(tdsiz); /* update the next block addr, which is free to be allocated */
ansi_ulRow++;
ansi_ucTblPtr -= TBL_WIDTH; /* next item pointer in the control table */
return (void*)ulAddrWk;
}
}
/* transfer the item to the high address by one */
void ANSI_SFTR1ROW( unsigned long address, unsigned long count )
{
int i;
unsigned long *entry = (unsigned long *)address;
unsigned long *next_entry = (unsigned long *)(address+8);
for ( i = 0; i < count ; i++ )
{
entry[i*2] = next_entry[i*2]; /* move the address of the item */
entry[i*2 + 1] = next_entry[i*2 + 1]; /* move the size of the item */
}
}
/* function : free the memory and update the control table */
void free(void *vpFrePtrP)
{
sTable *sTblPtrFre;
unsigned long ulAddrWk;
unsigned long ulSizeWk;
unsigned long ulSizeWk2;
int iLoop;
int iRowCnt;
if (vpFrePtrP == NULL)
{
return;
}
/* point to the last item of the control table */
sTblPtrFre = (void*)(ansi_ucEndAlloc - TBL_WIDTH);
/* search in the contol table and free the specified block */
for ( iLoop = 0 ; iLoop < ansi_ulRow; iLoop++, sTblPtrFre--)
{
/* found block to free */
if ( vpFrePtrP == ( sTblPtrFre->ulAddrTbl )
{
ulSizeWk = sTblPtrFre->ulSizeTbl & 0xfffffffe;
sTblPtrFre->ulSizeTbl= ulSizeWk; /* clear the flag and store the size */
/* the last data? */
if ( iLoop == ansi_ulRow - 1 )
{
ansi_ulRow--;
ansi_ucTblPtr += TBL_WIDTH;
ansi_ucNxtAlcP-= ulSizeWk;
sTblPtrFre += 1;
/* combine the neighbour free block to a new larger block */
if (( ansi_ulRow != 0 ) && (sTblPtrFre->ulSizeTbl & 0x1) == 0 )
{
ulSizeWk2 = sTblPtrFre->ulSizeTbl;
/* store the size */
sTblPtrFre->ulSizeTbl= ulSizeWk + ulSizeWk2;
ansi_ulRow--;
ansi_ucTblPtr += TBL_WIDTH;
ansi_ucNxtAlcP -= ulSizeWk2;
}
}
else
{
/* check if the previous block is free and can be merged and shift */
if (( iLoop != 0 ) && (( sTblPtrFre + 1 )->ulSizeTbl & 0x1 ) == 0 )
{
ulAddrWk = (unsigned long)sTblPtrFre;
sTblPtrFre++;
ulSizeWk = ulSizeWk + (sTblPtrFre->ulSizeTbl);
iRowCnt = ansi_ulRow - iLoop - 1;
ANSI_SFTF1ROW(ulAddrWk, iRowCnt);/* shift, table data */
ansi_ulRow--;
ansi_ucTblPtr += TBL_WIDTH;
iLoop--;
}
/* not the first item or the last one, and the next item is free block */
if ((iLoop < ansi_ulRow) && ((sTblPtrFre-1)->ulSizeTbl & 0x1) == 0 )
{
sTblPtrFre->ulSizeTbl= ulSizeWk + ((sTblPtrFre-1)->ulSizeTbl);
iLoop++;
sTblPtrFre--;
/* the number need to move */
iRowCnt = ansi_ulRow - iLoop - 1;
ulAddrWk = (unsigned long)sTblPtrFre;
ANSI_SFTF1ROW(ulAddrWk, iRowCnt);/* shift , table data */
ansi_ulRow--;
ansi_ucTblPtr += TBL_WIDTH;
}
}
return; /* normal end */
}
}
return; /* not found */
}
- Dynamic loading in embedded sytem
- Dynamic Class Loading in Java
- dynamic loading
- Dynamic loading
- Dynamic loading
- Dynamic loading
- Dynamic Loading
- dynamic Jpanel loading
- show dynamic loading process
- makefile dynamic loading
- Dynamic Memory Allocation in Critical Embedded Systems/关于嵌入式系统中的动态内存分配
- JavaScript Madness: Dynamic Script Loading
- Dynamic Page Loading for PhoneGap
- JavaScript Madness: Dynamic Script Loading
- Wi-Fi in Embedded
- Embedded DropDown in UltraGrid
- Dynamic Class Loading for C++ on Linux
- Creation, dynamic loading and instrumentation with javaagents
- form表单中的input有哪些类型及其用途
- L9 Linux特殊权限set_uid,set_gid,stick_bit,软链接和硬连接文件
- Java创建类的对象时遇到的问题1:Scanner输出输入的字符串
- @PathVariable和@RequestParam的区别【2全面版】
- Jenkins + Gradle + SonarQube 项目持续集成并分析环境搭建
- Dynamic loading in embedded sytem
- 迭代器、生成器
- 十个值得一试的开源深度学习框架
- palindrome-partitioning Java code
- Android architecture component架构
- Numpy库学习——线性代数及相关运算
- C++中的引用和指针的区别
- function power
- @RequestMapping 用法详解之地址映射 含 参数绑定(@RequestParam、 @RequestBody、 @RequestHeader 、 @PathVariable)