#单片机bug调试- HardFault_Handler硬件中断调试解决
??1. HardFault_Handler中断产生的主要原因
??2. HardFault_Handler 关键寄存器说明
??3. 分析HardFault_Handler硬件中断一般步骤
HardFault_Handler硬件中断,是单片机中经常出现的一种异常问题。出现 HardFault_Handler 的原因主要有3类:
??在单片机的HardFault_Handler 异常处理中,不同的单片机系列处理机制可能会有所不同,这取决于具体的MCU系列和其内部架构,需要看对应的内核手册。
不过STM32系列的异常处理机制大致相似,按照本文方法若不能解决问题,就需要详细查看对应的内核手册(R13、R14、R15的作用)。
??出现HardFault异常时,会进入HardFault_Handler中断处理程序。此时,MSP和PSP有两个特殊的寄存器,它们用于存储堆栈指针,帮助开发者定位和解决问题。
??主要用于非中断相关的操作,如主程序运行、用户任务等。
??主要用于嵌套中断处理和多任务环境。
??当发生异常时内核将R0、R1、R2、R3、R12、Returnaddress、PSR、LR寄存器依次入栈到MSP或PSP,以保存当前执行的上下文。
地址解释:
异常时,内核将当前执行的上下文数据按特定顺序入栈到堆栈指针,只要我们找到Returnaddress
地址的位置,就可定位到出现异常的大致位置。查看保存有异常数据的堆栈指针是MSP,还是PSP,需要根据R14(LR)的数值而定。
Coretex-M3和Coretex-M4架构中,R14(LR)数值及其代表含义:
以下使用Coretex-M3内核架构,进行异常分析,
??出现异常时,不要复位设备,保持当前设备运行的异常环境,能更大概率找到问题。若开启了看门狗,超时就会硬件复位,要复现并找到该问题,需要将看门狗进行关闭并重新烧写程序,等待问题复现。
??若进入调试界面后,没有 Registers
窗口,就点击KEIL-->View-->Registers Windown
就会弹出该窗口。
Registers
窗口查看R14(LR),确认保存异常数据的堆栈指针??若 Memory1
窗口未显示,就点击KEIL-->View-->Memory Windowns-->Memory1
就会弹出该窗口。
??若 Disassembly
反汇编窗口未显示,就点击KEIL-->View-->Disassembly Windown
就会弹出该窗口。
??通过MSP堆栈指针指向的地址0x20002B10 记录的上下文信息,查找Returnaddress地址定位到异常程序代码处,可分析出产生HardFault_Handler中断的原因 是由于函数内部数组 buf[50] 只有50个字节大小,但使用buf时操作了100个字节大小,导致了数组越界错误。
??LR寄存器保存了异常发生时的返回地址。如果由于外部信号干扰或电源问题导致异常,这个返回地址可能不准确或MSP的值与预期的函数堆栈位置不匹配,这可能表明异常发生时堆栈已经被破坏。需结合窗口工具 KEIL–>View–>Call Stack ,KEIL–>Peripherals–>Core Peripherals–>Fault Reports 进行具体异常分析。
某些 xxx.uvprojx
工程,在使用KEIL进行Debug在线调试时,打了断点,当退出调试时KEIL会卡死,需要使用任务管理器强制结束任务才能退出。
??出现该问题的原因是,xxx.uvprojx
工程建立不是在本电脑上创建的,是从其他电脑拷贝到本电脑编译运行调试的,存在的配置文件与本电脑不匹配; 或工程路径里面存在中文路径。解决措施:
关闭KEIL工程,拷贝一份工程出来并重命名,路径中不包含中文;
在 xxx.uvprojx
同目录下,删除文件 xxx.scvd
、 xxx.uvguix.Administrator
、 xxx.uvguix.zuozh
、 xxx.uvoptx
; 注意不要删除 xxx.uvprojx
;
打开 xxx.uvprojx
工程,进入Target
界面重新对该工程进行配置,并 Rebuild
编译;