您的位置:

hardfault_handler详解

Hard fault是指ARM Cortex-M处理器发生不可恢复的错误时触发的中断。当CPU执行一条非法指令、访问非法地址或者发生堆栈溢出等情况时,就会触发hard fault,中断处理函数为hardfault_handler。本文将从多个方面对hardfault_handler进行详细的阐述,包括其概念、原因、实现方式、调试方法等。

一、hardfault_handler的概念

1、hard fault发生的原因

Hard fault通常发生在以下情况下:

(1)非法汇编指令;

(2)非法物理地址;

(3)下溢或上溢;

(4)内存保护错误;

(5)堆栈溢出等。

在这些情况下,处理器会触发一个硬件异常,并跳转到hardfault_handler中断处理函数。

2、hardfault_handler的作用

Hardfault_handler的主要作用是对硬件错误进行处理,保存相关状态信息,并进行相应的操作,以及能够帮助程序员在调试时快捷地定位问题。

二、hardfault_handler的实现方式

1、arm-none-eabi-gcc编译环境下的实现方式

/**
  * @brief  This function handles Hard Fault exception.
  * @param  None
  * @retval None
  */
void HardFault_Handler(void)
{
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)
  {
  }
}

2、Keil MDK编译环境下的实现方式

void HardFault_Handler(void)
{
    __ASM volatile
    (
        "TST LR, #4 \n"
        "ITE EQ \n"
        "MRSEQ R0, MSP \n"
        "MRSNE R0, PSP \n"
        "MOV R1, LR \n"
        "B hard_fault_handler_c \n"
    );
}

这两种实现方式的流程都是一样的:CPU进入Hard Fault状态后,调用HardFault_Handler中断处理函数;在中断处理函数中保存相关现场信息,调用硬件操作等,最后进入死循环。

三、hardfault_handler的调试方法

在代码开发过程中,经常会出现hardfault_handler中断处理函数被触发的情况。针对这种问题,我们可以通过以下几种方法进行调试:

1、利用Keil MDK的Debug功能,设置断点,检查当前程序运行到了哪一行代码。通过检查每一行代码,找到导致Hard Fault的可能原因。

2、利用调试器查看相应的寄存器值,找到程序执行时可能出现的异常情况,如非法地址访问等。

3、通过硬件排除故障。当程序频繁地触发Hard Fault时,可能是硬件出现了故障,比如存储器损坏、电源不稳等。此时需要通过硬件测试设备,如万用表、示波器等进行排故。

四、hardfault_handler处理实例

以下是一个hardfault_handler处理的示例:

/* 程序代码 */
int main(void){
  uint8_t array[3] = { 0 };
  uint8_t i = 0;
  
  for(i=0; i<=3; i++){
    array[i] = i;
  }
  
  while(1);
}

/* Hard Fault中断处理函数 */
void HardFault_Handler(void){
  printf("Hard Fault!\n");
  printf("SCB->HFSR=0x%x\n",SCB->HFSR);
  printf("SCB->CFSR=0x%x\n",SCB->CFSR);
  printf("SCB->DFSR=0x%x\n",SCB->DFSR);
  printf("SCB->AFSR=0x%x\n",SCB->AFSR);
  
  while(1);
}

例子中,程序出现了数组越界的错误,导致发生了hard fault。在hardfault_handler中断处理函数中,将错误信息打印出来,从而更好地定位问题。

五、小结

本文详细讲述了hardfault_handler中断处理函数的概念、原因、实现方式、调试方法以及代码实例,对于进行ARM Cortex-M编程的开发人员来说是非常有参考价值的。