初级会员

- 积分
- 61
- 金钱
- 61
- 注册时间
- 2012-3-18
- 在线时间
- 2 小时
|
发表于 2012-3-22 11:05:38
|
显示全部楼层
算是把api实现了,目前的实现方法如下,没考虑多任务函数重入的问题,所以尽量不要在api中使用全局变量
。。。跳转到loader
。。。
。。。函数指针,指向各个api函数,我是用void (*)(void)型的数组api[]存储的,不是这种类型的api函数强制转换一下就可以了。
。。。通过链接脚本,使得api[]被放在PC复位指针+0x4的位置
。。。
…………
。。。
。。。api实现代码,其存放位置没有特殊要求,在api[]之后即可
。。。
…………
以上即为api的结构。api代码
//start.s
.global _start
_start:
//lib.c
int sum(int, int);
void *memcpy(void *, void *, int);
void (*api[])(void) __attribute__((section(".API"))) =
{
(void (*)(void))sum,
(void (*)(void))memcpy,
};
int sum(int x, int y)
{
return x+y;
}
void *memcpy(void *_des, void *_src, int len)
{
char *des = _des;
char *src = _src;
int i;
for(i=0;i<len;i++){
*des++ = *src++;
}
return _des;
}
api链接脚本,这里假设pc复位后从0x0开始取指令
SECTIONS
{
.API ALIGN(0x4):
{
. = 0x4;
}
.text ALIGN(0x4): { *(.text) }
.bss ALIGN(0x4): { *(.bss) }
}
编译后再将生成的文件转换为binary文件即是被放入flash的api库文件。
以下为接口文件,这个文件编译后生成的目标文件是用来与使用api的目标文件进行链接的
//memcpy.c
void *(*memcpy)(void *, void *, int len) = 0x08; //0x08是api数组地址+memcpy在api数组里的偏移。
//memcpy.h
void *(*memcpy)(void *, void *, int len);
应用程序,需要为应用程序也写一个链接脚本
//main.c
#include "memcpy.h"
int main(void)
{
memcpy((void*)12, (void*)24, 20);
return 0;
}
由于api指针的位置和排列是固定的,所以无论应用程序被放到哪个位置运行,均能调用到api函数。只要保持接口不变,即使更改库的实现或者增加库代码,应用程序也不需要重新链接
|
|