FreeRTOS.org
关于调试硬故障和其他异常
在ARM Cortex-M3和ARM Cortex-M4微控制器上,根据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使用寄存器r0bymrseq r0, msp或bymrsne r0, psp传递,它是函数中使用的唯一参数。那么ldr r1, [r0, #24]行有目的吗?

最佳答案

CPU、操作系统和编译器制造商经常串通,为特定平台生成一个标准ABI (aka Abstract Binary Interface)。它允许您将不同编译器/语言生成的对象文件链接到程序中。调用约定定义如何在调用方和被调用代码之间传递返回值和参数,以及允许用不同语言编写或由不同工具编译的可操作组件所需的其他详细信息。
您在汇编程序代码中看到的是should be documented by the ARM consortium的ABI细节。为了成功地从汇编程序调用C代码,您必须理解ABI。请注意,编译器编写器可以自由地以任何方式实现其调用约定,因此您的里程数可能会有所不同。这就是我建议你检查C编译器文档的原因。大多数C编译器提供可配置的调用方案,有时平台ABI是默认的,有时不是。
考虑到你的目标是一个实时操作系统,他们可能有自己的ABI,在这种情况下,他们可能修改了一个OSS编译器工具链,但很可能他们遵循ARM Cortex ABI。如果目标董事会没有可用的操作系统,则所有赌注都将取消,您应咨询董事会制造商以获取相关文档(如果有)。

关于c - ARM Cortex-M处理器硬故障处理中的冗余代码,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51088152/

10-12 00:20
查看更多