gpt4 book ai didi

c - 从 bootloader 跳转产生异常

转载 作者:太空狗 更新时间:2023-10-29 15:29:36 26 4
gpt4 key购买 nike

我已经为位于扇区 0 的 SAM4S 编写了一个引导加载程序,并在扇区 1 加载了一个应用程序。然而问题是,当我尝试跳转到新函数时,它似乎生成了一个异常(调试器转到 Dummy_Handler ()).

引导加载程序在映射中包含以下条目:

.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?或者更重要的是,为什么这会成为异常(exception)?

谢谢,

德文

更新:找到this但它似乎对我不起作用:

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();

}

代码打印:004100040041569D0041569C

更新更新:尝试使用 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 中完成?

最佳答案

我在使用 SAM4E 时遇到了同样的问题。我无法猜测您的问题可能是什么,但我可以指出我遇到的困难和我使用的信息。

我的引导加载程序没有将部分固件存储在正确的内存位置。这导致了 dummy_handler 异常。当我修复地址计算中的错误时,引导加载程序完美运行。

我的建议:

  • 以 ATMEL 为例:DocumentExample Code应该够了。 main.c 足以理解引导加载程序的工作方式。没有必要在一开始就深入了解分区细节。
  • 您可能想阅读如何 execute functions/ISRs from RAM
  • This webpage解释 Intel HEX 格式。
  • 最后,在引导加载程序完成升级后,您可以读取闪存并将其发送回主机。然后将其与原始图像进行比较(使用脚本)。这就是我调试引导加载程序的方式。

其他可能有帮助的想法:

  • 你会在写之前擦掉每一页吗?
  • 在删除/写入每个内存空间之前,您是否解锁它?
  • 您可以锁定 Bootloader 的部分以避免错误地覆盖它
  • 您可以锁定升级固件的部分。

您必须指向的地址是 0x00410000 而不是 0x00410004。 Atmel 的示例代码(参见函数 binary_exec)结合 Intel Hex 格式(记录类型 05)应该可以解决这个问题。

希望这条信息对您有所帮助!

关于c - 从 bootloader 跳转产生异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18218380/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com