从用asm定义的ARM函数调用C函数
我无法理解我的编译器。我们使用Scons实用程序为M0+处理器编译ARM代码(在Windows上,如果有必要的话。这是一个ARMCC编译),我试图在中断期间使用对的答案捕获堆栈指针的地址 对于我的编译器,我得到以下信息:从用asm定义的ARM函数调用C函数,c,arm,inline-assembly,cortex-m,armcc,C,Arm,Inline Assembly,Cortex M,Armcc,我无法理解我的编译器。我们使用Scons实用程序为M0+处理器编译ARM代码(在Windows上,如果有必要的话。这是一个ARMCC编译),我试图在中断期间使用对的答案捕获堆栈指针的地址 对于我的编译器,我得到以下信息:Error:#20:标识符“asm”未定义 我能够(大部分)编译它的唯一方法是使用以下方法: void IRQHandler_real( uint32_t *sp ) { // Do some work } __asm void IRQHandler(
Error:#20:标识符“asm”未定义
我能够(大部分)编译它的唯一方法是使用以下方法:
void IRQHandler_real( uint32_t *sp )
{
// Do some work
}
__asm void IRQHandler( void )
{
MOV R0,SP
ADDS R0, #1
LDR R1, =IRQHandler_real //<<-- This line fails
BX R1
}
用BL IRQHandler\u real
替换最后两条装配线会导致相同的错误
解释内联程序集非常依赖于编译器,因此我无法找到与我的代码匹配的示例
我读到我需要一个“extern C”电话,但我还没有找到关于这是什么样子的详细信息
我仔细检查了已编译处理器代码的语法,它看起来与我正在使用的命令相同。我认为在评估部件时没有定义符号。我只是还没有弄明白如何定义和链接符号
TL:DR,我需要调用ARM程序集的C函数,但我没有通过编译器。
< P>如果编译器是C++编译器,你就需要使用这个“外部”C;p>extern "C" {
void IRQHandler_real( uint32_t *sp )
{
// Do some work
}
}
编译器似乎是在对所有C代码进行求值之后,分别对ARM代码进行求值。我通过导入函数修复了它 使用
导入
命令。我的最终代码如下所示:
IMPORT IRQHandler_real
PUSH { R4, lr }
MOV R4, SP; The compiler does this from the C code, I'm assuming to avoid a hardware limitation.
MOV R0, R4
BL IRQHandler_real
POP { R4, PC }
ENDP
这适用于ARMCC 5.6。我认为大多数文档都是针对GCC ARM的(
asm(“语句”);
)。我仍然收到警告:#667-D:“asm”函数是非标准的
,因此如果存在的话,我很乐意接受一个“更正确”的答案。尝试在IRQHandler\u real
的开头添加下划线:IRQHandler\u real
我认为该代码还打算将SP传递给被调用的函数,而不是PC。Thomas,我尝试了单下划线和双下划线,两个都失败了,都是同一次编译。超级猫,我更新了问题。谢谢你的关注。我们所有的代码都是用C写的。我在办公室里问过,看起来我们使用的是ARMCC 5.06,而不是GCC ARM。我试图避免为这么小的更改创建新文件,但如果没有内联解决方案,我可以将其移动到新文件中。我将尝试将该结构加载到中断向量中,并用它进行检查,我认为这将适用于VS/C++。不幸的是,它不适用于ARMCC。@mps您可能需要用\ifdef\uu cplusplus
来包围它,但ARM网站上有相关的文档记录。我不认为有人会再使用armcc了,但我也确信这在gcc中是有效的。
IMPORT IRQHandler_real
PUSH { R4, lr }
MOV R4, SP; The compiler does this from the C code, I'm assuming to avoid a hardware limitation.
MOV R0, R4
BL IRQHandler_real
POP { R4, PC }
ENDP