LPC2378在线升级实现另类思路

ji123yun   2009-8-21 21:13 楼主
注:此贴为引用贴,特贴在此处,希望大家能对此发表一些看法和认识。

希望高手们能解解其中奥秒,还有像我这样的人可以学习一下。


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,复位芯片。

回复评论 (2)

感觉下载新程序时把旧程序上传上去,并且记下更新到哪了,万一中断操作可以再从上面把程序下下来还原,这样能减少不少ROM
但是如果停电了,在来电前系统算是隔屁了

也只是想法还没实践
点赞  2009-8-21 21:27
引用原作者的话:


“如果仔细看就会看出门道,不管你是否用两块FLASH,还是一块,关键是那个分散加载文件,能让第一个扇区相同是主要的,这点清楚了,如何做升级你自己说了算。上面的方法对客户应用没有任何要求。你可不让一半空着,也一样用这种方法升级。”
点赞  2009-8-21 21:54
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复