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

J-Link cmd的使用

[复制链接]
STMCU小助手 发布时间:2021-8-6 11:01
01 WHY
- c- ^0 E. a1 }; L( {
) Y6 l! u' i/ M% P% c
# B' Z) g! n' o- h# E+ V/ a
为什么要使用到J-LinkCommander呢???大部分情况下,我们使用J-link都是在IDE中debug使用的,出现问题,直接debug复现然后解决。这是最常见的开发方式。
: n" d' A. o+ G/ f7 A/ }1 {5 i& C. F6 D" Z- i3 j. n
5 w1 e6 m' N, \
但是有些情况我们不能使用IDE直接debug,比如发布版本(JTAG或SWD接口可以正常使用),大批量生产时发现几片异常的板子,重新debug问题就消失了。- n, r+ z7 \2 i* m2 M1 f

8 O) W" u. v! p7 b' V
/ Y. f% c9 p% h# h+ ?
这个时候使用IDE直接debug已经不能解决问题,我们需要使用J-LinkCommander读取关键寄存器的值来协助我们定位排查问题。
% c  v# s. c! ~1 r0 ?: O
$ c6 _: }  Q( {- O
) T8 X# s0 l, v# Y0 Y5 {$ @; H: l) N
02 Jlinkcmd使用- d9 ?0 T0 l5 Y: l$ t

9 w1 B+ r! p0 ^; J' `4 _- L' M
8 b3 P3 B+ Z6 ?* I. m
Jlinkcmd它可以方便用户在非仿真的情况下,hold内核、单步、全速、设置断点、查看内核和外设寄存器、读取flash代码等等,方便大家拥有最高的权限查看在运行中的MCU情况,查找非IDE仿真情况下,MCU运行异常的原因。! P0 w/ `# I4 O! s1 {3 W

$ y5 z3 t! T2 l" g1 d

" a$ N" V' u, m打开Jlinkcmd,如果单独安装了jlink驱动,我们可以在开始菜单找到Jlinkcmd。0 g8 C( r2 }2 J9 j) `
1.png 3 G% a  \7 M! e: ~) S! Y6 g
( R% M" }; Z9 ]+ ?3 X

9 X9 h) L  \6 M6 g8 q6 h- D" e2 u3 ~或者在安装目录中找到它4 `2 X6 J& u$ c8 U+ f
2.png
+ V5 ?+ _. L( ]% O3 `: p/ k/ Y$ S! N! e( ?
5 O( U- |- X  A& G7 L) \- a4 Q+ }0 V
如果你们有独立安装Jlink驱动,同样也可以在Keil的安装目录中找到它4 d: [( Z1 a- i4 ?
3.png
8 d% C' L% p3 {' v  l. K9 @
; F3 Y8 ~8 T; O  ?1 [  h4 f0 B& t- U4 A

4 d8 e; O$ w& w' D. M; Q首先使用Jlink连接好MCU,打开软件“Jlink.exe% q7 ]3 ]- W3 M: x6 _; V: U5 l. ]
4.png
6 f% j: y$ R' Z' t4 L
2 c+ z$ z* k% q9 l! g

2 l$ D" `6 u9 \5 V% f按照提示输入相应信息connect->?->s->回车(旧版只需要输入usb即可连接目标芯片)# N- u' V+ H/ N3 o5 |, @( q( R
5.png ! }: E+ v% J# Y/ b- o( Y
% `4 I% k' A) a
. H/ [0 i3 x% p1 T  g/ S+ J9 Y7 h8 O
正确的链接目标芯片后:& M3 c) M8 e8 `, S) ~. c" Y
6.png
0 K: t* Y2 j! O1 Q# U. H: A1 N  d$ P4 D  b; s
# f* h8 O9 n' z
如上图所示,选项字节里为"5AA5"即为无保护状态。) A2 T- a& l- n/ g* M

5 R5 Y- E0 }# I" Z; \- c

' B9 n! y( g0 I  d8 yJlinkcommand常用命令简介:5 Z6 L8 H1 L9 I5 D! J/ V
  1. <font face="微软雅黑" size="3">mem 读内存
    3 C3 _0 h* B/ l) p' _& z4 B
  2. 2 H* _) @& o* N0 }( @) B
  3. mem8 读8字节内存
    ' z5 X% g) i1 T& h) c
  4. & q+ y  j$ t, N# h6 ?" O8 F
  5. mem16 读16字节内存8 x% ~- ~4 W  D, H

  6. % t: \  s' }1 G
  7. mem32 读32字节内存; _1 n2 S- I( _3 E  u

  8. + s, M  m! V# K% @
  9. w1 写8字节内存4 o3 m1 K" W$ [! ]

  10. 7 u* t  x) K( K' S; Y
  11. w2 写16字节内存5 z! s: |$ ?4 [" Y0 ~5 |  I$ `+ b
  12. 7 ?4 S; s0 S1 e; y
  13. w4 写32字节内存$ _' m% Q- }4 S* w* K9 R4 F9 }/ [

  14. + s  l( E4 A9 B5 d0 k6 H& W
  15. h 停止cpu运行的程序: b( G9 H5 D6 E2 `3 c$ N% G

  16. 3 j( T' J" L& a) v
  17. setbp 设置断点
    7 @6 y, c9 w1 x4 z

  18. " d# w. K  T1 G$ f9 d
  19. g 跳到代码段地址执行
    $ b, z: m- s0 ^5 \  w$ O( v
  20. 2 C) {4 x5 C4 A
  21. s 单步执行(调试用)
    ( ]2 ]( s! }8 V0 b: s, D
  22. : S8 q0 ]/ H, P! C& a/ G
  23. r 复位</font>
复制代码

8 z' l3 x7 f8 ^. ~! p

) L# _/ C4 u% J  @  G03 实测
. N$ V$ k4 K( |6 H- V% |; _' _! o( Y" k
' O! i8 Y, T- L0 j# [7 a
接下来就是实测环节,我们通过一个真实的例子演示一下Jlinkcmd的使用。在之前文章《STM32延时函数的四种方法》中有以下代码" C2 J7 ?% m, T" Q5 Y) u
  1. <font face="微软雅黑" size="3">. t! X# P- s; M4 @: b$ ?
  2. void delay_ms(uint16_t nms)$ E3 \8 |3 o! v
  3. {. l. _  ]- W  N/ I# |# i4 ^
  4.   uint32_t temp;
    ( ?6 R4 c  }+ S
  5.   SysTick->LOAD = RCC_Clocks.HCLK_Frequency/1000/8*nms;
    ' j/ S1 ]5 e! I: W- y
  6.   SysTick->VAL=0X00;//清空计数器) F2 L8 F& f/ Y( |$ W, I  Y
  7.   SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源
    ; |7 o" Y) c% h: A5 o
  8.   do5 S. A8 a% Z$ x# C% _5 ~5 E
  9.   {# M  K( P9 E/ Q: Z7 U3 ~
  10.     temp=SysTick->CTRL;//读取当前倒计数值
    2 W- e, P  N: l8 K
  11.   }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达
    " E% p+ M6 _5 @3 z0 r' ?6 `- u% `
  12.   SysTick->CTRL=0x00; //关闭计数器
    + U" t% d; m% k" ~* G$ B3 S% p
  13.   SysTick->VAL =0X00; //清空计数器
    ( ~' C- _% a2 i* T, i
  14. }</font>
复制代码
调用示例: K: L- F7 \/ M  ]4 u& m  s
  1. <font face="微软雅黑" size="3">  while (1)
    % D1 v% v- x* j! V$ X8 C8 F" q
  2.   {
    - I; K) _/ R7 E) a" T
  3.     GPIO_SetBits(GPIOE,GPIO_Pin_4);  //熄灭LED灯                     
    ! r- ^+ ?0 o5 S& p
  4.     delay_ms(500);//延时500ms* S4 [' l" y3 r. h( h8 C  h$ U
  5.     GPIO_ResetBits(GPIOE,GPIO_Pin_4);//点亮LED灯                     
    $ A) |7 z- d0 U) O+ I; T! a
  6.     delay_ms(500);//延时500ms3 i1 m' V1 Q/ S) b" f4 O; V% P
  7.   }</font>
复制代码
我们就用来验证SysTick->LOAD寄存器的值。对于上述代码SysTick->LOAD的寄存器地址,我们可以按照芯片用户手册直接推算地址。或者如下面这样,写段测试代码。: t: D+ K$ v* f* W4 E3 L
7.png 1 [* u' q9 \2 l0 O) G
从上图得知,SysTick->LOAD寄存器的地址是0XE000E014,写入寄存器的值是0X007270E0。6 R5 U# E8 m6 s

+ N' p# K) `0 T

2 N0 {. S+ P: {4 Q按照上述方案读取寄存器的值,步骤如下:
. X+ P* B3 z2 r) P1 `6 _6 F 8.png ; T3 V% ]& m2 z" h% W& A
- r8 S7 D* S) [: h) t: ], r3 E

. s5 ]; Q1 Q, j* F2 O# a; Z可以看到地址0XE000E014的SysTick->LOAD寄存器的值为0X7270E0。
* ?3 A5 ?% V: W: s; B: g8 J9 l
1 n+ B5 ^. N5 J( l8 V. S. I

9 L+ c1 u0 ~) f; s! w0 M8 e1 {- \& Y: {6 J" U) r- t

( v( |5 W6 k) a6 ?$ Z2 h04 后记3 K( F# C( Q2 F" k
6 i  q6 d) h0 m
& ^& Z+ e8 y4 e: b
这里只是提供了一个简单的演示,可以非IDE仿真情况下,读取寄存器,协助排查MCU运行异常的原因,毕竟如果直接debug就能查到问题,熟悉32系列单片机的毕业生都可以做到。, I6 Z: W! f) ~; _( x7 j
, b; O! b+ @) L! X* K5 }

  v0 t! H" M8 t" j我们需要在工作中积累这样类似的经验,巧妙使用工具处理一些“诡异”的问题,积累开发经验。- N; P6 o2 u: k: {, L
8 m# t5 m5 X! i6 o6 f
0 Z- j5 U& x+ D# y( u( R. \
毕竟,填坑力就是核心竞争力。: m  z$ d+ U' y. h

' x3 p% N' Q' y8 x, f: v6 s
赞 收藏 评论0 发布时间:2021-8-6 11:01

举报

0个回答

所属标签

相似技术帖

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