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

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

[复制链接]
STMCU小助手 发布时间:2022-1-1 20:00
11.1 初学者重要提示1 p, G5 G9 V3 S( U8 _; c& l
  MDK本身也是支持硬件异常分析的,就是不够直观* B$ f$ S0 N& r3 g* P! Z* z  A7 U: p
; x/ O! l: H+ h6 {
  IAR8带的硬件异常分析比较好用,在本章11.6小节有说明。
) F% T. g$ [# m. T# b$ \11.2 移植方法5 `. z3 A7 A. ?/ R4 |6 q# G$ R& z1 k: m
直接移植SEGGER的硬件异常代码会有错误警告,这里针对IAR和MDK版本做了些简单修改,方便大家移植到自己的工程里面。
1 O  i3 t# j; a# P8 X: @
% _" H! h& j2 I& H7 l- b) C  MDK版本移植
& V: p1 X* ~3 j, p3 {3 X% m0 X  y源文件位于本章配套例子的\User\segger\HardFaultHandlerMDK文件夹,添加如下两个文件到工程里面即可。
& H  _0 [+ Y3 a7 o) i4 I9 K9 @/ x/ \2 X$ R5 i9 [1 k9 X
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
3 u# B8 f9 i5 |" f
: b1 t  ~  B4 }
  IAR版本移植1 X$ Y0 j/ y7 Q/ |* m2 t$ ~2 h
源文件位于本章配套例子的\User\segger\HardFaultHandlerIAR文件夹,添加如下两个文件到工程里面即可。
3 y9 m# [$ G/ ]9 h
0 h) `/ y: j( w- T* N- A! u
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

6 K% E5 |7 b# h! L  t8 r7 z: r& W" q: y
在文件SEGGER_HardFaultHandler.c里面都添加了串口打印功能,方便不用编译器的调试功能时,通过串口打印提示是否进入硬件异常。
. S+ y+ L" y- l
# \" w8 }1 j; [3 |7 N; v! l: s. \
  1. #define ERR_INFO "\r\nEnter HardFault_Handler, System Halt.\r\n"5 i; }$ l+ L2 D

  2. * B7 E( }# }7 g+ T: k7 r
  3. #if 1
    . Y  e5 e# W' M& w, O$ @
  4. {9 ~/ |/ t, F( B# t# i
  5.         const char *pError = ERR_INFO;' Y' l9 W& `1 \5 d8 S
  6.         uint8_t i;2 O9 R8 W2 _7 Z5 j" m0 w: L+ L
  7. & W8 z( t' ]- `# {
  8.         for (i = 0; i < strlen(ERR_INFO); i++)
    4 U7 a; M# i# C& |' x9 F  Q+ p
  9.         {
    , V$ J8 D% F3 ^2 G
  10.                 USART1->TDR = pError<i>;
    $ ]9 _/ j! Y3 Z, b, B7 f) }. b
  11.                 /* 等待发送结束 */
    , W2 }1 f" y3 H* f: Q4 m
  12.               </i>  while((USART1->ISR & USART_ISR_TC) == 0);  e+ V! t- ?2 B! n( `  u
  13.         }        
      D* D& L: A3 I4 o) U
  14. }
    " @9 `* X. Z9 T) O8 B+ p
  15. #endif
复制代码

' y3 H% A% G  d' y/ a  J" K7 s11.3 MDK锁定硬件异常位置方法( h2 |3 R8 |9 D2 w
以本章配套的例子为大家做个说明。2 k: H9 A5 w, y6 N2 E7 A9 w2 Y8 b" u0 l

( ?$ g# \6 p: s( |1、测试方法比较简单,进入调试状态,全速运行,然后按下K1按键,就会进入硬件异常中断,此时停止调试,程序就会自动定位到如下位置:
* Q$ e  p2 V9 P4 y+ l. Q, N7 N9 l- b. H  W
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
. ]1 x. K# X4 J
( S  m7 _3 `6 N6 w/ w$ x  ^4 \: h
2、在Watch1窗口添加变量_Continue$ v5 m- }, n/ B  x) @5 m

6 v' u6 ~% Y( Q
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

1 R" F) s& b+ L) B
( _9 x& s+ M$ Q, ~3 c9 t" e' P/ ^3、修改为任何非0数值,就可以继续单步调试。这个代码后面还有一个第1步中的while循环,也可以继续采用第2步的方法修改。退出硬件异常后就是大家进入硬件异常前下一条要执行的指令(可能还是这个函数本身,因为一个函数由多个指令完成)。定位到出问题的位置:
% ^- u9 I6 N1 ]. E- R; x8 c# t' s* C( M/ }  K# R4 l: [  d" `
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
9 \# u9 P# l7 b

' a# Q9 u/ r" R! {) w. c  z11.4 IAR锁定硬件异常位置方法
4 n  b) D, Z6 S4 F# B1 D! s$ G3 s
以本章配套的例子为大家做个说明。$ y0 F1 p, {4 N$ \% f

0 W4 d7 B4 H0 }, C; m# {1、测试方法比较简单,进入调试状态,全速运行,然后按下K1按键,就会进入硬件异常中断,此时停止调试,程序就会自动定位到如下位置:' s7 Q" ]+ l. n7 K% }
. s  g: t* z4 E" n6 r8 w2 e9 _4 o7 c1 I
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

/ F( I: \* p2 H  |. F. X2 o6 P
8 Z7 f/ B5 G- J3 p/ @4 A$ b- @% A4 e2、在Watch1窗口添加变量_Continue
; o! h& v9 x' r# @: l. c! L) a/ w0 v# L- A
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

* Z8 v+ f" k* n: @" y$ x
$ J' ^/ s2 M! s7 T# \3、修改为任何非0数值,就可以继续单步调试。这个代码后面还有一个第1步中的while循环,也可以继续采用第2步的方法修改。退出硬件异常后就是大家进入硬件异常前下一条要执行的指令(可能还是这个函数本身,因为一个函数由多个指令完成)。定位到出问题的位置:
  F  E9 B: H! f- a( x) ?- g3 `
& p1 F% _/ L8 v
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

  v8 u% M& R8 C$ K& H& a
5 h! o) t. |/ B% G, M  O& @11.5 硬件异常原因分析
1 r# G  `" \2 p. S# bSEGGER提供的这个机制查找出问题的位置比较方便,具体原因需要继续在调试界面里面添加HardFaultRegs结构变量,这个结构体变量添加了所有大家想看的东西。下面是MDK调试状态查看部分结构体数值:
( N/ k, @& x6 Z- n4 j7 N" ?9 K6 U! L0 n" k; {6 H2 Y' e$ ?* `7 \
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
) j' T; u4 k  N& I$ D' X7 k4 Z

# X" _; R, m7 ?% n" y6 P4 u+ _具体上面的变量代表什么含义呢,代码里面有注释,查阅起来没有IAR自带的硬件异常提示方便(注意,下面的代码用到了位域)。& m8 [) }/ S0 {( X9 ]! f
( a* c0 Z) h0 W% m
  1. #if DEBUG, X! `4 w& s- }0 W% S1 b
  2. static volatile unsigned int _Continue;  // Set this variable to 1 to run further
    6 s" n  M0 O$ N8 D- A2 T0 }4 m. ]
  3. , B- r9 Z1 _' |$ B
  4. static struct {+ S" g/ Q5 }. j
  5.   struct {
    % j5 K2 i; ]( f
  6.     volatile unsigned int r0;            // Register R0. n# o1 I0 Q0 ]- j' v3 |
  7.     volatile unsigned int r1;            // Register R1
    . w! @) S" k8 a6 V% a' g) v: J5 }
  8.     volatile unsigned int r2;            // Register R2
    9 o9 K; h- Y( A0 s6 U% [* H
  9.     volatile unsigned int r3;            // Register R3
    ( G  ]' W$ d" ]9 e7 y' y: n5 ~5 L
  10.     volatile unsigned int r12;           // Register R128 r4 }( R3 ^6 F( g+ {; ~) W
  11.     volatile unsigned int lr;            // Link register& n1 D' P6 q$ Y+ l
  12.     volatile unsigned int pc;            // Program counter
    7 T) p3 |( k6 r& N% S/ \
  13.     union {
    # g; x1 d3 x$ _! n. {
  14.       volatile unsigned int byte;
    ! i1 ^/ J3 X& D6 ?
  15.       struct {" f  d5 O; {. Y2 g3 F
  16.         unsigned int IPSR : 8;           // Interrupt Program Status register (IPSR)% U/ n/ J! T) _0 l( {1 R$ u' Z* I
  17.         unsigned int EPSR : 19;          // Execution Program Status register (EPSR), }( [- H' Q! j0 J
  18.         unsigned int APSR : 5;           // Application Program Status register (APSR)- m8 K7 C$ S' }, [, O( ]
  19.       } bits;
    : w$ i! D1 E) C( q
  20.     } psr;                               // Program status register.
    5 U$ Y& S4 f; l6 ]# N3 o
  21.   } SavedRegs;; r1 r: S! A4 q  W% f& j

  22. 1 w# L. I$ x: ?. `% ?
  23.   union {  R# W' i1 [; r
  24.     volatile unsigned int byte;( [8 b  Q$ O. e1 E% z% `
  25.     struct {
    / \* f4 e6 S: w8 a; V  K) ^2 e6 _4 z
  26.       unsigned int MEMFAULTACT    : 1;   // Read as 1 if memory management fault is active/ U% A/ ]( S, M9 D
  27.       unsigned int BUSFAULTACT    : 1;   // Read as 1 if bus fault exception is active
      b( b6 g) ?  F# h
  28.       unsigned int UnusedBits1    : 1;
    7 N% }) i8 P9 x& M* F' I6 J4 g
  29.       unsigned int USGFAULTACT    : 1;   // Read as 1 if usage fault exception is active
    7 L# d4 I1 C$ R) G/ }
  30.       unsigned int UnusedBits2    : 3;# j9 n4 c( d3 ~$ Z4 f% [; D
  31.       unsigned int SVCALLACT      : 1;   // Read as 1 if SVC exception is active
    0 a  ^. x- w7 U6 t
  32.       unsigned int MONITORACT     : 1;   // Read as 1 if debug monitor exception is active# {" t! r7 U6 b, ~2 Q% ^( t
  33.       unsigned int UnusedBits3    : 1;. b& X8 @+ h' L
  34.       unsigned int PENDSVACT      : 1;   // Read as 1 if PendSV exception is active! }* z' y- v/ X4 l5 Z' s3 h9 H$ [
  35.       unsigned int SYSTICKACT     : 1;   // Read as 1 if SYSTICK exception is active
    ( |- k' i8 R' d& X
  36.       unsigned int USGFAULTPENDED : 1;   // Usage fault pended; usage fault started but was replaced by a6 ?+ t4 J. _" D7 e9 G
  37. higher-priority exception
      @& K0 H* u& x, c; t( V3 y8 w
  38.       unsigned int MEMFAULTPENDED : 1;   //  Memory management fault pended; memory management fault started
    . d) V" {* t0 p
  39. but was replaced by a higher-priority exception: z5 k0 O0 z9 s% C7 L/ Y6 @5 _7 W
  40.       unsigned int BUSFAULTPENDED : 1;   // Bus fault pended; bus fault handler was started but was replaced
    / v/ k" T4 n1 ~" V6 `) h
  41. by a higher-priority exception# m& ~4 {; ?$ e% D; U2 D
  42.       unsigned int SVCALLPENDED   : 1;   // SVC pended; SVC was started but was replaced by a higher-priority
    ) v9 b3 ^) S& q+ n5 l) u! [- U
  43. exception, b: W- j" {3 Q, t4 o
  44.       unsigned int MEMFAULTENA    : 1;   // Memory management fault handler enable
    2 C. Z$ e. L" C& q7 U. Q( j
  45.       unsigned int BUSFAULTENA    : 1;   // Bus fault handler enable) Y5 D' A4 V$ R4 v' {" T& p
  46.       unsigned int USGFAULTENA    : 1;   // Usage fault handler enable
    5 b, }4 T. z, @3 u5 l
  47.     } bits;. D% |' f9 x; Y
  48.   } syshndctrl;                          // System Handler Control and State Register (0xE000ED24)8 o5 ]0 J/ Q- c) X+ l/ W) `2 b

  49. 1 U- i" g1 x" N6 r" s
  50.   /* 省略未写 */
    ( L% c, S1 r1 M0 @& \

  51. : I3 |+ e% j  T- D1 s
  52.   volatile unsigned int afsr;            // Auxiliary Fault Status Register (0xE000ED3C), Vendor controlled (optional)
    " a4 y9 ?$ [5 F2 K& q& L
  53. } HardFaultRegs;& Z* @5 E( p# M8 t4 e/ G5 y
  54. #endif
复制代码
# I& `% X# ~* I8 c
11.6 IAR自带的硬件异常分析
6 o# ^2 E4 Z/ V) E还以本章配套的例子为例,进入调试状态,全速运行,然后按下K1按键,就会进入硬件异常中断,此时停止调试,IAR还会弹出一个硬件异常错误分析,刚进来的时候也许是个空白
: v/ T$ o2 G& G$ o1 O5 Z4 U6 {& a; N( p- o+ n- n# A
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
2 m0 _! `& m; B- n8 u1 s4 J% O
5 M- H2 `( G# z; A# Z# z" f
单步调试刷新下就出来了:" b0 e* m) M) t
- m$ S$ `5 q) H1 ]) L7 O
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
4 Q7 N0 P  Y/ D' C4 q( `# D8 k3 c! ?

+ V1 p+ n9 v! o3 _' L9 }/ b指出了问题的原因是操作的数据地址有问题。2 @  \4 o- I7 h0 Z; b
0 M( b1 ]+ D1 ]. r, a) \4 n1 [
11.7 实验例程4 A) J6 P4 z1 Y, a
专门为本章节配套了一个例子:V7-009_移植SEGGER的硬件异常分析机制。大家可以按照本章教程提供的方法进行测试。
$ k7 {% k$ x: J, x* D" i5 {' R5 D) w: I* ~. x2 ^2 y( M! ?: ^# ^
11.8 总结& C0 \1 `. H6 h8 `) M% w
除了SEGGER的硬件异常分析方案,建议也测试下MDK和IAR的,以后遇到硬件异常问题,解决起来可以得心应手。* w! S5 X" l3 ~/ m, Q( e$ C
8 {1 A# r& e2 b2 t- u
: N5 p# [+ [8 W# `& ^) o
收藏 评论0 发布时间:2022-1-1 20:00

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版