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

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

[复制链接]
STMCU小助手 发布时间:2022-1-1 20:00
11.1 初学者重要提示$ h* h* k/ A% s' Q0 r3 K$ ~5 A" Q
  MDK本身也是支持硬件异常分析的,就是不够直观/ \) A3 U6 E  U$ A8 j
9 }4 d# M- S4 P5 a, E( b
  IAR8带的硬件异常分析比较好用,在本章11.6小节有说明。- N3 |; ^% v1 {! B/ b8 b
11.2 移植方法
, [( ]6 j% m2 R2 l; N; p: p: @; c直接移植SEGGER的硬件异常代码会有错误警告,这里针对IAR和MDK版本做了些简单修改,方便大家移植到自己的工程里面。7 Z6 `- F$ R  U7 Y* J
3 v% s, ~: d4 V4 X
  MDK版本移植! f* g; }( _2 k1 d7 ^
源文件位于本章配套例子的\User\segger\HardFaultHandlerMDK文件夹,添加如下两个文件到工程里面即可。& Y. ]. Z. n5 Z6 R+ n8 z  w; J
( ^1 O! E+ u+ p, u0 H
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
" R/ Q3 n/ @8 N. k5 n7 o& v* G1 [

$ z5 Q; {$ X# }& I& K# D  IAR版本移植! L/ @( w) i& }  g; A  M; `! c- U
源文件位于本章配套例子的\User\segger\HardFaultHandlerIAR文件夹,添加如下两个文件到工程里面即可。2 F: n9 k+ @$ A
0 ^6 w: {0 V: \' J, \# u7 L6 w
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
1 \# e9 O+ }( P6 K! b8 `$ v

. f) e% W3 S- Q0 z% g0 M! k% ]在文件SEGGER_HardFaultHandler.c里面都添加了串口打印功能,方便不用编译器的调试功能时,通过串口打印提示是否进入硬件异常。6 M: t! u6 N2 i: l9 t

3 R2 [7 {+ U3 ]4 A( R; t
  1. #define ERR_INFO "\r\nEnter HardFault_Handler, System Halt.\r\n"- G% l+ [& G+ d3 d$ B

  2. $ Z! ]+ ?) _; T5 Y8 r. A$ D
  3. #if 1+ ^- d9 x. i3 {1 w. A* h$ `
  4. {2 E0 M' K  _( P/ ?/ C
  5.         const char *pError = ERR_INFO;* c% @) {: h* }8 p& X/ _) |
  6.         uint8_t i;! P+ f% o3 [% Y: x3 E+ [4 ^

  7. / R$ Z/ Z& v! c: i! J) E
  8.         for (i = 0; i < strlen(ERR_INFO); i++)
      X) x% i/ d, f, b; h: v; f
  9.         {. {5 Z" Y4 O+ D5 O$ ~  ]
  10.                 USART1->TDR = pError<i>;
    5 P9 c8 _5 `7 L; i" E- A3 U  g
  11.                 /* 等待发送结束 */
    ! Q4 s( V0 c2 n- H
  12.               </i>  while((USART1->ISR & USART_ISR_TC) == 0);
    3 \* p1 T' t" f* I# M1 X) ~
  13.         }        / x, Y2 Z% X) {  N) G
  14. }
      S( x- o8 N; U$ [# u% T/ a
  15. #endif
复制代码

" v4 b1 _: Y1 e/ L11.3 MDK锁定硬件异常位置方法$ W: ]$ ~( U& L) m( l% L' _
以本章配套的例子为大家做个说明。
* X: g% `! v$ v+ u! t3 d7 c2 l, J" Q
1、测试方法比较简单,进入调试状态,全速运行,然后按下K1按键,就会进入硬件异常中断,此时停止调试,程序就会自动定位到如下位置:8 d9 I& |  d  ^

+ B5 [4 F7 r4 I; n( l3 A
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
2 V; `, p6 y7 i& z! z% _9 M

1 U  s* I  L$ ?9 W2、在Watch1窗口添加变量_Continue1 |0 o# I  n* A1 r$ G9 ~

' F8 j% p0 `9 z* n% W7 I$ }
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

+ h7 Q, c- s0 E; _, l) K1 z$ S- y& Y$ d1 Q
3、修改为任何非0数值,就可以继续单步调试。这个代码后面还有一个第1步中的while循环,也可以继续采用第2步的方法修改。退出硬件异常后就是大家进入硬件异常前下一条要执行的指令(可能还是这个函数本身,因为一个函数由多个指令完成)。定位到出问题的位置:1 ], A+ p& h( k  C7 Y" O2 A2 k. G

9 P( F1 o! u+ J3 e- F
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

! i, I0 z" X6 M* h( q  F5 q& w6 T* k# ?" U1 C, P5 D$ S3 f& Y
11.4 IAR锁定硬件异常位置方法
  t; p( a+ [, Q" X- l- ?0 g/ `: Y
以本章配套的例子为大家做个说明。! X! [; M7 f) x4 U) ^5 i
! f! d- L. ?( d2 F$ {
1、测试方法比较简单,进入调试状态,全速运行,然后按下K1按键,就会进入硬件异常中断,此时停止调试,程序就会自动定位到如下位置:
2 g. @% \% A+ k! Q
, _- d9 i1 u" Z1 b3 s2 g
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
5 H. l4 v# f( x& M

- U  z$ Z8 j, L2、在Watch1窗口添加变量_Continue0 ~0 K; Z9 v/ d

5 P6 ?% b% O6 h' Q
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

6 K; N, f; O5 |2 S/ m( c8 \0 j. ^$ w/ Y7 C- c0 x) m
3、修改为任何非0数值,就可以继续单步调试。这个代码后面还有一个第1步中的while循环,也可以继续采用第2步的方法修改。退出硬件异常后就是大家进入硬件异常前下一条要执行的指令(可能还是这个函数本身,因为一个函数由多个指令完成)。定位到出问题的位置:" p) [- j' x# ^* i4 M( X

! O% J3 v( e2 V3 l1 {& M9 J
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

8 a8 }8 U# L2 X/ F  e
4 j0 ~8 `, R; O. n11.5 硬件异常原因分析
# E, u, C, Q- R0 k1 B9 ASEGGER提供的这个机制查找出问题的位置比较方便,具体原因需要继续在调试界面里面添加HardFaultRegs结构变量,这个结构体变量添加了所有大家想看的东西。下面是MDK调试状态查看部分结构体数值:' p" P& H% i* m% Q) S$ V

0 V; g) M4 G2 j/ P, ~9 t% ?
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
4 ~1 d/ I% ]4 O6 |" j$ ]

& d* J2 ^3 o& n  k: V$ i具体上面的变量代表什么含义呢,代码里面有注释,查阅起来没有IAR自带的硬件异常提示方便(注意,下面的代码用到了位域)。: M2 Z9 R: d0 g# @3 P! H

. {& G+ W; A3 f. M! K! ^6 e
  1. #if DEBUG
    8 N4 |* @" M8 f+ ]0 j9 p
  2. static volatile unsigned int _Continue;  // Set this variable to 1 to run further
    ' L. s- t9 `* c: g1 H: e7 @/ {

  3. 3 Y) v$ z' |- ]( k& t
  4. static struct {1 Q* T$ s& P$ b- C0 j* M8 r
  5.   struct {
    - f6 r) _  V) n- s5 Z- v2 }8 ^
  6.     volatile unsigned int r0;            // Register R0+ l) U- c( o' }
  7.     volatile unsigned int r1;            // Register R1
    , f2 p4 R, l9 m9 N! H1 ^. D
  8.     volatile unsigned int r2;            // Register R2' W* D' z0 X5 \3 V7 k+ ]
  9.     volatile unsigned int r3;            // Register R3
      z* c+ g( l& H- x; T' k
  10.     volatile unsigned int r12;           // Register R12
    / F5 f) i4 Q- v3 b5 o0 E1 q
  11.     volatile unsigned int lr;            // Link register
    - ^' {/ t: ?4 ~% o
  12.     volatile unsigned int pc;            // Program counter
    - W+ q$ k5 S9 w: f% a
  13.     union {- D: q; X5 |- z: j8 I
  14.       volatile unsigned int byte;9 r% ?/ H  y4 h4 y1 |* d5 k0 F2 ~
  15.       struct {
    ' N' J. u6 }) ~2 P
  16.         unsigned int IPSR : 8;           // Interrupt Program Status register (IPSR). Y3 X( a. `& N" ]% z( V, ~) C
  17.         unsigned int EPSR : 19;          // Execution Program Status register (EPSR)
    ( \. ^2 a: @  K8 L9 K% t" h  a
  18.         unsigned int APSR : 5;           // Application Program Status register (APSR)
    * `% m, T) U! K- ]  z2 K6 A
  19.       } bits;' c' K* M% d6 i' N3 ?: d
  20.     } psr;                               // Program status register.
    6 A$ ?4 d3 P4 p8 b. M4 K( U
  21.   } SavedRegs;
    + e7 p  g# {3 d4 q; ^2 T' b8 P

  22. & _. |' ]4 D, a. H  d7 v
  23.   union {
    . g$ ^+ R* B# t% E$ w
  24.     volatile unsigned int byte;
    ) F3 H7 u* D- t/ d- w9 g3 J2 O
  25.     struct {
    " K% x2 l& @6 w# P% s
  26.       unsigned int MEMFAULTACT    : 1;   // Read as 1 if memory management fault is active
    ' O8 n1 S+ o9 h. \- M
  27.       unsigned int BUSFAULTACT    : 1;   // Read as 1 if bus fault exception is active$ F& k8 E8 S$ U" @
  28.       unsigned int UnusedBits1    : 1;
    " \0 P( g3 R' i$ K! G7 N
  29.       unsigned int USGFAULTACT    : 1;   // Read as 1 if usage fault exception is active
    7 y& Q8 j. {+ J( j" O7 |) R
  30.       unsigned int UnusedBits2    : 3;
    ( T/ v2 k+ y2 m( L! b% L3 D5 R
  31.       unsigned int SVCALLACT      : 1;   // Read as 1 if SVC exception is active" o7 C+ X/ x+ R2 U% R8 E
  32.       unsigned int MONITORACT     : 1;   // Read as 1 if debug monitor exception is active0 l( V7 i3 `5 s
  33.       unsigned int UnusedBits3    : 1;2 s1 Y: R; c# x1 p4 F/ e: u" g
  34.       unsigned int PENDSVACT      : 1;   // Read as 1 if PendSV exception is active' V6 P  {  @. S$ w8 h" q0 H
  35.       unsigned int SYSTICKACT     : 1;   // Read as 1 if SYSTICK exception is active
    9 _! {6 ?. Y+ r4 b
  36.       unsigned int USGFAULTPENDED : 1;   // Usage fault pended; usage fault started but was replaced by a& v2 p$ S8 L% g' Z( C
  37. higher-priority exception$ t( V( F! p, B0 n' N9 ?
  38.       unsigned int MEMFAULTPENDED : 1;   //  Memory management fault pended; memory management fault started# b& [8 v& X, d5 {+ s
  39. but was replaced by a higher-priority exception+ R( {8 X  h  L: B. ~
  40.       unsigned int BUSFAULTPENDED : 1;   // Bus fault pended; bus fault handler was started but was replaced7 L& _* n1 Z( I7 o& x
  41. by a higher-priority exception
    4 G) z# C* M6 ?/ d
  42.       unsigned int SVCALLPENDED   : 1;   // SVC pended; SVC was started but was replaced by a higher-priority
    - P) {& N9 I- ]& q- k# s. U% Q9 x# g+ @
  43. exception
    & k6 C: k2 T7 A# O2 u' i
  44.       unsigned int MEMFAULTENA    : 1;   // Memory management fault handler enable
    1 x+ C; ?. J& i+ v: h0 {/ W' ~
  45.       unsigned int BUSFAULTENA    : 1;   // Bus fault handler enable8 }7 b" O, H& Q9 R* ~
  46.       unsigned int USGFAULTENA    : 1;   // Usage fault handler enable
    7 b3 R$ C3 G1 C6 Q0 N) k5 K
  47.     } bits;
    - A- o/ W3 z6 A% Q" N
  48.   } syshndctrl;                          // System Handler Control and State Register (0xE000ED24)
    : E  R1 C4 T0 h, b
  49. 3 O& W9 w1 S! m3 V9 q8 t6 ?7 r+ C
  50.   /* 省略未写 */" o% s% a3 Y/ W: W- H- x
  51. / |, Z; k. ^/ K" X$ I9 x  R) K
  52.   volatile unsigned int afsr;            // Auxiliary Fault Status Register (0xE000ED3C), Vendor controlled (optional)' B+ o1 }1 Z2 D: q" _
  53. } HardFaultRegs;
    5 V( }  `4 g8 h3 k- I
  54. #endif
复制代码

+ ~2 u; h% G/ ]( |; P8 v3 y11.6 IAR自带的硬件异常分析
. Q+ O7 f; W3 m* Z6 @! P还以本章配套的例子为例,进入调试状态,全速运行,然后按下K1按键,就会进入硬件异常中断,此时停止调试,IAR还会弹出一个硬件异常错误分析,刚进来的时候也许是个空白+ n' ?4 z* ]. N3 `" I7 k6 I

; d' Q' K4 Q4 z" T
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
0 H2 L$ Z5 u; P  C* C, g- d

, {' k* f) E* d& j6 P单步调试刷新下就出来了:
* N* d. U$ U# Y: o' U% C2 n
* ~3 N; e3 \" p% }% X
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

# e, j# S% b8 y7 T  G5 B3 _( ]8 t. ?. U9 {: I6 J
指出了问题的原因是操作的数据地址有问题。( @, q0 j! w* ]- i. j( m  E
4 R& U. [: j3 N# Q
11.7 实验例程1 a3 W' S/ A" R1 n2 b+ f
专门为本章节配套了一个例子:V7-009_移植SEGGER的硬件异常分析机制。大家可以按照本章教程提供的方法进行测试。+ T% ]  U  M5 S- g. ~2 W( r
3 I- y* K/ W2 h9 U
11.8 总结
; c( T! y: _% ]4 h/ f: p2 t* \除了SEGGER的硬件异常分析方案,建议也测试下MDK和IAR的,以后遇到硬件异常问题,解决起来可以得心应手。
! |( x- k3 X5 p3 @  c! H! ]: B, p
8 L( k; h) S9 V1 V' n; Y8 H8 U# _2 y2 _
收藏 评论0 发布时间:2022-1-1 20:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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