簡體   English   中英

ARM Cortex-M處理器硬故障處理中的冗余代碼

[英]Redundant code in hard fault handling of ARM Cortex-M processor

來自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通過寄存器r0mrseq r0, msp或由mrsne r0, psp它是函數中使用的唯一參數。 那么, ldr r1, [r0, #24]行是否有用途?

CPU,OS和編譯器制造商經常合謀為特定平台生產標准ABI(又稱為抽象二進制接口) 它是使您可以將不同的編譯器/語言生成的目標文件與程序鏈接在一起的方法。 調用約定定義了如何在調用者和被調用代碼之間傳遞返回值和參數,以及允許使用不同語言編寫或由不同工具編譯的可互操作組件所需的其他詳細信息。

您在匯編代碼中看到的是ABI詳細信息,該詳細信息應由ARM聯盟記錄 為了從匯編程序成功調用C代碼,您必須了解ABI。 請注意,編譯器編寫者可以按自己希望的任何方式自由實現其調用約定,因此您的工作量可能會有所不同。 這就是為什么我建議您檢查C編譯器文檔的原因。 大多數C編譯器提供可配置的調用方案,有時平台ABI是默認的,有時不是。

考慮到您的目標是RTOS,他們可能擁有自己的ABI,在這種情況下,他們可能會修改OSS編譯器工具鏈,但是很可能他們遵循ARM Cortex ABI。 如果目標板沒有可用的操作系統,則所有選擇均不適用,您應咨詢板制造商以獲取相關文檔(如果有)。

我們可能對此讀得太多。 我認為將prvGetRegistersFromStack地址推到4個字節的邊界(這是我的M7和外部SDRAM所要求的)只是個麻煩。 他們可以使用align指令來實現相同的目的。

void HardFault_Handler(void)
{
    __asm volatile
        (
            " tst lr, #4                                                \n"
            " ite eq                                                    \n"
            " mrseq r0, msp                                             \n"
            " mrsne r0, psp                                             \n"
            " ldr r2, handler2_address_const                            \n"
            " bx r2                                                     \n"
            " .align 4                                                  \n"
            " handler2_address_const: .word prvGetRegistersFromStack    \n"
        );
}

但是,嘿,如果可行,誰會說哪種方法更好:)

大衛,干杯

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM