我目前正在为ARM Cortex M3做一个 Bootstrap 。
我有两个函数,一个在 C 中,一个在 assembly 中,但是当我试图调用 *assembly函数 * 时,我的程序挂起并产生某种错误。
功能如下,
C:
extern void asmJump(void* Address) __attribute__((noreturn));
void load(void* Address)
{
asmJump(Address);
}
字符串
组装:
.section .text
.global asmJump
asmJump: @ Accepts the address of the Vector Table
@ as its first parameter (passed in r0)
ldr r2, [r0] @ Move the stack pointer addr. to a temp register.
ldr r3, [r0, #4] @ Move the reset vector addr. to a temp register.
mov sp, r2 @ Set the stack pointer
bx r3 @ Jump to the reset vector
型
我的问题是
代码通过串行打印“Hello”,然后调用load
。加载的代码打印“再见”,然后重置芯片。
如果我慢慢地逐步完成load
调用asmJump
的部分,一切都可以完美地工作。然而,当我让代码运行时,我的代码遇到了 '内存故障'。我知道这是一个内存错误,因为它以某种方式导致了Hard Fault
(当我在4或5秒后暂停时,Hard Fault处理程序的无限while循环正在执行)。
以前有人遇到过这个问题吗?如果是这样,你能告诉我如何解决吗?
正如您所看到的,我已经尝试使用函数属性来解决这个问题,但还没有找到解决方案。我希望有人能帮助我了解问题是什么摆在首位。
编辑:
感谢@JoeHass的回答,以及@MartinRosenau的评论,从那以后,我继续寻找this SO answer,它对我为什么需要这个标签有非常透彻的解释。这是一个很长的阅读,但值得。
3条答案
按热度按时间p4rjhz4m1#
我认为你需要告诉汇编器使用统一的语法,并显式地声明你的函数是一个thumb函数。GNU汇编器有这样的指令:
字符串
.syntax unified
指令告诉汇编程序您正在使用汇编代码的现代语法。我认为这是一些遗留语法的不幸遗物。.thumb_func
指令告诉汇编程序此函数将在thumb模式下执行,因此用于符号asmJump
的值的LSB设置为1。当Cortex-M执行分支时,它会检查目标地址的LSB,以确定它是否为1。如果是,则以拇指模式执行目标代码。由于这是Cortex-M支持的唯一模式,因此如果目标地址的LSB为零,则会出现故障。cunj1qz12#
既然你提到你有调试器工作,使用它!
查看determine the fault source的故障状态寄存器。也许不是
asmJump
崩溃,而是你调用的代码。bxpogfeg3#
如果这是你所有的代码。我想你的SP变化称为段错误或类似的东西。您应该在更改SP之前保存它,并在使用后恢复它。
字符串