ARM Cortex-M处理器硬故障处理中的冗余代码

来自FreeRTOS.org ,关于在ARM Cortex-M3和ARM Cortex-M4微控制器上调试硬故障和其他exception ,根据FreeRTOS的人员,我们可以使用以下代码来调试ARM Cortex-M硬故障 –

/* The fault handler implementation calls a function called prvGetRegistersFromStack(). */ static void HardFault_Handler(void) { __asm volatile ( " tst lr, #4 \n" " ite eq \n" " mrseq r0, msp \n" " mrsne r0, psp \n" " ldr r1, [r0, #24] <======== NOTE THIS LINE \n" " ldr r2, handler2_address_const \n" " bx r2 \n" " handler2_address_const: .word prvGetRegistersFromStack \n" ); } 

现在,根据我的理解,标记的行没有效果,并且未在对应的prvGetRegistersFromStack函数中使用:

 void prvGetRegistersFromStack( uint32_t *pulFaultStackAddress ) { /* These are volatile to try and prevent the compiler/linker optimising them away as the variables never actually get used. If the debugger won't show the values of the variables, make them global my moving their declaration outside of this function. */ volatile uint32_t r0; volatile uint32_t r1; volatile uint32_t r2; volatile uint32_t r3; volatile uint32_t r12; volatile uint32_t lr; /* Link register. */ volatile uint32_t pc; /* Program counter. */ volatile uint32_t psr;/* Program status register. */ r0 = pulFaultStackAddress[ 0 ]; r1 = pulFaultStackAddress[ 1 ]; r2 = pulFaultStackAddress[ 2 ]; r3 = pulFaultStackAddress[ 3 ]; r12 = pulFaultStackAddress[ 4 ]; lr = pulFaultStackAddress[ 5 ]; pc = pulFaultStackAddress[ 6 ]; psr = pulFaultStackAddress[ 7 ]; /* When the following line is hit, the variables contain the register values. */ for( ;; ); } 

pulFaultStackAddress使用寄存器r0通过mrseq r0, mspmrsne r0, psp它是函数中使用的唯一参数。 那么ldr r1, [r0, #24]行的目的是什么?

CPU,OS和编译器制造商经常勾结为特定平台生成标准ABI(aka抽象二进制接口) 。 它允许您将不同编译器/语言生成的目标文件与您的程序链接。 调用约定定义了如何在调用者和被调用代码之间传递返回值和参数,以及允许以不同语言编写或由不同工具编译的可互操作组件所需的其他详细信息。

您在汇编代码中看到的是ABI详细信息, 应由ARM联盟记录 。 为了从汇编程序成功调用C代码,您必须了解ABI。 请注意,编译器编写者可以任意方式自由实现其调用约定,因此您的里程可能会有所不同。 这就是为什么我建议你查看你的C编译器文档。 大多数C编译器提供可配置的调用方案,有时平台ABI是默认的,有时则不是。

鉴于您的目标是RTOS,它们可能有自己的ABI,在这种情况下,它们可能修改了OSS编译器工具链,但很可能它们遵循ARM Cortex ABI。 如果目标板没有任何操作系统可用,则所有投注均已关闭,您应咨询板制造商以获取相关文档(如果有)。