一、资源:
LPC2378(ARM7内核),
IDE:KEIL,或者ADS
二、实现:
建立两个工程,也就是说包含独立的MAIN函数,包含独立的中断向量表(地址不同),编译后烧录到指定的不重复的地址处。
这样可以实现任意升级功能,任意切换某一执行区,且互不依赖。
三、如何运行:
通过烧录在0x0地址处的简单BOOTLOADER代码决定要启动哪个地址区域的代码。
四、BOOTLOADER要做的:
在BOOTLOADER代码中将中断向量表得到到RAM,然后重新映射到RAM。然后通过指针跳转到需要等等的区域。
五、存在的问题:
通过BOOTLOADER复制中断向量表并做重新映射再配合分散加载文件,可以实现不同区域的切换,可跳转到指定的地址处执行,但运行到某处就死掉,不能正常运行起来。
六、问题分析:
估计还是因为中断向量表重映射的问题。
七、求助:
请教高手:中断向量表的重映射和复制正确的做法是怎么样的?中断向量表复制后,中断处理程序的地址是否还要处理?
下面是我写的中断向量表复制的代码以及RAM重映射,请大家指正。
(代码思路来源于ZLG深圳分公司工程师的指导)
/******************************************************
* bootloader中检测试标志位决定启动哪个区域的代码
* 复制中断向量表并重新映射
*
*******************************************************/
typedef void (*func_t)(void);
func_t ptr;
void checkFlag(void)
{
int i;
unsigned char *pc = (unsigned char *)0x0007d000;
unsigned int *pram = (unsigned int *)0x40000000;
unsigned int *webup = (unsigned int *)0x00003800;
unsigned int *uartaddr = (unsigned int *)0x00001000;
if ((pc[0] == 0x02) &&
(pc[1] == 0x02) &&
(pc[2] == 0x09) &&
(pc[3] == 0x20))
{
for(i=0;i<8;i++)
{
*(pram+i) = *(uartaddr+i); //复制8*4字节的中断向量表
//到RAM:0x40000000
}
MEMMAP = 2;
ptr = (func_t)uartaddr; //跳转到uartaddr地址处运行这个区域的代码
(*ptr)();
}
else if ((pc[0] == 0x01) &&
(pc[1] == 0x01) &&
(pc[2] == 0x09) &&
(pc[3] == 0x20))
{
for(i=0;i<8;i++)
{
*(pram+i) = *(webup+i);
}
MEMMAP = 2;
ptr = (func_t)0x00003800;
(*ptr)();
}
}
下面为第一个工程中的分散加载文件:
BOOT_LOAD 0x00000000
{
BOOT 0x00000000
{
bootentry.o (BOOTS, +First) ;这部分为检测标志位,处理中断向量表复制
boot.o(+RO) ;和重新映射并跳转的代码
}
}
OS_LOAD 0x00003800
{
WEBUPGRADE_EXE 0x00003800 FIXED
{ ;这个工程的中断向量表,因为这个工程被放在0x3800处,所以它的中断向量 ;表放在这个区域的最开始处
vectors.o (VECT, +First)
init.o (INIT)
}
ROM2_EXE +0
{
*(+RO)
}
RW_IRAM1 0x40000020 0x00007000
{
* (+RW,+ZI)
}
ARM_LIB_HEAP 0x40007000 EMPTY 0x00000100 {}
ARM_LIB_STACK 0x40008000 EMPTY -0x00000E00 {}
}
;---------------------------------------------------------
下面为第二个工程的分散加载文件:
OS_LOAD 0x00030000 ;放在地址0x30000处的第二个工程的代码
{
WEBUPGRADE_EXE 0x00030000 FIXED
{ ;中断向量表
vectors.o (VECT, +First)
init.o (INIT)
}
ROM2_EXE +0
{
*(+RO)
}
RW_IRAM1 0x40000020 0x00007000
{
* (+RW,+ZI)
}
ARM_LIB_HEAP 0x40007000 EMPTY 0x00000100 {}
ARM_LIB_STACK 0x40008000 EMPTY -0x00000E00 {}
}
八、总结:
请大家在这里讨论一下,指点一下,谢谢。
bootlaod 里,不能只单独拷贝中断向量表吧,应该连CODE 和data 一起拷贝吧
这个需求很特殊啊 mark围观 一起学习
感觉上肯定是可行的,但是中断向量表着实很棘手,是不是可以试试用相同的中断向量表,然后把中断服务程序入口处做跳转,跳向不同的地址,完成真正的中断服务程序再返回
LS的朋友的思路貌似可行。
我是在想,就像我们的电脑一样,我们装个XP,可以运行,再装个LINUX一样能运行。
在LPC2378上应该也可行,说白了,不都是两包代码吗。
重启切换着运行应该没问题啊。