IAR环境 HandFault定位

在gpio_led_output.c 和 startup_MK65F18.S文件添加下面代码,点击运行产生HardFault中断;

/***gpio_led_output.c***/
static void EnableFault(void)
    {
      SCB->SHCSR |= \(SCB_SHCSR_USGFAULTENA_Msk|SCB_SHCSR_BUSFAULTENA_Msk|SCB_SHCSR_MEMFAULTENA_Msk);
    }
int main(void)
{
    /* Define the init structure for the output LED pin*/
    gpio_pin_config_t led_config = {
        kGPIO_DigitalOutput, 0,
    };
    /* Board pin, clock, debug console init */
    BOARD_InitPins();
    BOARD_BootClockRUN();
    BOARD_InitDebugConsole();
    EnableFault();
    *(uint8_t *)0x10000 = 0x12;
    /* Print a note to terminal. */
    PRINTF("\r\n GPIO Driver example\r\n");
    PRINTF("\r\n The LED is blinking.\r\n");
    /* Init output LED GPIO. */
    GPIO_PinInit(BOARD_LED_GPIO, BOARD_LED_GPIO_PIN, &led_config);
    while (1)
    {
        delay();
        GPIO_PortToggle(BOARD_LED_GPIO, 1u << BOARD_LED_GPIO_PIN);
    }
}
/****startup_MK65F18.S****/
  PUBWEAK HardFault_Handler
        SECTION .text:CODE:REORDER:NOROOT(1)
HardFault_Handler
        IMPORT hard_fault_handler

一、进入HardFault中断时CPU寄存器的值
IAR环境 HandFault定位_第1张图片
二、在进入异常服务程序后, LR的值被自动更新为特殊的 EXC_RETURN,这是一个高28位全为1的值
上图中LR = 0xFFFFFFF9,所以使用的是MSP
IAR环境 HandFault定位_第2张图片

IAR环境 HandFault定位_第3张图片
三、在内存中找到MSP对应的地址,并查看存储地址的值
IAR环境 HandFault定位_第4张图片
四、LR对应的汇编语句,正常执行时,函数返回后的执行地址
IAR环境 HandFault定位_第5张图片
五、PC寄存器对应的汇编语句
IAR环境 HandFault定位_第6张图片
PC寄存器存储的是中断返回后执行的语句,
1、在异常处理例程完成后需要从中断返回时,LR的值载入到PC中(通常是BX LR指令,也可以是MOV PC,LR指令,或者POP {…, PC}等指令,只要能将LR赋给PC即可),由于LR的值是0xFFFFFFF9,CPU检测到向PC中载入的是这个特殊值时,就知道是中断返回,于是做中断返回的动作(与压入动作相反:从堆栈中弹出核心寄存器的值,恢复到线程模式或Handler模式等)。此时的BX LR 与 一般函数的中所调用的BX LR 有所不同。

2、在进入中断函数之前 PC计数器执行到 0x1964: 0xf7ff 0xf890 BL DbgConsole_Printf ; 0xa88后发生中断进入到HardFault_Handler函数执行第一条指令BX LR;但实际上触发中断的是0x1960: 0x7008 STRB R0, [R1] 这条指令;这可能是因为中断触发延时。如果在没有触发中断的情况下PC将执行0X00000F6B 地址处的语句,

        break;
        0xf6a: 0xe014         B.N       0xf96
            LPUART_GetDefaultConfig(&lpuart_config);

当中断返回时,因为是执行这句*(uint8_t *)0x10000 = 0x12; 代码产生了中断,所以在中断返回时PC寄存器将指向0X00001962 地址处执行

 0x1962: 0x480b         LDR.N     R0, [PC, #0x2c]         ; 0x1df0 (7664)

你可能感兴趣的:(IAR,HardFault)