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

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

[复制链接]
STMCU小助手 发布时间:2022-1-1 20:00
11.1 初学者重要提示
' I$ h" Z4 p+ q" ], L& q0 P  MDK本身也是支持硬件异常分析的,就是不够直观
- m- g5 v7 a  }
" v4 A6 i& W4 J  IAR8带的硬件异常分析比较好用,在本章11.6小节有说明。( @" L/ j, D; e& `' s, [
11.2 移植方法, X8 \. l/ q, E5 F9 u
直接移植SEGGER的硬件异常代码会有错误警告,这里针对IAR和MDK版本做了些简单修改,方便大家移植到自己的工程里面。
+ q4 s! |* [: e+ h; J( F
/ n/ _# K% t: \- @7 Z  o, w  MDK版本移植
6 z4 q0 X* ~1 r5 I# g源文件位于本章配套例子的\User\segger\HardFaultHandlerMDK文件夹,添加如下两个文件到工程里面即可。
& y* _; K. Z" D! F  V# W$ t& [8 ]- k
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
' G4 O9 h" k3 e' s

& h9 p; p0 c1 {2 }& A0 O* w4 p  IAR版本移植
1 _  M! w. V( b! @! s% E/ Y& t' D- G$ W源文件位于本章配套例子的\User\segger\HardFaultHandlerIAR文件夹,添加如下两个文件到工程里面即可。8 O; a7 d1 [2 \7 {$ M: M& a* U  W

7 i, H2 U8 m) v' \& s( |- ^6 Y
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

9 o& L' o/ @9 {, v  M: a: B5 A/ Q
- N; p3 |& q, r+ u4 f在文件SEGGER_HardFaultHandler.c里面都添加了串口打印功能,方便不用编译器的调试功能时,通过串口打印提示是否进入硬件异常。2 C/ _( P( }3 ~+ [. J, u( H: v

# n- h: J0 F5 g8 C$ E8 G' A
  1. #define ERR_INFO "\r\nEnter HardFault_Handler, System Halt.\r\n"; l) `5 |$ P- O6 |! I
  2. ' \) h- t* I5 @6 `/ l+ x. \
  3. #if 1. _/ @/ e8 V: }' ~! y2 ?  ?
  4. {
    1 ~, |8 |' W: z% @0 Z8 B. W
  5.         const char *pError = ERR_INFO;
    2 U9 s# u5 G2 H/ Q! z
  6.         uint8_t i;) D" d# V0 H% u% I( o
  7. 5 {. K9 @  i2 o5 n4 l9 ^
  8.         for (i = 0; i < strlen(ERR_INFO); i++)
    5 A, l! O* K" D6 k1 h, ^
  9.         {
    ; v/ a& o$ w+ ^: A
  10.                 USART1->TDR = pError<i>;
    / o  [* h  e. T
  11.                 /* 等待发送结束 */
    / h1 m$ v% D; F& \9 R0 Q! v6 Q
  12.               </i>  while((USART1->ISR & USART_ISR_TC) == 0);+ A- A7 u3 ^, l" t; `8 e
  13.         }        
    4 Z. p7 x- Q' O( J1 r
  14. }& I$ _' U. c' O0 T4 o1 P/ p- [" `
  15. #endif
复制代码
$ ^8 B+ K& {: L% k6 J0 a+ S! B
11.3 MDK锁定硬件异常位置方法
( Y/ P' R* x0 ]: |( }1 K( o; `以本章配套的例子为大家做个说明。$ _5 C" |9 x  w  B

! v9 q5 C# f* t/ N0 E1、测试方法比较简单,进入调试状态,全速运行,然后按下K1按键,就会进入硬件异常中断,此时停止调试,程序就会自动定位到如下位置:
, _7 b$ u7 n: H1 u, C, D5 N, P. Z. m1 W& r2 t
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

; x3 x: A% P: f- W5 j9 `/ g% U& X# \8 C! _7 Z$ ~
2、在Watch1窗口添加变量_Continue
2 Y' ]. f7 j1 R; z/ M' P8 j9 I5 U7 H7 q3 w- D% ?4 J/ _4 C
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
. Y! x0 p. v6 \' c& U( S
9 b+ Y1 p  _& D3 M# ~
3、修改为任何非0数值,就可以继续单步调试。这个代码后面还有一个第1步中的while循环,也可以继续采用第2步的方法修改。退出硬件异常后就是大家进入硬件异常前下一条要执行的指令(可能还是这个函数本身,因为一个函数由多个指令完成)。定位到出问题的位置:9 P: l' Q3 C/ X3 z
* n* L* x3 I1 T5 J! d* i% I6 O
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

6 Y2 q' ~% v# M7 Y, @% v7 O* N2 D3 K9 c: k+ @# C0 X/ [( D
11.4 IAR锁定硬件异常位置方法

4 h; {7 {5 |3 K% U& q& s$ O0 y以本章配套的例子为大家做个说明。
' x, s+ D4 a+ J  O" W' y# P9 {( w3 k8 f
1、测试方法比较简单,进入调试状态,全速运行,然后按下K1按键,就会进入硬件异常中断,此时停止调试,程序就会自动定位到如下位置:: a/ b$ k* @2 Q" \; z
7 x. O9 p, g1 j- h, a$ y8 S
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
9 V4 s1 H) i; [9 K& o
1 Q" d9 W+ F( U% p0 W& k
2、在Watch1窗口添加变量_Continue1 r( v' g, Z9 x& _

  Y+ D- g, F3 `3 V
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

- @: t% R: R, T$ J! C" y& j" q- e" V
3、修改为任何非0数值,就可以继续单步调试。这个代码后面还有一个第1步中的while循环,也可以继续采用第2步的方法修改。退出硬件异常后就是大家进入硬件异常前下一条要执行的指令(可能还是这个函数本身,因为一个函数由多个指令完成)。定位到出问题的位置:
0 Z, b1 P% q9 U# t& ?) f- `- \* F1 o. Z4 O( \* B4 b/ R
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
* H/ Q3 x/ m! @# f
% f' Z* e% H. J$ e/ w
11.5 硬件异常原因分析1 K. G/ u( {+ e
SEGGER提供的这个机制查找出问题的位置比较方便,具体原因需要继续在调试界面里面添加HardFaultRegs结构变量,这个结构体变量添加了所有大家想看的东西。下面是MDK调试状态查看部分结构体数值:6 A- Z0 n4 s; t! u) n  e

1 p: J# A" u& U& J! m: `
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
& ^  Q+ p: f3 v7 Q( t

0 [1 Y4 ]% `, y4 N) \* D4 t4 l1 s具体上面的变量代表什么含义呢,代码里面有注释,查阅起来没有IAR自带的硬件异常提示方便(注意,下面的代码用到了位域)。8 z! W% t$ [6 r4 a/ T4 ]" n% Q" [

7 _2 h7 p% n( N6 `
  1. #if DEBUG
    ( s& C" ^5 S% Q4 f0 |
  2. static volatile unsigned int _Continue;  // Set this variable to 1 to run further( E( Q( G7 B9 k# i: t

  3. : ^3 n8 A4 O' \5 Y# \
  4. static struct {2 z* |! S$ L) C: I+ I  m+ N2 R
  5.   struct {% Q1 U; W# T* H, i
  6.     volatile unsigned int r0;            // Register R0
    ) X0 C( ]) f- J+ A. T
  7.     volatile unsigned int r1;            // Register R13 [/ H" |4 U' }1 S! \2 f0 v: z/ k
  8.     volatile unsigned int r2;            // Register R2
    ' L; \5 @2 P: Y) ?; W
  9.     volatile unsigned int r3;            // Register R3
    $ ~; C# c9 L2 R
  10.     volatile unsigned int r12;           // Register R12
    ( R( Z' Q" B, |2 K* K0 Z# g
  11.     volatile unsigned int lr;            // Link register
    ) K) T. W% f! T/ ]8 p
  12.     volatile unsigned int pc;            // Program counter+ w+ h7 S- u1 ^7 v
  13.     union {, ~/ E3 `: X0 u
  14.       volatile unsigned int byte;
    " `; J* [# b& Z0 x
  15.       struct {
    + B) U8 i3 v. Z  D/ r
  16.         unsigned int IPSR : 8;           // Interrupt Program Status register (IPSR)+ M- d- Y! I2 h4 V; T
  17.         unsigned int EPSR : 19;          // Execution Program Status register (EPSR)
    9 V; N6 H2 z$ T! t# N, I1 D
  18.         unsigned int APSR : 5;           // Application Program Status register (APSR), X0 X$ r- ^' W. N  f5 l
  19.       } bits;- a" s- Y3 w% H. `  _
  20.     } psr;                               // Program status register.8 x! ~. P! ?' K: @
  21.   } SavedRegs;% L; @, l# j* K+ b
  22.   G8 h3 v# s/ d2 a3 g2 I
  23.   union {) X/ ^  c: o* Y# ~% X4 m" N" ?
  24.     volatile unsigned int byte;( n2 Y! u( O. J* J- z
  25.     struct {8 z1 ~& P( }2 }2 J7 V
  26.       unsigned int MEMFAULTACT    : 1;   // Read as 1 if memory management fault is active9 q! Y5 T( b0 i+ t
  27.       unsigned int BUSFAULTACT    : 1;   // Read as 1 if bus fault exception is active: x7 B8 R4 X; f6 y7 G) Z* W/ t
  28.       unsigned int UnusedBits1    : 1;* C. F& ^2 {# E! |1 S  y
  29.       unsigned int USGFAULTACT    : 1;   // Read as 1 if usage fault exception is active
    , n  M# b9 i; u* B& t- Y/ R! J
  30.       unsigned int UnusedBits2    : 3;
    - Y7 r: _  C  ^- u; j7 B, V7 R
  31.       unsigned int SVCALLACT      : 1;   // Read as 1 if SVC exception is active
    % @4 A/ a" p8 i) ]2 e  {
  32.       unsigned int MONITORACT     : 1;   // Read as 1 if debug monitor exception is active2 s1 l7 _/ W6 {! E
  33.       unsigned int UnusedBits3    : 1;
    $ Z' F& _! u* L& k+ I
  34.       unsigned int PENDSVACT      : 1;   // Read as 1 if PendSV exception is active+ G; J5 F: h+ F1 z& b8 a5 y% Z
  35.       unsigned int SYSTICKACT     : 1;   // Read as 1 if SYSTICK exception is active
    7 w4 b' o& `3 |  ?+ [- v3 _$ N
  36.       unsigned int USGFAULTPENDED : 1;   // Usage fault pended; usage fault started but was replaced by a% U+ G  E/ H0 S
  37. higher-priority exception& O( V% W4 L9 b4 [
  38.       unsigned int MEMFAULTPENDED : 1;   //  Memory management fault pended; memory management fault started; F+ h  p% _. |1 ~: D% ~" Y4 Z
  39. but was replaced by a higher-priority exception
    2 P0 |/ U2 X7 l! m4 F
  40.       unsigned int BUSFAULTPENDED : 1;   // Bus fault pended; bus fault handler was started but was replaced
    / P5 p, m. C/ I1 [7 f
  41. by a higher-priority exception
    & p3 p0 i- h/ o7 ]3 U
  42.       unsigned int SVCALLPENDED   : 1;   // SVC pended; SVC was started but was replaced by a higher-priority
    ( a* y8 Q+ Z" H
  43. exception7 d/ \4 u' O8 V7 s5 ~2 ~
  44.       unsigned int MEMFAULTENA    : 1;   // Memory management fault handler enable
    7 Z6 k% F7 k8 ?
  45.       unsigned int BUSFAULTENA    : 1;   // Bus fault handler enable( }7 J8 E( f2 X) D
  46.       unsigned int USGFAULTENA    : 1;   // Usage fault handler enable5 n2 u* r1 @& Q* F# C3 M* A
  47.     } bits;
    & g7 h+ G+ K# p1 N$ Z* R  \$ z
  48.   } syshndctrl;                          // System Handler Control and State Register (0xE000ED24)5 ~! Z- o  n# d0 G% b) ?
  49. 7 m; r& N# t, o% H
  50.   /* 省略未写 */5 M5 `) P5 x' ]- B3 G9 E1 ^/ K

  51. % I: Q7 N! F* {% M' _) S
  52.   volatile unsigned int afsr;            // Auxiliary Fault Status Register (0xE000ED3C), Vendor controlled (optional)9 p# M9 {% c- C/ G% w7 p: {9 A
  53. } HardFaultRegs;* m; [$ \4 A" {" L. W  v
  54. #endif
复制代码
$ Q. C" z# P1 y5 V/ x; l
11.6 IAR自带的硬件异常分析
. Q7 `0 M! G- v0 f2 z3 i3 Q; f还以本章配套的例子为例,进入调试状态,全速运行,然后按下K1按键,就会进入硬件异常中断,此时停止调试,IAR还会弹出一个硬件异常错误分析,刚进来的时候也许是个空白& R% C  k, ~- s/ R* M) t% [# ?
8 h; M" S! I4 [9 l
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
3 [% b6 ]/ W% W# [( ^/ O# b

8 @) y# n8 p% d0 S单步调试刷新下就出来了:5 O) g2 f1 z8 a) d9 L
1 L; X7 @6 n* b( I
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
3 R% |" [( z: R" Z* R
3 X% j) R& f* {8 T
指出了问题的原因是操作的数据地址有问题。+ C  E8 w6 c5 P

2 ]4 d& i* g, m11.7 实验例程2 @4 h: }+ I( J
专门为本章节配套了一个例子:V7-009_移植SEGGER的硬件异常分析机制。大家可以按照本章教程提供的方法进行测试。0 |+ ~# `2 j: C. f
$ t( I, X- j( e1 r
11.8 总结2 ]0 y; z" M- T
除了SEGGER的硬件异常分析方案,建议也测试下MDK和IAR的,以后遇到硬件异常问题,解决起来可以得心应手。4 a# f7 [# n- U

: W3 a- V, z: V0 ?- I4 v, A, S+ q! E' C4 D/ `! w  E
赞 收藏 评论0 发布时间:2022-1-1 20:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版