注:此贴为引用贴,特贴在此处,希望大家能对此发表一些看法和认识。
希望高手们能解解其中奥秒,还有像我这样的人可以学习一下。
LPC2378在线升级实现
一、
概述
在线升级要求正在执行的程序对自己进行升级,如何能可靠升级,如升级失败可以回到原来程序继续执行,本文介绍一种简单容易做到不影响应用的方法。
二、
实现方法分析
先看下面的图,把程序空间分为三部分,这是容易理解的分配,
有人问了,这是不是要写一个引导程序,答案是:不用,就用你自己的应用程序,只是巧妙使用分散加载进行编译,把程序分别编译到不同地址就可以了。
0x00040000
高地址区(HighAddr):256k
0x00008000
低地址区(LowAddr):224k
0x00000000
共用代码 32k
我们现在看一下分散加载文件:
分散加载文件1 ------低端地址
ROM_LOAD 0x00000000 0x1000
{
ROM_EXEC 0x00000000{
;中断向量表
Startup.o (RESET, +First);//*.o (RESET, +First)
}
}
ROM_LOAD1 0x00004000 0x2000
{
ROM_EXEC1 0x00004000{
__main.o(+RO)
__scatter.o
(+RO)
__scatter_zi.o(+RO)
lib_init.o(+RO)
irq.o(+RO)
target.o(+RO)
timer.o(+RO)
swi_handler.o(+RO)
comm_arm.o(+RO)
}
}
ROM_LOAD2 0x00008000
0x40000;
//加载映像文件,从第0x00001000开始
{
ROM_EXEC2 0x00008000 {
* (+RO)
}
RW_IRAM1 0x40000000 0x00008000
{
; RW data
* (+RW +ZI)
}
}
分散加载文件2 ------高端地址
ROM_LOAD 0x00000000 0x1000
{
ROM_EXEC 0x00000000{
;中断向量表
Startup.o (RESET, +First)
}
}
ROM_LOAD1 0x00004000 0x2000
{
ROM_EXEC1 0x00004000{
__main.o(+RO)
__scatter.o
(+RO)
__scatter_zi.o(+RO)
lib_init.o(+RO)
irq.o(+RO)
target.o(+RO)
timer.o(+RO)
swi_handler.o(+RO)
comm_arm.o(+RO)
}
}
ROM_LOAD2 0x00040000
0x40000 ;加载映像文件,从第0x00040000开始
{
ROM_EXEC2 0x00040000 {
* (+RO)
}
RW_IRAM1 0x40000000 0x00008000
{
; RW data
* (+RW +ZI)
}
}
低地址程序空间占用:
0x0000 0000 --- 0x0000 0FFF 4k 和高端重用 B1
0x0000 1000 --- 0x0000 1FFF 4K B2
0x0000 2000 --- 0x0000 3FFF 8k未用 B3
0x0000 4000 --- 0x0000 5FFF 8k和 高端重用 B4
0x0000 6000 --- 0x0000 7FFF 8k未用 B5
0x0000 8000 --- 0x0003 FFFF 224K 低端 B6
0x0004 0000 --- 0x0007 FFFF 256k未用 B7
低端用:B1、B4、B6
高地址程序空间占用:
0x0000 0000 --- 0x0000 0FFF 4k和低端重用 B1
0x0000 1000 --- 0x0000 1FFF 4K B2
0x0000 2000 --- 0x0000 3FFF 8k未用 B3
0x0000 4000 --- 0x0000 5FFF 8k和低端重用 B4
0x0000 6000 --- 0x0000 7FFF 8k未用 B5
0x0000 8000 --- 0x0003 FFFF 224K 未用 B6
0x0004 0000 --- 0x0007 FFFF 256k高端 B7
高端用:B1、B4、B7
为什么要这么做?我们对比两个编译好的文件发现:
1、 B1 的内容两个文件完全一样。
2、 B4的内容有个别不同, 两个文件B4内容放在同一块内的目的是为让B1相同
3、 B6和B7不同。
这样编译好的两个文件就可以互相升级,因为两个文件第一个扇区相同,向量表一样,升级时第一扇区不用改写,低端的B4可以备份到B3, 高端的B4可以备份到B5, 这样两个程序同时存在,B2来标识正在运行的程序是高端还是低端。 如想改变高低端的程序运行,只要把备份的B3或B5重写到B4然后复位芯片就可以了。
所以升级时写FLASH过程如下:
1、 收到B4的部份,如为高端写在B5,低端则写在B3
2、 B6或B7内容直接按地址写入
3、 全部校验成功后,把B3或B5的内容复制B4,复位芯片。
感觉下载新程序时把旧程序上传上去,并且记下更新到哪了,万一中断操作可以再从上面把程序下下来还原,这样能减少不少ROM
但是如果停电了,在来电前系统算是隔屁了
也只是想法还没实践
引用原作者的话:
“如果仔细看就会看出门道,不管你是否用两块FLASH,还是一块,关键是那个分散加载文件,能让第一个扇区相同是主要的,这点清楚了,如何做升级你自己说了算。上面的方法对客户应用没有任何要求。你可不让一半空着,也一样用这种方法升级。”