来源:网路素材
, Z. T8 @, s3 W1 R; d0 v% Z
在用Keil对STM32的程序进行仿真时程序有时会跑飞,停止仿真程序会停在HardFault_Handler函数里的死循环while(1)中。这说明STM32出现了硬件错误。
5 F" [9 V+ e( F V- _6 H * O) [/ i( O8 j+ C" G
STM32出现硬件错误可能有以下原因:
: {; f; D* N# K- Z; m9 Z(1)数组越界操作;
+ [6 n7 \1 @* F. w(2)内存溢出,访问越界;
) c: Q9 E9 s) g# b1 L) d9 x# m2 x
(3)堆栈溢出,程序跑飞;
( g. Z+ Q/ C+ R5 z( f4 p: U(4)中断处理错误;
2 [1 T$ B4 f8 [& {9 d1 L9 s
遇到这种情况,可以通过以下2种方式来定位到出错代码段。
" K7 _ ` \) ?/ O) f+ j1 B9 [8 [
方法1:
: d- v4 L8 o6 `% n
1.1在硬件中断函数HardFault_Handler里的while(1)处打调试断点,程序执行到断点处时点击“STOP”停止仿真。
9 Y( T. ]+ w# ~+ B) V2 |
; g& D, e# E, ]8 d8 v9 h
1.2 在Keil菜单栏点击“View”——“Registers Window”,在寄存器查看窗口查找R14(LR)的值。如果R14(LR) = 0xFFFFFFE9,继续查看MSP(主堆栈指针)的值,如果R14(LR) = 0xFFFFFFFD,继续查看PSP(进程栈指针)的值。我的程序R14(LR) = 0xFFFFFFF9,接下来以此为例。
% s$ ] w- n2 N+ c) H7 x T2 E
8 s7 ^, o6 G# m8 K, z/ E1.3 在Keil菜单栏点击“View”——“Memory Windows”——“Memory1”,在“Address”地址栏中输入MSP的值:0x20001288,然后在对应的行里找到地址。地址一般以0x08开头的32位数。本例中,地址为0x08003CB9。
6 ]' ^, m* U; n/ j: M/ r' @ j# s% |; {6 [ k+ @! i
1.4 在Keil菜单栏点击“View”——“Disassembly Window”,在“Disassembly”窗口中右击,在下拉菜单中选择“Show Disassemblyat Address...”。在弹出框“Show Code atAdress”的地址框中输入地址0x08003CB9进行搜索,然后就会找到相对应的代码。这里的代码就是进入循环中断之前的情况。仔细查看附近区域的相关代码来排查错误具体原因。" R) t% E( F# K- |6 _
8 Z! _6 m. D8 U2 m% G9 `% O8 o2 `
, O: w7 W5 n/ d8 w) n方法2:
! d7 ]& H; w7 A) ]4 ^4 K2.1在硬件中断函数HardFault_Handler里的while(1)处打调试断点,程序执行到断点处时点击“STOP”停止仿真。
. C; e. j0 d9 n. s5 w% W+ p$ K2.2 在Keil菜单栏点击“View”——“Call Stack Window”弹出“Call Stack + Locals”对话框。然后在对话框中右键选择“Show Caller Code”,就会跳转到出错之前的函数处,仔细查看这部分函数被调用或者数组内存使用情况。
( U' x( {0 G9 i$ f4 ]8 _1 g: w I
; V. m* \& ]5 Q' N' i \0 m) j