OpenOCD
JTAG SWD 是什么?
是一种协议,用来调试、烧录 CPU
JTAG 线多
SWD 线少
JLink = USB 转 JTAG
流程 - 103C8-jlink_swd
安装 openocd
编写脚本
liyongjun@liyongjun-desktop:~/project/c/openocd-code/tcl$ cat board/my103.cfg
#
# This is an STM32F429 discovery board with a single STM32F429ZI chip.
# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/PF259090
#
source [find interface/jlink.cfg] # jlink
transport select swd # swd
# increase working area to 128KB
set WORKAREASIZE 0x20000
source [find target/stm32f1x.cfg]
reset_config srst_only
运行 openocd
liyongjun@liyongjun-desktop:~/project/c/openocd-code/tcl$ sudo ../src/openocd -f board/my103.cfg
[sudo] password for liyongjun:
Open On-Chip Debugger 0.11.0+dev-00590-g2586fec-dirty (2022-03-12-02:34)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : DEPRECATED target event trace-config; use TPIU events {pre,post}-{enable,disable}
srst_only separate srst_nogate srst_open_drain connect_deassert_srst
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : J-Link ARM-OB STM32 compiled Aug 22 2012 19:52:04
Info : Hardware version: 7.00
Info : VTarget = 3.300 V
Info : clock speed 1000 kHz
Info : SWD DPIDR 0x1ba01477
Info : stm32f1x.cpu: Cortex-M3 r1p1 processor detected
Info : stm32f1x.cpu: target has 6 breakpoints, 4 watchpoints
Info : stm32f1x.cpu: external reset detected
Info : starting gdb server for stm32f1x.cpu on 3333
Info : Listening on port 3333 for gdb connections
telnet 方式连接
liyongjun@liyongjun-desktop:~$ telnet 127.0.0.1 4444
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Open On-Chip Debugger
> halt // 停止运行
target halted due to debug-request, current mode: Thread
xPSR: 0x81000000 pc: 0x08000200 msp: 0x20000430
> resume // 继续运行
> mdw 0x08000000 // 读取 0x08000000 内存地址处数据,由 STM32f103C8 数据手册可知,0x08000000 为 flash 空间起始地址(外设、内存、flash 统一编址。0x20000000 为 SRAM 起始地址)。
0x08000000: 20000450 // 此处的数据为 0x20000450,与 test.axf 的程序数据内容一致,见下图
> mdw 0x20000444 // 读取内存地址为 0x20000444 的数据,和下图打印的 a = 100 一致
0x20000444: 00000064
> mdw 0x20000440 // 读取内存地址为 0x20000440 的数据,和下图打印的 b = 200 一致
0x20000440: 000000c8
>
gdb 方式连接
liyongjun@liyongjun-desktop:~/project/c/openocd-code$ arm-none-eabi-gdb my/test.axf // 这里要用 arm-none-eabi-gdb,是为了【反汇编】、【打断点】使用。test.axf 是使用 Keil5 编译产生的程序文件
GNU gdb (7.6.50.20131218-0ubuntu1+1) 7.6.50.20131218-cvs
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-linux-gnu --target=arm-none-eabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from my/test.axf...
warning: Loadable section "RW_IRAM1" outside of ELF segments
done.
(gdb) target remote 127.0.0.1:3333 // 连接 OpenOCD
Remote debugging using 127.0.0.1:3333
warning: Loadable section "RW_IRAM1" outside of ELF segments
HAL_Delay (Delay=1000)
at ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c:328
328 ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c: 没有那个文件或目录.
(gdb) monitor reset // monitor 意为向连接的外部软件发送指令,此处即向 OpenOCD 发送指令。因为 reset、halt 不是 gdb 的内部指令,而是 OpenOCD 的指令。reset:复位目标板
(gdb) monitor halt // 中断目标板的运行
target halted due to debug-request, current mode: Thread
xPSR: 0x81000000 pc: 0x08000540 msp: 0x20000430
(gdb) disassemble main // 反汇编 main 函数
Dump of assembler code for function main:
0x08001cf8 <+0>: push {r2, r3, r4, lr}
0x08001cfa <+2>: bl 0x800055c <HAL_Init>
0x08001cfe <+6>: bl 0x8001640 <SystemClock_Config>
0x08001d02 <+10>: bl 0x8001534 <MX_GPIO_Init>
0x08001d06 <+14>: bl 0x80015b8 <MX_USART1_UART_Init>
0x08001d0a <+18>: movs r0, #100 ; 0x64
0x08001d0c <+20>: str r0, [sp, #4]
0x08001d0e <+22>: movs r0, #200 ; 0xc8
0x08001d10 <+24>: str r0, [sp, #0]
0x08001d12 <+26>: ldrd r1, r0, [sp]
0x08001d16 <+30>: bl 0x8001d8c <sum>
0x08001d1a <+34>: b.n 0x8001d54 <main+92>
0x08001d1c <+36>: mov.w r1, #8192 ; 0x2000
0x08001d20 <+40>: ldr r0, [pc, #52] ; (0x8001d58)
0x08001d22 <+42>: bl 0x800052c <HAL_GPIO_TogglePin>
0x08001d26 <+46>: add r0, pc, #52 ; (adr r0, 0x8001d5c)
0x08001d28 <+48>: bl 0x80019d4 <__2printf>
0x08001d2c <+52>: add r1, sp, #4
0x08001d2e <+54>: add r0, pc, #52 ; (adr r0, 0x8001d64)
0x08001d30 <+56>: bl 0x80019d4 <__2printf>
0x08001d34 <+60>: add r0, pc, #56 ; (adr r0, 0x8001d70)
0x08001d36 <+62>: ldr r1, [sp, #4]
0x08001d38 <+64>: bl 0x80019d4 <__2printf>
0x08001d3c <+68>: mov r1, sp
0x08001d3e <+70>: add r0, pc, #56 ; (adr r0, 0x8001d78)
0x08001d40 <+72>: bl 0x80019d4 <__2printf>
0x08001d44 <+76>: add r0, pc, #60 ; (adr r0, 0x8001d84)
0x08001d46 <+78>: ldr r1, [sp, #0]
0x08001d48 <+80>: bl 0x80019d4 <__2printf>
0x08001d4c <+84>: mov.w r0, #1000 ; 0x3e8
0x08001d50 <+88>: bl 0x80001f4 <HAL_Delay>
0x08001d54 <+92>: b.n 0x8001d1c <main+36>
End of assembler dump.
(gdb) continue
Continuing.
^C
Program received signal SIGINT, Interrupt.
0x08000204 in HAL_Delay (Delay=1000)
at ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c:328
328 in ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c
(gdb) monitor reset
(gdb) ^CQuit
(gdb) monitor halt
target halted due to debug-request, current mode: Thread
xPSR: 0x81000000 pc: 0x08000200 msp: 0x20000430
(gdb) continue
Continuing.
^C
Program received signal SIGINT, Interrupt.
0x08000204 in HAL_Delay (Delay=1000)
at ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c:328
328 in ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c
(gdb) b *0x08001d50 // 将断点打在 0x08001d50(HAL_Delay) 之前
Breakpoint 1 at 0x8001d50: file ../Src/main.c, line 110.
(gdb) c // 继续运行
Continuing.
Note: automatically using hardware breakpoints for read-only addresses.
Breakpoint 1, 0x08001d50 in main () at ../Src/main.c:110
110 ../Src/main.c: 没有那个文件或目录.
(gdb) c
Continuing.
Breakpoint 1, 0x08001d50 in main () at ../Src/main.c:110
110 in ../Src/main.c
(gdb) monitor mdw 0x08000000
0x08000000: 20000450
(gdb) monitor mdw 0x20000444
0x20000444: 00000064
(gdb) monitor mdw 0x20000440
0x20000440: 000000c8
注:
berak、continue、Ctrl + C 这是 gdb 的内部命令
reset、halt、resume 这是 OpenOCD 的命令
实测:使用 resume 恢复目标板运行,无视断点;使用 continue 继续执行程序,遇到断点会停止。
小结:
monitor xxx 其实就是调用 OpenOCD 本身的 xxx 命令,也就相当于 telnet 连接 OpenOCD 后执行的原生命令。
流程 - 107VC-jlink_jtag
编写脚本
liyongjun@liyongjun-desktop:~/project/c/openocd-code/tcl$ cat board/my107.cfg
#
# This is an STM32F429 discovery board with a single STM32F429ZI chip.
# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/PF259090
#
source [find interface/jlink.cfg] # jlink
transport select jtag # jtag
# increase working area to 128KB
set WORKAREASIZE 0x20000
source [find target/stm32f4x.cfg]
reset_config srst_only
gdb 方式连接
报错
(gdb) target remote 127.0.0.1:3333
Remote debugging using 127.0.0.1:3333
Remote connection closed
OpenOCD 报错
Warn : Cannot identify target as a STM32 family.
Error: auto_probe failed
Error: Connect failed. Consider setting up a gdb-attach event for the target to prepare target for GDB connect, or use 'gdb_memory_map disable'.
Error: attempted 'gdb' connection rejected
目前结论:stm32 不支持使用 jtag 方式调试?
telnet 方式连接
liyongjun@liyongjun-desktop:~/project/c/openocd-code/my$ telnet 127.0.0.1 4444
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Open On-Chip Debugger
> resume
> halt
target halted due to debug-request, current mode: Thread
xPSR: 0x21000000 pc: 0x080001f6 msp: 0x20000680
> resume
流程 - mini2440-jlink_jtag
运行 openocd
注释掉 mini2440.cfg 第 124 行: jtag interface
liyongjun@liyongjun-desktop:~/project/c/openocd-code/tcl$ sudo ../src/openocd -f interface/jlink.cfg -f board/mini2440.cfg
[sudo] password for liyongjun:
Open On-Chip Debugger 0.11.0+dev-00590-g2586fec-dirty (2022-03-12-02:34)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "jtag". To override use 'transport select <transport>'.
force hard breakpoints
Error: No valid NAND flash driver found (0)
Info : J-Link ARM V8 compiled Nov 28 2014 13:44:46
Info : Hardware version: 8.00
Info : VTarget = 3.313 V
Info : clock speed 12000 kHz
Info : JTAG tap: s3c2440.cpu tap/device found: 0x0032409d (mfg: 0x04e (Samsung), part: 0x0324, ver: 0x0)
Info : Embedded ICE version 2
Info : s3c2440.cpu: hardware has 2 breakpoint/watchpoint units
Info : starting gdb server for s3c2440.cpu on 3333
Info : Listening on port 3333 for gdb connections
-------------------------------------------
--- login with - telnet localhost 4444 ---
--- then type help_2440 ---
-------------------------------------------
help_2440
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
telnet 方式连接
liyongjun@liyongjun-desktop:~/project/c/openocd-code/my$ telnet 127.0.0.1 4444
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Open On-Chip Debugger
> help_2440
-----------------------------------------------------------
---- The following mini2440 funcs are supported ----
---- init_2440 - initialize clocks, DRAM, IO ----
---- flash_config - configures nand flash ----
---- load_uboot - loads uboot into ram ----
---- flash_uboot - flashes uboot to nand (untested) ----
---- help_2440 - this help display ----
-----------------------------------------------------------
> halt
target halted in ARM state due to debug-request, current mode: Supervisor
cpsr: 0x80000093 pc: 0xc0031078
MMU: enabled, D-Cache: enabled, I-Cache: enabled
> resume
>
gdb 方式连接
liyongjun@liyongjun-desktop:~/project/c/openocd-code/my$ gdb
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.3) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
(gdb) target remote 127.0.0.1:3333
Remote debugging using 127.0.0.1:3333
warning: while parsing target description (at line 4): Target description specified unknown architecture "arm"
warning: Could not load XML target description; ignoring
0x3001f0d4 in ?? ()
(gdb) continue
Continuing.
^C
Program received signal SIGINT, Interrupt.
0x3001f0d4 in ?? ()
(gdb) continue
Continuing.
^C
Program received signal SIGINT, Interrupt.
0x3001f0d4 in ?? ()
(gdb) continue
Continuing.
^C
Program received signal SIGINT, Interrupt.
0x004155a2 in ?? ()
(gdb) monitor resume
(gdb) monit halt
target halted in ARM state due to debug-request, current mode: Supervisor
cpsr: 0x80000093 pc: 0xc0031078
MMU: enabled, D-Cache: enabled, I-Cache: enabled
(gdb) monitor resume
(gdb)
进阶
在源码目录下执行 arm-none-eabi-gdb 有助于 gdb 分析代码。
错题集
没插 J-Link
liyongjun@liyongjun-desktop:~/project/c/openocd-code/tcl$ sudo ../src/openocd -f board/my107.cfg
Open On-Chip Debugger 0.11.0+dev-00590-g2586fec-dirty (2022-03-12-02:34)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
srst_only separate srst_nogate srst_open_drain connect_deassert_srst
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Error: No J-Link device found
目标板未上电
liyongjun@liyongjun-desktop:~/project/c/openocd-code/tcl$ sudo ../src/openocd -f board/my107.cfg
Open On-Chip Debugger 0.11.0+dev-00590-g2586fec-dirty (2022-03-12-02:34)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
srst_only separate srst_nogate srst_open_drain connect_deassert_srst
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : J-Link ARM V8 compiled Aug 18 2009 09:06:07
Info : Hardware version: 8.00
Info : VTarget = 0.000 V
Error: JTAG I/O operation failed: 0x5.
Error: jaylink_jtag_io() failed: device: unspecified error
Info : clock speed 2000 kHz
Error: JTAG I/O operation failed: 0x5.
Error: jaylink_jtag_io() failed: device: unspecified error
Error: JTAG I/O operation failed: 0x5.
Error: jaylink_jtag_io() failed: device: unspecified error
Error: JTAG I/O operation failed: 0x5.
Error: jaylink_jtag_io() failed: device: unspecified error
embedded:startup.tcl:56: Error:
in procedure 'jtag_init' called at file "src/jtag/core.c", line 1678
in procedure 'init_reset' called at file "embedded:startup.tcl", line 39
at file "embedded:startup.tcl", line 56
embedded:startup.tcl:56: Error:
in procedure 'jtag_init' called at file "src/jtag/core.c", line 1678
in procedure 'init_reset' called at file "embedded:startup.tcl", line 39
at file "embedded:startup.tcl", line 56
参考
浅论各种调试接口(SWD、JTAG、Jlink、Ulink、STlink)的区别
OpenOCD-JTAG调试 OpenOCD命令
openocd+jlink为mini2440调试u-boot
JTAG接口定义与其他简介 jtag 接口图片
JTAG各类接口针脚定义及含义 哪些 jtag 引脚是强制要求的
树莓派3B+底层玩法:OP-TEE、Kernel module、JTAG 成功案例呀
2440开发板处理坏块之换nand flash 换 flash
Preparing Raspberry PI for JTAG Debugging 最终成功了,TDI 引脚不同,含设置引脚模式的 C++ 代码