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

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

[复制链接]
STMCU小助手 发布时间:2022-1-1 20:00
11.1 初学者重要提示# X5 p8 @) C* d
  MDK本身也是支持硬件异常分析的,就是不够直观
3 v2 v: k" ^4 i3 }, N5 }0 W
8 M$ v! L6 A- A$ W8 ?# a. ~* o5 B  IAR8带的硬件异常分析比较好用,在本章11.6小节有说明。
9 S: K: C6 _! X) ?* G8 y" r' `11.2 移植方法
6 i- J* z+ B0 u) O0 X' G9 \直接移植SEGGER的硬件异常代码会有错误警告,这里针对IAR和MDK版本做了些简单修改,方便大家移植到自己的工程里面。
' D  o$ o4 V% Z% P* R- F) h: `1 i3 x, K
6 z5 J4 W; J' J( S( J4 k: E: Z% Y7 B  MDK版本移植
+ F$ Y0 r; v9 m* J( `源文件位于本章配套例子的\User\segger\HardFaultHandlerMDK文件夹,添加如下两个文件到工程里面即可。( w" S7 G. O% s3 d
( ?! Y$ E: Q1 x" b7 v: h
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

# b! p  D% d0 ]. P+ B! A! X1 q/ B" J
  IAR版本移植
, i& ]& f1 u; A3 T. R- x源文件位于本章配套例子的\User\segger\HardFaultHandlerIAR文件夹,添加如下两个文件到工程里面即可。
0 O4 c, L7 B4 s# ?' v
* N) X" s* C: M+ d: {
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
6 \2 S6 z  W* k" ]
. [" D( P" H5 P; g: r
在文件SEGGER_HardFaultHandler.c里面都添加了串口打印功能,方便不用编译器的调试功能时,通过串口打印提示是否进入硬件异常。' E& Q% k* ?7 U( d9 n, o
1 D: M5 G8 ~2 V' A; v8 @. X& y9 M
  1. #define ERR_INFO "\r\nEnter HardFault_Handler, System Halt.\r\n"5 J- a  b! J: _( }0 L5 K

  2. ! L2 B1 f0 y  ?5 c5 ?% u, s) s
  3. #if 1, M. B5 k, K+ u# w
  4. {
    / \* |; `: A' R& O( N
  5.         const char *pError = ERR_INFO;
    + U+ x$ S! g+ k/ b
  6.         uint8_t i;
    3 e% ]+ J. p8 w% ]8 p8 l4 N

  7. # `- ~+ Z# C) p$ g
  8.         for (i = 0; i < strlen(ERR_INFO); i++)0 ?8 m. F. X5 ?+ i3 E
  9.         {
    / p+ |! O. Y6 i; H) N$ [
  10.                 USART1->TDR = pError<i>;
    + {, G7 I8 x. h; ^; l6 o& L$ _
  11.                 /* 等待发送结束 */' t- A0 m$ r4 }) L( |0 i  a* u
  12.               </i>  while((USART1->ISR & USART_ISR_TC) == 0);
    # X+ O, o- ^/ V7 J& d# |3 l( J
  13.         }        * K( H+ f3 M/ x3 s
  14. }
    6 Y2 P+ h( ?* y, N  t/ _+ p
  15. #endif
复制代码
4 l* @$ R  q; C+ j# C
11.3 MDK锁定硬件异常位置方法5 }2 Z# a7 j2 @; z  l
以本章配套的例子为大家做个说明。. }1 Y& t, b, D6 b4 Z3 _

, Q! o9 B3 y9 k- q# e1 S1、测试方法比较简单,进入调试状态,全速运行,然后按下K1按键,就会进入硬件异常中断,此时停止调试,程序就会自动定位到如下位置:
+ {) t- F8 M. z5 b9 m& x3 W' S; e
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
6 X/ q3 |1 {2 W7 d$ [

; X" j8 R# i3 d" G/ ]: O4 x% J& G2、在Watch1窗口添加变量_Continue( t! o' j" |$ y/ Z# u

* P; f( I# n7 ^* N
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

1 n. L/ a/ f9 S! v
" H* f, U7 A' P9 l3、修改为任何非0数值,就可以继续单步调试。这个代码后面还有一个第1步中的while循环,也可以继续采用第2步的方法修改。退出硬件异常后就是大家进入硬件异常前下一条要执行的指令(可能还是这个函数本身,因为一个函数由多个指令完成)。定位到出问题的位置:" U7 L- T$ h4 d
3 G% r7 \6 h& g6 g
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

7 `9 s- T5 i2 f# t% m6 _0 w9 v4 o, y$ [2 T9 P' A& [+ \: M
11.4 IAR锁定硬件异常位置方法

. x5 p" ~4 v  S, `5 V以本章配套的例子为大家做个说明。2 r0 @1 s+ q$ C5 g$ v, V7 ?' g
$ F: {/ W9 g& ]
1、测试方法比较简单,进入调试状态,全速运行,然后按下K1按键,就会进入硬件异常中断,此时停止调试,程序就会自动定位到如下位置:
' F& w- d) l0 C- {: A8 j, A7 n1 F5 [# b$ T; x
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

& ^) @. ~( }8 ?8 c9 P1 o9 f# B6 K: j/ j, I' G8 |
2、在Watch1窗口添加变量_Continue
/ N3 n! I3 C5 p- a( l. }9 e7 r9 c2 }
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
, z* G3 C- |9 v( x# }& `1 h

+ s7 q2 c! ?5 L3、修改为任何非0数值,就可以继续单步调试。这个代码后面还有一个第1步中的while循环,也可以继续采用第2步的方法修改。退出硬件异常后就是大家进入硬件异常前下一条要执行的指令(可能还是这个函数本身,因为一个函数由多个指令完成)。定位到出问题的位置:: B, |' C5 h" `% O

1 ]9 V& i, x7 @
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png
8 Y# U' f! H, S; q# J$ I+ e" a& U

1 I& y4 k7 K4 T11.5 硬件异常原因分析
; U, q  G8 @- l  d: }% ~SEGGER提供的这个机制查找出问题的位置比较方便,具体原因需要继续在调试界面里面添加HardFaultRegs结构变量,这个结构体变量添加了所有大家想看的东西。下面是MDK调试状态查看部分结构体数值:
2 p. N% @# h3 N  B
. C) W, Z! |: H  _+ t/ c
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

7 Y0 v1 Y% B& F& S6 c0 W7 _6 z5 O- W7 p) T9 B0 O( c
具体上面的变量代表什么含义呢,代码里面有注释,查阅起来没有IAR自带的硬件异常提示方便(注意,下面的代码用到了位域)。
/ O# z) [1 f0 ?+ ]4 p1 E: T
, G% C: `3 O6 S# D/ b4 C
  1. #if DEBUG
    , |( O! i0 Q' o* g3 Y& ?
  2. static volatile unsigned int _Continue;  // Set this variable to 1 to run further9 Z* {' m, J# I0 j: _6 X
  3. # ~4 y# @/ U; Q0 A( o4 S9 I7 z
  4. static struct {) b& V6 |- z" n7 H' |3 @' m+ h
  5.   struct {
    9 Q: M7 x( Z% D' |
  6.     volatile unsigned int r0;            // Register R0  q. x( a: E, W
  7.     volatile unsigned int r1;            // Register R1
    6 P$ a* D" z# ^
  8.     volatile unsigned int r2;            // Register R28 O" z, N. t' d7 o' Y& f) z, A
  9.     volatile unsigned int r3;            // Register R3
    . K2 U6 Q0 f5 P3 q3 C
  10.     volatile unsigned int r12;           // Register R12
    * @$ C! o/ {8 v
  11.     volatile unsigned int lr;            // Link register1 f( ~6 o+ |  z) s2 ]& {
  12.     volatile unsigned int pc;            // Program counter- p6 b, C- I; d# k# j* u0 l
  13.     union {
      \/ m8 K( E! z
  14.       volatile unsigned int byte;
    ; S% `) ^, t! p5 G0 T# D# `
  15.       struct {% j. B6 d) ]- c+ L
  16.         unsigned int IPSR : 8;           // Interrupt Program Status register (IPSR)
    " i0 Q4 C: |5 r' A
  17.         unsigned int EPSR : 19;          // Execution Program Status register (EPSR), L3 j' A& b. f& S, l
  18.         unsigned int APSR : 5;           // Application Program Status register (APSR)$ p* Y8 @4 A  Z! o
  19.       } bits;
    5 C  b' q3 e8 j  L+ h3 K$ ?3 E
  20.     } psr;                               // Program status register.
    ' E& y* x2 |6 B4 ]5 O
  21.   } SavedRegs;# u7 }# ~1 _$ u/ r4 x, n+ E, e- n

  22. , A- F8 w: @: W3 {
  23.   union {
    ! l  T9 o: D: b+ {( n( L
  24.     volatile unsigned int byte;
    ; @% U1 f' i0 K3 ^) I2 ]( B3 n. N" o
  25.     struct {2 T$ V% ?' j0 E4 z2 m. @
  26.       unsigned int MEMFAULTACT    : 1;   // Read as 1 if memory management fault is active* U( l+ A, e, _! A" b* q  z+ C4 ?
  27.       unsigned int BUSFAULTACT    : 1;   // Read as 1 if bus fault exception is active. W$ g6 s/ F# A0 J1 X; ?4 v
  28.       unsigned int UnusedBits1    : 1;
    9 P0 M2 t( r! G4 d! D0 F
  29.       unsigned int USGFAULTACT    : 1;   // Read as 1 if usage fault exception is active
    * W! t/ H/ B4 p! m0 n3 S
  30.       unsigned int UnusedBits2    : 3;. j7 i8 r, F% ]8 b) r) t9 ]
  31.       unsigned int SVCALLACT      : 1;   // Read as 1 if SVC exception is active/ f5 p3 @' D4 e# E9 K4 {
  32.       unsigned int MONITORACT     : 1;   // Read as 1 if debug monitor exception is active
    ; @" K: K% _+ K9 D8 W/ ~
  33.       unsigned int UnusedBits3    : 1;$ T# ?: B0 B( I$ E
  34.       unsigned int PENDSVACT      : 1;   // Read as 1 if PendSV exception is active% {$ `4 O. z3 t8 ^  _+ l
  35.       unsigned int SYSTICKACT     : 1;   // Read as 1 if SYSTICK exception is active
    2 J2 ~2 [. P$ ]2 u
  36.       unsigned int USGFAULTPENDED : 1;   // Usage fault pended; usage fault started but was replaced by a( S" B8 b4 B! v" C% Y
  37. higher-priority exception& l' @+ I1 Z5 D1 W3 ]( S
  38.       unsigned int MEMFAULTPENDED : 1;   //  Memory management fault pended; memory management fault started
    0 z" _9 @  B' z2 p+ _
  39. but was replaced by a higher-priority exception# _# o9 O8 G; [- A' i* `2 X6 S; _% O
  40.       unsigned int BUSFAULTPENDED : 1;   // Bus fault pended; bus fault handler was started but was replaced. `% U; V2 R* u; N+ j: g
  41. by a higher-priority exception. C8 t! U, s( {+ I# P/ ]
  42.       unsigned int SVCALLPENDED   : 1;   // SVC pended; SVC was started but was replaced by a higher-priority( R. p- m8 ~4 j5 Z& l% D
  43. exception
    ! ]+ V) y* u9 i  _! @& v8 I4 U! z6 i
  44.       unsigned int MEMFAULTENA    : 1;   // Memory management fault handler enable  o+ A0 q! P  t( G
  45.       unsigned int BUSFAULTENA    : 1;   // Bus fault handler enable
    / i. q7 n/ V+ D4 }
  46.       unsigned int USGFAULTENA    : 1;   // Usage fault handler enable
    8 e5 q3 I, J( b9 k0 X2 ^  J( p
  47.     } bits;: I1 O2 w3 j' B
  48.   } syshndctrl;                          // System Handler Control and State Register (0xE000ED24)
      A6 O2 [3 v# V
  49. * l/ g$ Y4 r! L! c1 e
  50.   /* 省略未写 */+ H4 N% Z1 t7 v5 g: ~3 y
  51. 9 x3 f$ u3 U2 [
  52.   volatile unsigned int afsr;            // Auxiliary Fault Status Register (0xE000ED3C), Vendor controlled (optional): y6 h$ [( b+ M7 J+ q9 l$ L* Z: F
  53. } HardFaultRegs;- e* n' z# O4 x
  54. #endif
复制代码
! I. B) \5 l. [6 Q
11.6 IAR自带的硬件异常分析
# H! V* B7 l: \5 T0 |- A# i9 y* b还以本章配套的例子为例,进入调试状态,全速运行,然后按下K1按键,就会进入硬件异常中断,此时停止调试,IAR还会弹出一个硬件异常错误分析,刚进来的时候也许是个空白: a5 A" z( ~  S. J1 @6 {. y0 Y

5 @! Y+ @$ o% P3 m# W% h
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

8 u: B( ]8 O# m- z6 A. l: Z3 w# I$ Y6 [
单步调试刷新下就出来了:- m3 O$ V. k# B2 W

# k# S4 C( ^1 @8 G
aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTM3OTEwNy8yMDE5MDQvMTM3OTEwNy0yMDE5.png

5 L) i+ A& F. s* T( Z- S# L2 M  a6 K7 q" I5 @3 S0 Y
指出了问题的原因是操作的数据地址有问题。
. C5 T  X# H( x
, P; U+ F, A& i- @) F11.7 实验例程  h4 p6 Z: _9 z+ {: Q' \0 H# m7 j
专门为本章节配套了一个例子:V7-009_移植SEGGER的硬件异常分析机制。大家可以按照本章教程提供的方法进行测试。. K# o# P' N# G6 _

2 ^: z6 y8 m  h4 q+ m11.8 总结$ A: P  p; U9 e! R& @7 C
除了SEGGER的硬件异常分析方案,建议也测试下MDK和IAR的,以后遇到硬件异常问题,解决起来可以得心应手。
2 a/ b0 L- j$ q
+ E4 ^5 ^0 F; l& v7 E$ O) {* J5 ^1 e' E/ j
收藏 评论0 发布时间:2022-1-1 20:00

举报

0个回答

所属标签

相似分享

官网相关资源

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