在我使用m128开发的软件当中,我将软件分成三部分:app+resource(多国语言部分相关)+bootloader.
bootloader放在后8K当中,其中的代码可以读写前面120K的flash。
app+resouce放在前120K当中,resouce是一个数组,绝对定位在一个固定地址如 0xa00, app提供菜单选择,然后调用bootloader中的程序,以修改resource的内容。
bootloader与app+resource是分别建立工程开发的。那么app如何调用bootloader中的程序呢?我选择了最简单的办法:分析bootloader的map文件,找到写flash函数的绝对地址比如是0x1F352,然后在app中直接call就可以了。需要注意以下几点:
1. bootloader中的服务函数(及其调用的其他函数)只能使用局部变量。也可用其他办法。
2. app如何传递参数:假如bootloader中的服务函数的原型是 void func(char c);则在app中可以这样调用:
void call_bootloader_func(char c){
asm("call 0x1F352");
}
app工程的链接命令为:
-Z(CODE)SEG_RESOURCE=0xa00
-Ointel-extended,(CODE)=.hex
-Ointel-extended,(XDATA)=.eep
resouce的数组定义如下:
__hugeflash unsigned char cResource[1024*38U] @"SEG_RESOURCE" =
{
#include "..\Resource\Resource.txt"
};
弊端:bootloader程序更新或重新编译后,服务函数的地址会变化,那我的app也需要升级了。
可行的方案:在bootloader中通过链接控制指定服务函数的地址。则bootloader升级,而app不用升级。进一步思考,如果avr单片机能提供类似arm的软件中断功能,实现起来更方便了,就如同linux app调用kernel提供的系统服务的方式。
以上讲的比较杂乱,不清楚的地方可以大家讨论。 |