27,508
社区成员




__global_reg(6) unsigned int *StaticVariableRelocate;
extern unsigned int *DynamicStaticVar=0;// Ö¸ÏòdllµÄ¾²Ì¬±äÁ¿
extern unsigned int HostStaticVar = 0x123455AA;
Fun DelayUs = 0;
TFun RunHostFun = 0;
NFun StaticVarInit = 0;
static unsigned int DLL_Len = 0;
static unsigned int DLL_Version = 0;
static unsigned int __attribute__((aligned(8))) DynamicRAM[SIZE_MEM_INT];
extern void DynamicLoader(unsigned int AddrDynamicLinkLib)
{
unsigned int *dst,*src;
unsigned int *RAM_ADDRESS_DLY = (unsigned int *)DynamicRAM;
unsigned int DLL_Static_len,DLL_Static_offset_addr;
unsigned int i;
DLL_Len = *((unsigned int *)AddrDynamicLinkLib);// 从DLL首地址获取文件长度
DLL_Version = *((unsigned int *)(AddrDynamicLinkLib + 4));// 获取DLL版本号
DLL_Static_offset_addr = *((unsigned int *)(AddrDynamicLinkLib + 8));// 获取动态库中静态变量区的首地址
DLL_Static_len = DLL_Len - DLL_Static_offset_addr;//动态链接库的静态区全长
//在RAM中为DLL分配静态变量区,或者说创建DLL的RW的运行域
for(i = 0,dst = RAM_ADDRESS_DLY,src = (unsigned int *)(AddrDynamicLinkLib + DLL_Static_offset_addr); i < ((DLL_Static_len / 4) + 1); i ++){
*dst ++= *src ++;
}
// 初始化宿主程序中需要用到的DLL函数地址
DelayUs = (Fun) (Name2Addr(AddrDynamicLinkLib,"DelayUs",7) + (unsigned int)AddrDynamicLinkLib);
RunHostFun = (TFun) (Name2Addr(AddrDynamicLinkLib,"RunHostFun",10) + (unsigned int)AddrDynamicLinkLib);
StaticVarInit = (NFun) (Name2Addr(AddrDynamicLinkLib,"StaticVarInit",13) + (unsigned int)AddrDynamicLinkLib);
StaticVariableRelocate = (unsigned int *)((unsigned int)RAM_ADDRESS_DLY); //重定向RW的地址,但地址值原则不明
StaticVarInit((unsigned int)LED_B_Control,&DynamicStaticVar,&HostStaticVar);
}
AREA FunctionArray, DATA, READONLY, ALIGN=0
Fun_Start
DCD 0x000000C4 ;//动态库的长度
DCD 0x00000007 ;//动态库版本
DCD 0x080040B4 - 0x08004000 ;// 静态变量的偏移地址
DCB "DelayUs"
DCB "%" ;注意要用%或&填充空缺,把下面的DCD指令顶到4倍地址处。如果是Thumb Code,用%。如果是ARM Code,用&
DCD 0x0800403C - 0x08004000 + 1 ;是Thumb Code的话,加1
DCB "RunHostFun"
DCB "%%" ;
DCD 0x08004054 - 0x08004000 + 1 ;
DCB "StaticVarInit"
DCB "%%%" ;
DCD 0x08004094 - 0x08004000 + 1 ;
END
unsigned int Name2Addr(unsigned int addr,unsigned char *src,unsigned char len)
{
unsigned char *targ = (unsigned char *)(addr);
unsigned int i = 8,j;
FindHead:
for(j = 0; i < DLL_Len; i ++){//
if(src[j] == targ[i]){
j ++;
i ++;
break;
}
}
if((i + len) < DLL_Len){//
}else{
return 0;
}
for(; j < len; j ++,i++){
if(src[j] != targ[i]){
goto FindHead;
}
}
if(j == len){//
if('%' == targ[i]){ //
while(1){
if(targ[i]!= '%'){ ///
break;
}else{
i ++;
}
}
if((i+4)<DLL_Len){//
return ( (targ[i+0] << 8*0) |
(targ[i+1] << 8*1) |
(targ[i+2] << 8*2) |
(targ[i+3] << 8*3) );
}
}
}
return 0;
}