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

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

[复制链接]
STMCU小助手 发布时间:2022-1-1 20:00
11.1 初学者重要提示% y3 }, j6 {3 ]  `6 ~6 x- S; F
  MDK本身也是支持硬件异常分析的,就是不够直观
) `3 z  L1 P( L  J3 d* u5 i0 o' ^$ E5 ?, I
  IAR8带的硬件异常分析比较好用,在本章11.6小节有说明。
3 ^+ N% k: }* w' Z7 {9 e' l11.2 移植方法2 d8 f/ T, |& F2 ^7 t4 o
直接移植SEGGER的硬件异常代码会有错误警告,这里针对IAR和MDK版本做了些简单修改,方便大家移植到自己的工程里面。
3 Y) J8 o" \$ P' z  B( N- i! T/ K- C* b, Y. E' u/ M0 K( N2 ?
  MDK版本移植5 [; @; X* z, Y' T% s- u( r! j
源文件位于本章配套例子的\User\segger\HardFaultHandlerMDK文件夹,添加如下两个文件到工程里面即可。9 U2 K% ~- t! w8 `+ f7 V' Y& m4 Y

& }* W* D9 b6 C3 h* m5 O0 s. N
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

- p& B4 z* y% ?8 c) N
1 t4 e1 @- ]$ f6 U; `) I# s3 v  IAR版本移植0 B# ]) X4 l$ L
源文件位于本章配套例子的\User\segger\HardFaultHandlerIAR文件夹,添加如下两个文件到工程里面即可。  p. m% y7 t4 B9 i

! z- H/ B& M7 f* d2 F: v6 L
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
0 P6 G; {7 B, x$ ?1 C3 E

9 b. o+ b. T. a在文件SEGGER_HardFaultHandler.c里面都添加了串口打印功能,方便不用编译器的调试功能时,通过串口打印提示是否进入硬件异常。9 w1 L1 w0 y) O6 s3 U" \
6 y' y) b8 k. e' ^. C
  1. #define ERR_INFO "\r\nEnter HardFault_Handler, System Halt.\r\n". G, @- P( r$ J& Y' E) F" X2 M

  2. $ J4 n, X. `! j) i' T+ }
  3. #if 11 n: `" W4 ]0 I( ~1 @% Q; _
  4. {
    / l. P& o/ b7 @5 Z5 h9 ?5 l& A
  5.         const char *pError = ERR_INFO;5 g, E7 u: r5 }- ?5 j
  6.         uint8_t i;
    & K2 r9 u5 k1 t% f8 Y& V
  7. 8 s$ y5 E, G" \: q
  8.         for (i = 0; i < strlen(ERR_INFO); i++)
    8 N4 d; d8 z+ S9 a3 X! e
  9.         {7 Y' P7 O/ B, p+ Y# b
  10.                 USART1->TDR = pError<i>;
    - h1 ^8 c0 q; l* E% B2 r& [
  11.                 /* 等待发送结束 */
    - `. f; a4 _; |, g* g& m
  12.               </i>  while((USART1->ISR & USART_ISR_TC) == 0);" X; w( Z; r, T
  13.         }        
    * |3 _% N/ r6 V9 b4 s% W
  14. }
    ( m  V  c* b" H* D: i( L
  15. #endif
复制代码

  [  l  a6 v# I0 h0 ]11.3 MDK锁定硬件异常位置方法! Q! O4 J7 u1 j6 v! P
以本章配套的例子为大家做个说明。
5 U3 e2 @6 g% s: {8 G. Q) ^. b
- ^" |9 L' {+ [4 E5 I/ c7 v* s1、测试方法比较简单,进入调试状态,全速运行,然后按下K1按键,就会进入硬件异常中断,此时停止调试,程序就会自动定位到如下位置:5 T" ^: m) J3 @3 d' g) u  }+ K
. z+ d. B7 A7 n
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

0 X+ `4 X2 N6 W5 S" z- L+ s. B- c7 i9 F% E
2、在Watch1窗口添加变量_Continue2 u2 g3 a- V9 Y5 G+ |  K: Z! B% I
3 {7 b6 V4 {: w; O+ t( Z$ X, P- F
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
3 _% B- I. ]6 ?* }" V3 d$ ~

& e4 v3 K3 e/ K: n0 o3、修改为任何非0数值,就可以继续单步调试。这个代码后面还有一个第1步中的while循环,也可以继续采用第2步的方法修改。退出硬件异常后就是大家进入硬件异常前下一条要执行的指令(可能还是这个函数本身,因为一个函数由多个指令完成)。定位到出问题的位置:& O0 X( @  U6 H! o0 K$ s: i7 ^4 C

3 h8 b9 _8 Z6 L( ~3 J* E5 C
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
0 n% }' N/ @  V& G$ @; [
" O; ~" [' F2 U) R( ?
11.4 IAR锁定硬件异常位置方法

, p% J2 F/ L2 h4 [; S$ c$ X: ]以本章配套的例子为大家做个说明。
( v- X5 c4 P; }. T6 I$ b: K; W2 Q9 ]( \- ^3 z! _: s
1、测试方法比较简单,进入调试状态,全速运行,然后按下K1按键,就会进入硬件异常中断,此时停止调试,程序就会自动定位到如下位置:: m9 i* [, |+ [
$ g. p& b! x2 y% G. `6 g
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
% I+ j* A& i" y8 v* ~

2 x0 K* `3 G; d- \+ o2、在Watch1窗口添加变量_Continue
; h- R' v$ m; I% j0 Z. W
3 o% u: N, w$ C, G& ]
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
; ?+ L5 R% R( L9 X# N

! w1 R. N" ~) C( [8 n" v4 ~6 D3、修改为任何非0数值,就可以继续单步调试。这个代码后面还有一个第1步中的while循环,也可以继续采用第2步的方法修改。退出硬件异常后就是大家进入硬件异常前下一条要执行的指令(可能还是这个函数本身,因为一个函数由多个指令完成)。定位到出问题的位置:
' d: u1 w7 e! [7 U; F% i; L" k
9 z1 q/ S% o9 w* o1 T
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

" C8 b. Q4 G3 m( ~9 U# I/ P
7 F7 _- r0 g! W  z- _11.5 硬件异常原因分析
3 P- ?: ^8 F6 I, C7 V; l% s# PSEGGER提供的这个机制查找出问题的位置比较方便,具体原因需要继续在调试界面里面添加HardFaultRegs结构变量,这个结构体变量添加了所有大家想看的东西。下面是MDK调试状态查看部分结构体数值:
5 |  W$ e, e$ C2 ?) d6 X
) e& `" W* Q8 ^! y# F  D
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

+ ?6 b  {3 H0 `- Q4 q" T9 R$ ]4 \- r; {7 T0 L( @0 F# o% X$ ~
具体上面的变量代表什么含义呢,代码里面有注释,查阅起来没有IAR自带的硬件异常提示方便(注意,下面的代码用到了位域)。& U& Y1 O7 R3 B6 N: w
5 c: {- K2 _$ C% ^7 q
  1. #if DEBUG! o* b* D" j/ U6 k  B. t
  2. static volatile unsigned int _Continue;  // Set this variable to 1 to run further
    ! a& Y$ q3 ]2 _: M$ M; u2 L

  3. 3 ]! I. ?+ f5 g8 K& Z
  4. static struct {- E9 _3 W$ C1 u
  5.   struct {
    3 [7 ^) N/ k3 Y+ S6 d
  6.     volatile unsigned int r0;            // Register R0* \& v9 h& ?$ o: Y' |/ K" p: X
  7.     volatile unsigned int r1;            // Register R19 [; F1 ?. p0 \, d! Q5 @
  8.     volatile unsigned int r2;            // Register R2" R4 D  q  A1 g
  9.     volatile unsigned int r3;            // Register R3) R& _- E7 O+ p7 W  g9 n& K' x& Q
  10.     volatile unsigned int r12;           // Register R12. Q/ ~, o1 R3 F) L% U3 c
  11.     volatile unsigned int lr;            // Link register
    ; h" k6 `* k6 x/ V/ q  o
  12.     volatile unsigned int pc;            // Program counter6 Z3 E4 s+ [, _2 b$ ~3 w
  13.     union {9 @7 e$ Q7 e0 _: _$ G& X8 R
  14.       volatile unsigned int byte;4 |( q( U$ w4 K1 i" k9 j
  15.       struct {# Y8 t. O. @0 `* u) j7 }: A+ C9 t
  16.         unsigned int IPSR : 8;           // Interrupt Program Status register (IPSR). k$ O3 @/ j7 I* v" t5 i
  17.         unsigned int EPSR : 19;          // Execution Program Status register (EPSR)" c2 U6 L' x0 l
  18.         unsigned int APSR : 5;           // Application Program Status register (APSR)
    7 M$ g& R& |1 Y$ w$ M& N$ [& @+ ^
  19.       } bits;
    ) d* ~) o* m8 K* M4 \
  20.     } psr;                               // Program status register.; S% a" [# G( P1 Z7 n; j5 r% }
  21.   } SavedRegs;: ^! s( v9 A( t

  22. ) \0 a4 b( T1 H
  23.   union {' O" `4 X) a  X; j
  24.     volatile unsigned int byte;
    ; z0 d7 Z0 X* g$ V. u6 T
  25.     struct {  |4 x$ l" h+ _: J& C7 \: p) F
  26.       unsigned int MEMFAULTACT    : 1;   // Read as 1 if memory management fault is active  D" p: U  H0 Y
  27.       unsigned int BUSFAULTACT    : 1;   // Read as 1 if bus fault exception is active
    + Z  d& L' ]; P; Y
  28.       unsigned int UnusedBits1    : 1;
    # \* T" b% Q1 B  x
  29.       unsigned int USGFAULTACT    : 1;   // Read as 1 if usage fault exception is active- P$ m! \  m3 x0 ?- z
  30.       unsigned int UnusedBits2    : 3;
    # F2 G  L2 u( q: ^" v# v0 D0 n0 F3 e
  31.       unsigned int SVCALLACT      : 1;   // Read as 1 if SVC exception is active
    ! p( Z8 n* h; u0 k
  32.       unsigned int MONITORACT     : 1;   // Read as 1 if debug monitor exception is active
    2 [' x' `, S$ H2 P% G1 Q
  33.       unsigned int UnusedBits3    : 1;! ?' F3 x; Z+ n" O/ T
  34.       unsigned int PENDSVACT      : 1;   // Read as 1 if PendSV exception is active
    7 z' e$ D2 [. \! f' w4 }: L
  35.       unsigned int SYSTICKACT     : 1;   // Read as 1 if SYSTICK exception is active5 p* f. C1 L( ]1 w0 P3 H2 t
  36.       unsigned int USGFAULTPENDED : 1;   // Usage fault pended; usage fault started but was replaced by a
    + T+ t# F* g# A; {+ @, y9 B* c/ q+ Z2 y  X
  37. higher-priority exception- R- U4 b  j6 _; e
  38.       unsigned int MEMFAULTPENDED : 1;   //  Memory management fault pended; memory management fault started
    6 P7 R/ l, k: d6 F
  39. but was replaced by a higher-priority exception
    * F+ V; o; @$ R3 J3 e: U
  40.       unsigned int BUSFAULTPENDED : 1;   // Bus fault pended; bus fault handler was started but was replaced
    2 ?  ?( X2 A- C. \7 y6 j9 h# ]& O% Y
  41. by a higher-priority exception6 o5 a: s- o0 w5 z
  42.       unsigned int SVCALLPENDED   : 1;   // SVC pended; SVC was started but was replaced by a higher-priority4 k: y: _" \; @: q# w$ Q" L
  43. exception
    ( ^: e9 Q3 d7 E( a( s6 {% d
  44.       unsigned int MEMFAULTENA    : 1;   // Memory management fault handler enable
    ) d6 h2 Q. t8 j" y! K: \7 e
  45.       unsigned int BUSFAULTENA    : 1;   // Bus fault handler enable
    6 U7 D2 i3 @  r3 K
  46.       unsigned int USGFAULTENA    : 1;   // Usage fault handler enable1 b/ ^6 F8 z  {9 Z7 k/ q' G
  47.     } bits;
    : k) _4 U% T# k  w# x
  48.   } syshndctrl;                          // System Handler Control and State Register (0xE000ED24)
    . s2 K8 A5 t; h7 V6 Q

  49. 8 \4 P  r! @" t- M* J8 e  x
  50.   /* 省略未写 */
    2 W: t2 r0 ?% M6 ~) {
  51. " {) h! E1 J- S! M  f7 c& x0 u; }
  52.   volatile unsigned int afsr;            // Auxiliary Fault Status Register (0xE000ED3C), Vendor controlled (optional)
    1 E$ W9 _, ^4 P1 g
  53. } HardFaultRegs;) N; s% e/ Z) |5 O+ a
  54. #endif
复制代码
9 h, W" L9 d5 Y- ]& Y& J; m
11.6 IAR自带的硬件异常分析
0 j% p! {  w9 Y/ J9 _# X还以本章配套的例子为例,进入调试状态,全速运行,然后按下K1按键,就会进入硬件异常中断,此时停止调试,IAR还会弹出一个硬件异常错误分析,刚进来的时候也许是个空白
6 k' J% H- W$ g& t8 S- r% I0 `3 k2 m- G. f* w1 q7 K! `
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
; c* f2 K1 [: B- ?; u; d3 P$ C6 Q- l6 m
6 P0 m/ p1 d: m% b3 o! s
单步调试刷新下就出来了:- ~$ r# N) J! p+ _* `8 y, p+ D" @
  d5 U) W; ?0 i7 H- C$ J3 y
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

" U' _' `: @' w+ |: X! f9 W# m/ Q8 e3 Q% t4 j9 t
指出了问题的原因是操作的数据地址有问题。
. S4 M+ R7 O& O, x2 \
% D8 n* R% B) g' B/ _# s- s11.7 实验例程+ W8 _( ?- u( T$ p3 f
专门为本章节配套了一个例子:V7-009_移植SEGGER的硬件异常分析机制。大家可以按照本章教程提供的方法进行测试。
* g5 [# t. {" p! A0 A; o& `' w+ l+ ~' C4 T; L. `
11.8 总结1 ~% k. k9 g  d  d
除了SEGGER的硬件异常分析方案,建议也测试下MDK和IAR的,以后遇到硬件异常问题,解决起来可以得心应手。- `# L2 p" O- }" T/ J

4 S& m6 C) l2 Y5 A+ e% v
* ?+ L* U' E9 C4 i9 K
收藏 评论0 发布时间:2022-1-1 20:00

举报

0个回答

所属标签

相似分享

官网相关资源

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