cortex内核hardfault错误的定位方法实战

单片机一般是cortex-m3/m4/m0之类的内核,典型的就是stm32,其实其他内核也是一个道理。hardfault错误一般是操作了不该操作的内存,或者执行了不该执行的动作,例如一个非法的函数指针,你非要去调用。

调试这个错误的原理是:

发生hardfault错误后就会进入相应的hardfault中断,进入中断前会在被中断的地址执行压栈动作,将当时的工作环境(就是系统的一些寄存器,r0,r1,r2,r3,lr,pc,r12)压进堆栈,将lr赋值非法数据,然后跳到hardfault中断执行中断服务程序。那么只需要将压栈后的lr读出来,就知道中断服务程序的返回地址,也就是出现hardfault时的程序地址,也就是错误的代码地址。

直接看代码:

/**
  * @brief  This function handles Hard Fault exception.
  * @param  None
  * @retval None
  */

 void HardFault_Handler_C(unsigned int* hardfault_args)
{
	printf("\r\nsp =0x%.8X\r\n",hardfault_args);
    printf("R0    = 0x%.8X\r\n",hardfault_args[0]);         
    printf("R1    = 0x%.8X\r\n",hardfault_args[1]);         
    printf("R2    = 0x%.8X\r\n",hardfault_args[2]);         
    printf("R3    = 0x%.8X\r\n",hardfault_args[3]);         
    printf("R12   = 0x%.8X\r\n",hardfault_args[4]);         
    printf("LR    = 0x%.8X\r\n",hardfault_args[5]);         
    printf("PC    = 0x%.8X\r\n",hardfault_args[6]);         
    printf("PSR   = 0x%.8X\r\n",hardfault_args[7]);         
    printf("BFAR  = 0x%.8X\r\n",*(unsigned int*)0xE000ED38);
    printf("CFSR  = 0x%.8X\r\n",*(unsigned int*)0xE000ED28);
    printf("HFSR  = 0x%.8X\r\n",*(unsigned int*)0xE000ED2C);
    printf("DFSR  = 0x%.8X\r\n",*(unsigned int*)0xE000ED30);
    printf("AFSR  = 0x%.8X\r\n",*(unsigned int*)0xE000ED3C);
    printf("SHCSR = 0x%.8X\r\n",SCB->SHCSR);                
    while (1);
}

#undef TST
__ASM void HardFault_Handler_a(void)
{	
	IMPORT HardFault_Handler_C
    TST LR, #4
    ITE EQ
    MRSEQ R0, MSP
    MRSNE R0, PSP
    B HardFault_Handler_C
}
  

  
void HardFault_Handler(void)
{
  /* Go to infinite loop when Hard Fault exception occurs */

	HardFault_Handler_a();

	printf("HardFault_Handler\r\n");
	while (1)
	{
	}
}

HardFault_Handler_a这个函数里面执行过程是:判断lr的值,判断是从msp还是psp中去读堆栈数据,将堆栈指针赋给r0,然后调用HardFault_Handler_C这个函数

HardFault_Handler_C执行过程:就是从堆栈中将堆栈的数据打印出来,重点关注lr

拿到lr以后,打开keil,一半都不习惯使用硬件的jtag,所以设置下软件模拟,目的只是为了看反汇编代码

然后进入调试模式,出现了反汇编代码,在反汇编代码里面右键-"show code at address"-输入刚才得到的lr数值,就跳到出问题的那个代码了!

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Cortex-M0是一种ARM处理器的核心架构,用于嵌入式系统中。"hardfault"是指在程序运行时发生的硬错误或异常。当Cortex-M0处理器检测到硬错误时,会引发一个硬错误中断,即硬错误中断(HardFault)。 Cortex-M0的硬错误中断(hardfault)通常是由以下情况触发: 1. 无效的指令:当程序执行到一个非法或无效的指令时,会导致硬错误中断。 2. 内存访问错误:当程序试图访问不存在的内存地址、只读内存进行写操作或对只执行内存进行写操作时,会导致硬错误中断。 3. 栈溢出:当程序使用的堆栈空间超过其分配的大小,会导致硬错误中断。 4. 数学运算错误:当程序进行除零或无效的浮点数操作等数学运算时,会引发硬错误中断。 发生硬错误中断后,Cortex-M0处理器会中止当前正在执行的进程,并将程序控制权传递给硬错误中断处理程序(HardFault Handler)。硬错误中断处理程序可以用于处理硬错误的日志记录、调试等操作,并根据具体情况采取相应的纠正措施。 为了解决Cortex-M0硬错误中断问题,应该进行以下步骤: 1. 使用调试工具来定位并修复导致硬错误中断的问题,例如检查程序是否存在无效的指令或内存访问错误。 2. 检查堆栈空间的分配是否合理,确保不会发生栈溢出。 3. 避免发生数学运算错误,例如在进行除法运算前进行零值检查。 通过以上措施,可以有效解决Cortex-M0硬错误中断的问题,确保程序的稳定性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值