你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32H7移植SEGGER的硬件异常分析

[复制链接]
STMCU小助手 发布时间:2022-1-1 20:00
11.1 初学者重要提示  W! s. O+ y% v2 E3 M
  MDK本身也是支持硬件异常分析的,就是不够直观1 v# ?* o3 i& ^% W. W

2 x( s3 p3 n; E& `6 B; Q  IAR8带的硬件异常分析比较好用,在本章11.6小节有说明。# j% u3 T( @; C
11.2 移植方法% o+ F! k" _' C9 X% P3 z
直接移植SEGGER的硬件异常代码会有错误警告,这里针对IAR和MDK版本做了些简单修改,方便大家移植到自己的工程里面。
$ Y# X% c- o* Y. P& g* M; D( }& P" t- `6 L$ ~
  MDK版本移植, L: m3 S- \& N1 D* @
源文件位于本章配套例子的\User\segger\HardFaultHandlerMDK文件夹,添加如下两个文件到工程里面即可。
& m" G$ _0 H, O6 v7 W/ S/ S2 }$ M* C4 P7 V5 z' A9 _
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

2 R# \% w& k1 \7 v5 x5 @- w
. _0 Q1 m, F* I  IAR版本移植( S6 F/ o+ O" ]" V; ^6 Q* E
源文件位于本章配套例子的\User\segger\HardFaultHandlerIAR文件夹,添加如下两个文件到工程里面即可。
2 N8 i: r( I- A, o% M$ {* r/ f8 B  a4 {; s6 z% p
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

' F1 G# j3 @& p  w, n; R$ `
; X* ^$ L5 x% u7 J在文件SEGGER_HardFaultHandler.c里面都添加了串口打印功能,方便不用编译器的调试功能时,通过串口打印提示是否进入硬件异常。8 w' z1 O+ l! |) A6 ^4 h

3 Z& E- N5 v5 a" R
  1. #define ERR_INFO "\r\nEnter HardFault_Handler, System Halt.\r\n"* P: o9 _3 P1 N2 E' z

  2. 9 i% X/ l- g" ?
  3. #if 1
    + O* m, J6 o, n# a, l
  4. {5 E5 i7 z& C2 W; O
  5.         const char *pError = ERR_INFO;; f6 ^  o& Y% C" _, Z7 C
  6.         uint8_t i;
    4 e9 C9 r% L" ~2 [3 q% z2 N' z+ t

  7. ; ^$ W5 L4 t( _( ]
  8.         for (i = 0; i < strlen(ERR_INFO); i++)
    ( g' Z2 e% C$ [- N2 p8 u
  9.         {
    5 a  G  g% {% C4 k5 {' ^( \/ O  o
  10.                 USART1->TDR = pError<i>;$ I- J! _; I, n, T5 _: h
  11.                 /* 等待发送结束 */% [3 o% k% @' H  t$ d) J
  12.               </i>  while((USART1->ISR & USART_ISR_TC) == 0);& J5 ^, o0 T; w) u/ ^6 \0 \- A! }
  13.         }        
    - l9 S. X, v2 d7 E, H" Y! H
  14. }
    ) d$ u4 e! Z# C1 u$ o9 X; m% m2 F3 O
  15. #endif
复制代码

1 O7 `2 z( a: Q- E& {& v% a- j11.3 MDK锁定硬件异常位置方法! n& C! g+ t2 p. m2 w' y! E
以本章配套的例子为大家做个说明。
' N) c- @( P) m; s8 Z7 S7 e: ~( Q6 H$ e' V8 H5 y
1、测试方法比较简单,进入调试状态,全速运行,然后按下K1按键,就会进入硬件异常中断,此时停止调试,程序就会自动定位到如下位置:
( Z% N: l* q& u$ _1 B$ P6 {! n
$ }# z3 p" ]  Q1 A& p
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

7 \3 x8 J( n. f) n6 N$ {% V- p: U
6 r; V, a& n$ g3 M5 R1 k$ X2、在Watch1窗口添加变量_Continue
8 O2 x2 h, M1 g! f8 I. \. [' ^* h4 X
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
$ W- O: q; d( @+ h! X7 A: Q

$ a: g1 X( w, V0 r, u3、修改为任何非0数值,就可以继续单步调试。这个代码后面还有一个第1步中的while循环,也可以继续采用第2步的方法修改。退出硬件异常后就是大家进入硬件异常前下一条要执行的指令(可能还是这个函数本身,因为一个函数由多个指令完成)。定位到出问题的位置:
, A/ b+ Z& ?$ R' Q
1 i8 H8 ^7 w: Z# M9 ]
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
- F" b4 \5 n& ?" C

2 [0 r# K* Q# z11.4 IAR锁定硬件异常位置方法

3 C* j6 w7 S! o: i0 M以本章配套的例子为大家做个说明。
1 U& F- J9 R9 K1 \! {
2 z7 o, x' X" v1 O' t; N3 T1、测试方法比较简单,进入调试状态,全速运行,然后按下K1按键,就会进入硬件异常中断,此时停止调试,程序就会自动定位到如下位置:2 O( P+ C; W: o  U9 n
1 y) U$ C/ U7 D
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
/ }% u8 r5 U# y: C& P
0 y- l& \% V0 h8 R
2、在Watch1窗口添加变量_Continue! H5 p: @8 u1 F2 B- N3 i
* }4 V6 X4 i! l: E2 Y* T5 z: r
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
/ R0 |' G1 a! H7 j/ y$ F: R, S8 d

$ q! a9 j) U" g1 j8 K) V* T! G0 P3、修改为任何非0数值,就可以继续单步调试。这个代码后面还有一个第1步中的while循环,也可以继续采用第2步的方法修改。退出硬件异常后就是大家进入硬件异常前下一条要执行的指令(可能还是这个函数本身,因为一个函数由多个指令完成)。定位到出问题的位置:
( L1 F2 Y4 c: o1 U" R
3 v% r/ \* B" M( p
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

4 _& D4 [, t; r) ]8 Y1 K, Q2 g1 }+ O) w+ |9 U1 X
11.5 硬件异常原因分析: V7 E6 ^& P4 M6 `/ t% I( P
SEGGER提供的这个机制查找出问题的位置比较方便,具体原因需要继续在调试界面里面添加HardFaultRegs结构变量,这个结构体变量添加了所有大家想看的东西。下面是MDK调试状态查看部分结构体数值:
& I9 }% k1 F# v
9 U" z4 W) S9 K5 `
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
( w) b5 a) u* Z% R1 R! C; D

, P& Z, _! A* o* [* A- |8 W具体上面的变量代表什么含义呢,代码里面有注释,查阅起来没有IAR自带的硬件异常提示方便(注意,下面的代码用到了位域)。
" D$ Z: S3 t( Y& f6 m6 ^& E: e; e0 I9 ~6 C- _
  1. #if DEBUG$ R" [5 m  b; d; F2 p
  2. static volatile unsigned int _Continue;  // Set this variable to 1 to run further
    8 |+ m& ]2 p+ f: W
  3. ; G/ H' I* P- O! D
  4. static struct {
    6 i& b3 z: x, C5 e# c7 D3 K
  5.   struct {3 L. V: J! x* a0 e; H& k
  6.     volatile unsigned int r0;            // Register R0
    6 d- c1 X/ b4 U
  7.     volatile unsigned int r1;            // Register R1
    ) }1 P# F- ~% u
  8.     volatile unsigned int r2;            // Register R2
    ' u8 J" Z2 f$ W
  9.     volatile unsigned int r3;            // Register R3- l3 W( j' `, }- H( v  {6 Y
  10.     volatile unsigned int r12;           // Register R127 t4 m- _: h, f+ s- a+ M9 D
  11.     volatile unsigned int lr;            // Link register
    ) B; s( o5 X: P/ m* P  n: ~1 E7 @
  12.     volatile unsigned int pc;            // Program counter
    . b4 h. ~* Y; R
  13.     union {! B) `0 T; H& g0 i9 l) r% }4 B
  14.       volatile unsigned int byte;
    . u' g& n0 j7 h6 d: e, z0 |
  15.       struct {
    / S' y9 ^, \' r& J
  16.         unsigned int IPSR : 8;           // Interrupt Program Status register (IPSR)
    ' s9 J! O7 E& u( C, `
  17.         unsigned int EPSR : 19;          // Execution Program Status register (EPSR)
    ! Y- l/ v' X: n( r* }! {6 v
  18.         unsigned int APSR : 5;           // Application Program Status register (APSR), L3 u& Q# Y! [; n
  19.       } bits;
    * B" E) P; C% j$ @$ |# t
  20.     } psr;                               // Program status register.2 C/ f; U+ V& E& B- \& s
  21.   } SavedRegs;
    + X* Q+ ~0 H0 }: e& W( y

  22. * u, J& C8 q% e" p0 D6 U( v% n/ e
  23.   union {6 d# \& \$ `. S) O, C# f. I( l
  24.     volatile unsigned int byte;' a/ ~8 F) d3 q; c& S
  25.     struct {
    4 F2 L0 _, y: _) S& W; \
  26.       unsigned int MEMFAULTACT    : 1;   // Read as 1 if memory management fault is active5 E) ]& w" P7 u3 Q4 X5 }
  27.       unsigned int BUSFAULTACT    : 1;   // Read as 1 if bus fault exception is active$ _7 i7 d% q% Z0 k
  28.       unsigned int UnusedBits1    : 1;
    ' m" U! M* b6 b4 X( e  I% b& \, H
  29.       unsigned int USGFAULTACT    : 1;   // Read as 1 if usage fault exception is active" B$ m0 y$ }# }) `) s
  30.       unsigned int UnusedBits2    : 3;
    $ I0 K' A$ W( Q& h
  31.       unsigned int SVCALLACT      : 1;   // Read as 1 if SVC exception is active
    8 A) C' W  _& G8 F( d  [0 I
  32.       unsigned int MONITORACT     : 1;   // Read as 1 if debug monitor exception is active2 v) u) Q( W: n% G. B
  33.       unsigned int UnusedBits3    : 1;
    4 g6 A; i8 m2 \% V: \
  34.       unsigned int PENDSVACT      : 1;   // Read as 1 if PendSV exception is active
    $ t% p( r" X7 R% P3 K' J# b
  35.       unsigned int SYSTICKACT     : 1;   // Read as 1 if SYSTICK exception is active0 d; X: E9 k, M% i& u
  36.       unsigned int USGFAULTPENDED : 1;   // Usage fault pended; usage fault started but was replaced by a
    ; L  h! F, `4 S
  37. higher-priority exception
    : Z5 q* e1 O& e* `1 X& ^0 b- V
  38.       unsigned int MEMFAULTPENDED : 1;   //  Memory management fault pended; memory management fault started
    $ J0 V0 b& z7 X; N  P* s( Q
  39. but was replaced by a higher-priority exception& r% c. R8 v) u* S6 [
  40.       unsigned int BUSFAULTPENDED : 1;   // Bus fault pended; bus fault handler was started but was replaced
    3 T3 v" P/ {3 ]; _
  41. by a higher-priority exception
    " N5 G' x# H  R+ P% [: o
  42.       unsigned int SVCALLPENDED   : 1;   // SVC pended; SVC was started but was replaced by a higher-priority1 ~- ^% [: A# W: F( h6 z3 l
  43. exception
    8 [  }$ j& w, p$ p! `
  44.       unsigned int MEMFAULTENA    : 1;   // Memory management fault handler enable/ G$ K) z9 M1 D+ X5 c$ C
  45.       unsigned int BUSFAULTENA    : 1;   // Bus fault handler enable: X, k( C  S; W8 \
  46.       unsigned int USGFAULTENA    : 1;   // Usage fault handler enable, \4 n9 {2 ]- n  _
  47.     } bits;0 B" H3 ~3 d" w# H6 O2 D$ e& |
  48.   } syshndctrl;                          // System Handler Control and State Register (0xE000ED24)
    ) b7 J: s/ I1 X! }
  49. 1 r+ N7 v: E  q, K" |0 Y3 i
  50.   /* 省略未写 *// |, _" _) R. G" g6 c6 S

  51. ( @3 [$ o( D( `
  52.   volatile unsigned int afsr;            // Auxiliary Fault Status Register (0xE000ED3C), Vendor controlled (optional)
    " J' N3 q% M+ r) f4 r8 k
  53. } HardFaultRegs;
    $ N+ F& P6 j& p! t  c/ a
  54. #endif
复制代码

$ L. @2 F2 F2 B, D( r11.6 IAR自带的硬件异常分析
0 l! F5 Q5 o4 ?) H7 v- L还以本章配套的例子为例,进入调试状态,全速运行,然后按下K1按键,就会进入硬件异常中断,此时停止调试,IAR还会弹出一个硬件异常错误分析,刚进来的时候也许是个空白+ {, i; ^9 ]) y. V8 O

  P/ ~1 n* L7 G! O  G5 V* T" J
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

3 |$ l" T* ?& F. O
7 `" S- [6 n/ Q0 h单步调试刷新下就出来了:
, b' p' v# q1 n0 s. w" n. W5 D; E( S( M  S
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
! I4 i6 W2 n6 Q4 k: s
* X3 n8 S' Q, _( L
指出了问题的原因是操作的数据地址有问题。
$ D+ q- D) T! |" ~9 ]- r. V; }( @$ I* M( ^" n; ^/ j: u. g. z+ w. N# [
11.7 实验例程  @6 U( f) f+ b# B1 Z
专门为本章节配套了一个例子:V7-009_移植SEGGER的硬件异常分析机制。大家可以按照本章教程提供的方法进行测试。: V: o: r4 C1 t$ A& x8 I& D

6 s4 e% F% x" @11.8 总结
! g7 j0 B- W8 F$ R; m除了SEGGER的硬件异常分析方案,建议也测试下MDK和IAR的,以后遇到硬件异常问题,解决起来可以得心应手。& ?/ o# @$ U$ Y  c& d
' @' M! u. `8 x& j' Z. f

- P4 I5 e( q5 v5 N% S3 d6 ]
收藏 评论0 发布时间:2022-1-1 20:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版