我为我的 SAM4S 编写了一个引导加载程序,它位于扇区 0 并在扇区 1 中加载应用程序。但是问题是,当我尝试跳转到新函数时,它似乎会生成异常(调试器转到 Dummy_Handler()) .
Bootloader 在映射中包含以下条目:
.application 0x00410000 0x0
0x00410000 . = ALIGN (0x4)
0x00410000 _sappl = .
0x00410004 _sjump = (. + 0x4)
应用程序图像映射文件具有:
.vectors 0x00410000 0xd0 src/ASF/sam/utils/cmsis/sam4s/source/templates/gcc/startup_sam4s.o
0x00410000 exception_table
…
.text.Reset_Handler
0x0041569c 0x100 src/ASF/sam/utils/cmsis/sam4s/source/templates/gcc/startup_sam4s.o
0x0041569c Reset_Handler
异常表定义如下:
const DeviceVectors exception_table = {
/* Configure Initial Stack Pointer, using linker-generated symbols */
.pvStack = (void*) (&_estack),
.pfnReset_Handler = (void*) Reset_Handler,
引导加载程序将应用程序跳转点声明为:
extern void (*_sjump) ();
然后进行以下调用:
_sjump();
0x00410004 处的内存内容为 0x0041569d,我注意到这不是字对齐的。这是因为我们使用的是 Thumb 指令吗?不管怎样,为什么它不是 0x0041569c?或者更重要的是,为什么这会出现异常?
谢谢,
德万
更新: 找到了这个,但它似乎对我不起作用:
void (*user_code_entry)(void);
unsigned *p;
p = (uint32_t)&_sappl + 4;
user_code_entry = (void (*)(void))(*p - 1);
if(applGood && tempGood) {
SCB->VTOR = &_sappl;
PrintHex(p);
PrintHex(*p);
PrintHex(user_code_entry);
user_code_entry();
}
代码打印:00410004 0041569D 0041569C
更新更新: 尝试使用 C 函数指针跳转的代码产生了以下反汇编:
--- D:\Zebra\PSPT_SAM4S\PSPT_SAM4S\SAM4S_PSPT\BOOTLOADER\Debug/.././BOOTLOADER.c
user_code_entry();
004005BA ldr r3, [r7, #4]
004005BC blx r3
我能够使用以下程序集完成此工作:
"mov r1, r0 \n"
"ldr r0, [r1, #4] \n"
"ldr sp, [r1] \n"
"blx r0"
基于此,我想知道是否需要重置堆栈,如果需要,是否可以在 C 中完成此操作?