三,调试测试
1,在启动OpenOCD连接JLink之前需要进行配置,可以用OpenOCD的帮助命令看有那些命令可以用来和OpenOCD进行交互操作,当然需要看下OpenOCD Manual来了解这些命令怎么使用。
[root@localhost ~]# openocd --h
Open On-Chip Debugger 0.4.0 (2011-03-28-11:40)
Licensed under GNU GPL v2
For bug reports, read
Open On-Chip Debugger
Licensed under GNU GPL v2
--help | -h display this help
--version | -v display OpenOCD version
--file | -f use configuration file <name>
--search | -s dir to search for config files and scripts
--debug | -d set debug level <0-3>
--log_output | -l redirect log output to file <name>
--command | -c run <command>
--pipe | -p use pipes for gdb communication
[root@localhost ~]#
2,进入到Leds工程目录下,用vi命令新建一个配置openocd.cfg
[root@localhost Leds]# vi openocd.cfg
然后将以下内容粘贴其中
#The configuration script can be divided in the following 5 sections:
#-------------------------------------------------------------------------
#No.1 the interface configuration
#-------------------------------------------------------------------------
interface jlink
#-------------------------------------------------------------------------
#No.2 daemon configuration
#------------------------------------------------------------------------
#The default telnet port setup
#----------------------------------------------------------------
telnet_port 4444
#----------------------------------------------------------------
#The default tcl port setup
#----------------------------------------------------------------
#tcl_port 6666
#----------------------------------------------------------------
#GDB setup
#----------------------------------------------------------------
gdb_port 2331
#----------------------------------------------------------------
#gdb breakpoint override <hard|soft|disabled>
#Note that GDB will use hardware breakpoints
#if the memory map has been set up for flash regions.
#----------------------------------------------------------------
#gdb_breakpoint_override hard
#----------------------------------------------------------------
#gdb memory map <enable|disable>
#enable when to set hardware breakpoints, and program flash
#using the gdb load command,enable is default.
#----------------------------------------------------------------
#gdb_memory_map enable
#gdb_flash_program enable
#-------------------------------------------------------------------------
#No.3 target configuration
#-------------------------------------------------------------------------
if { [info exists CHIPNAME] } {
set _CHIPNAME $CHIPNAME
} else {
set _CHIPNAME s3c2440
}
if { [info exists ENDIAN] } {
set _ENDIAN $ENDIAN
} else {
# this defaults to a bigendian
set _ENDIAN little
}
if { [info exists CPUTAPID ] } {
set _CPUTAPID $CPUTAPID
} else {
# force an error till we get a good number
set _CPUTAPID 0x0032409d
}
#-------------------------------------------------------------------------
#No.4 jtag scan chain
#-------------------------------------------------------------------------
#In order for OpenOCD to control a target, a JTAG tap must be defined
#/created.
#jtag newtap CHIPNAME TAPNAME configparams ....
#Required configparams
# -irlen NUMBER - the length in bits of the instruction register
# -ircapture NUMBER - the ID code capture command.
# -irmask NUMBER - the corresponding mask for the ir register.
#Optional configparams
#-expected-id NUMBER By default it is zero. If non-zero represents the
#expected tap ID used when the Jtag Chain is examined. See below.
# -disable
# -enable By default not specified the tap is enabled.
#newtap is a sub command of the "jtag" command.
jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID
target create mini2440 arm920t -endian $_ENDIAN -chain-position $_CHIPNAME.cpu -variant arm920t
mini2440 configure -work-area-virt 0 -work-area-phys 0x200000 -work-area-size 0x4000 -work-area-backup 1
#------------------------------------------------
# ARM SPECIFIC
#------------------------------------------------
targets
#arm7_9 dcc_downloads enable
#arm7_9 fast_memory_access enable
#arm7_9 dbgrq enable
#----------------------------------------------------------------
# JTAG ADAPTER SPECIFIC
#----------------------------------------------------------------
#To set the JTAG frequency(khz)
jtag interface
jtag_khz 12000
#-------------------------------------------------------------------------
#No.5 flash configuration
#-------------------------------------------------------------------------
#fash bank cfi <base> <size> <chip width> <bus width> <target#>
#[jedec_probe|x16 as x8]
#chip width and bus width are specified in bytes.
# 1MBx16 NOR Flash
#flash bank cfi 0x40000000 0x200000 2 2 mini2440 #jedec_probe
# NAND flash
#nand device s3c2440 mini2440
#----------------------------------------------------------------
#reset configuration
#----------------------------------------------------------------
#How long (in milliseconds) OpenOCD should wait after deasserting nSRST
#before starting new JTAG operations.
#----------------------------------------------------------------
jtag_nsrst_delay 100
#----------------------------------------------------------------
#it are useful if reset circuitry (like a big resistor/capacitor,reset
#supervisor, or on-chip features). This keeps the signal asserted for
#some time after the external reset got deasserted.
#----------------------------------------------------------------
jtag_ntrst_delay 100
#-----------------------------------------------------------------
#reset_config <signals> [combination] [trst type] [srst type]
#[combination] is an optional value specifying broken reset signal.
#The default behaviour if no option given is `separate'.
#The [trst type] and [srst type] parameters allow the driver type of
#the reset lines to be specified. Possible values are `trst_push_pull'
# (default) and `trst_open_drain' for the test reset signal, and
#`srst_open_drain' (default) and `srst_push_pull' for the system reset.
#-----------------------------------------------------------------
reset_config trst_and_srst
保存并退出,有关openocd脚本编写可以参考
/usr/local/share/openocd/scripts/board 和usr/local/share/openocd/scripts/target相关内容
3,确保j-link正确连到了CentOS
启动openocd服务
在启动时最好测试一下,有时会出现如下情形
[root@localhost Leds]# JLinkExe
SEGGER J-Link Commander V4.22 ('?' for help)
Compiled Dec 17 2010 17:41:09
Can not connect to J-Link via USB.
J-Link>
如果上面链接不上的情形,就先断开和CentOS的连接,并在windows下启动J-Link Commander,如下图所示
可以看到连接成功,这时再重新断开windows连到CentOS,然后执行usb连接命令
J-Link>usb
Connecting to J-Link via USB (Port: 0)
DLL version V4.22, compiled Dec 17 2010 17:41:06
Firmware: J-Link ARM V8 compiled Dec 1 2015 11:42:48
Hardware: V8.00
S/N: 20080643
Feature(s): RDI,FlashDL,FlashBP,JFlash,GDBFull
VTarget = 3.254V
Info: TotalIRLen = 4, IRPrint = 0x01
Info: CP15.0.0: 0x41129200: ARM, Architecure 4T
Info: CP15.0.1: 0x0D172172: ICache: 16kB (64*8*32), DCache: 16kB (64*8*32)
Info: Cache type: Separate, Write-back, Format A
Found 1 JTAG device, Total IRLen = 4:
#0 Id: 0x0032409D, IRLen: 04, Unknown device
Found ARM with core Id 0x0032409D (ARM9)
JTAG speed: 100 kHz
J-Link>
4,启动openocd服务
[root@localhost Leds]# openocd
Open On-Chip Debugger 0.4.0 (2011-03-28-11:40)
Licensed under GNU GPL v2
For bug reports, read
force hard breakpoints
trst_and_srst separate srst_gates_jtag trst_push_pull srst_open_drain
12000 kHz
jtag_nsrst_delay: 100
jtag_ntrst_delay: 100
trst_and_srst separate srst_gates_jtag trst_push_pull srst_open_drain
Info : J-Link initialization started / target CPU reset initiated
Info : J-Link ARM V8 compiled Dec 1 2015 11:42:48
Info : JLink caps 0xb9ff7bbf
Info : JLink hw version 80000
Info : JLink max mem block 9576
Info : Vref = 3.254 TCK = 1 TDI = 0 TDO = 1 TMS = 0 SRST = 1 TRST = 0
Info : J-Link JTAG Interface ready
Info : clock speed 12000 kHz
Info : JTAG tap: s3c2440.cpu tap/device found: 0x0032409d (mfg: 0x04e, part: 0x0324, ver: 0x0)
Info : Embedded ICE version 2
Info : s3c2440.cpu: hardware has 2 breakpoint/watchpoint units
5,在另一个终端中启动调试程序
在终端的命令行调试程序有两种调试方式:
A,直接调用openocd调试命令进行调试
【1】openocd常用命令
<1>连接命令
telnet ip port :ip表示远程或本地主机(如localhost),port表示端口号,即配置脚本中telnet_port指定端口号。
<2>目标板状态处理命令(Target state handling)
poll :查询目标板当前状态。
halt :中断目标板的运行。
resume [address] :恢复目标板的运行,如果指定了address,则从address 处开始运行。
step [address] :单步执行,如果指定了address,则从address 处开始执行一条指令。
reset :复位目标板。
<3>断点命令
bp <addr> <length> [hw] :在地址addr 处设置断点,指令长度为length,hw 表示硬件断点。
rbp <addr> :删除地址addr 处的断点。
<4>内存访问指令(Memory access commands)
mdw ['phys'] <addr> [count] :显示从(物理)地址addr 开始的count(缺省是1)个字(4 字节)。
mdh ['phys'] <addr> [count] :显示从(物理)地址addr 开始的count(缺省是1)个半字(2 字节)。
mdb ['phys'] <addr> [count] :显示从(物理)地址addr 开始的count(缺省是1)个字节。
mww ['phys'] <addr> <value> :向(物理)地址addr 写入一个字,值为value。
mwh ['phys'] <addr> <value> :向(物理)地址addr 写入一个半字,值为value。
mwb ['phys'] <addr> <value> :向(物理)地址addr 写入一个字节,值为value。
load_image <file> <address> [‘bin’|‘ihex’|‘elf’] :
将文件<file>载入地址为address 的内存,格式有‘bin’、‘ihex’、‘elf’。
dump_image <file> <address> <size> :
将内存从地址address 开始的size 字节数据读出,保存到文件<file>中。
verify_image <file> <address> [‘bin’|‘ihex’|‘elf’]:
将文件<file>与内存address 开始的数据进行比较,格式有‘bin’、‘ihex’、‘elf’。
<5>CPU 架构相关命令(Architecture Specific Commands)
reg: 打印寄存器的值。
arm7_9 fast_memory_access ['enable'|'disable'] :使能或禁止“快速的内存访问”。
arm mcr cpnum op1 CRn op2 CRm value :修改协处理器的寄存器,比如:arm mcr 15 0 1 0 0 0 关闭MMU。
arm mrc cpnum op1 CRn op2 CRm:读出协处理器的寄存器,比如:arm mcr 15 0 1 0 0读出cp15协处理器的寄存器1。
arm920t cp15 regnum [value] :修改或读取cp15 协处理器的寄存器,比如arm920t cp15 2 0 关闭MMU。
virt2phys virtual_address: 获得虚拟地址对应的物理地址。
<6>其他命令
script <file> :执行file 文件中的命令。
【2】启动openocd调试器
[root@localhost ~]# telnet localhost 4444
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
Open On-Chip Debugger
>
【3】命令测试
> poll
background polling: on
TAP: s3c2440.cpu (enabled)
target state: running
> halt
target state: halted
target halted in ARM state due to debug-request, current mode: System
cpsr: 0x6000005f pc: 0x33f08f7c
MMU: enabled, D-Cache: enabled, I-Cache: enabled
> arm920t cp15 2 0
2: 00000000
> step
target state: halted
target halted in ARM state due to single-step, current mode: System
cpsr: 0x6000005f pc: 0x33f08f80
MMU: disabled, D-Cache: disabled, I-Cache: disabled
【4】加载测试文件
> load_image leds_elf
360 bytes written at address 0x30000000
downloaded 360 bytes in 0.092932s (3.783 kb/s)
>
【5】恢复运行
> resume
这时可以看到mini2440上led在闪烁
【6】暂停后退出调试
> halt
target state: halted
target halted in ARM state due to debug-request, current mode: System
cpsr: 0x6000005f pc: 0x33f08f58
MMU: disabled, D-Cache: disabled, I-Cache: disabled
> exit
Connection closed by foreign host.
[root@localhost ~]#
B,在新打开的终端中用GDB中用dgb端口进行连接
【1】GDB常用命令
<1>启动/退出
gdb [FILE] 或xxx-xxxx-xxxx-xxxx-gdb [FILE]:x表示前缀字符,启动gdb,调试FILE(也可以先不指定文件)。
quit 退出gdb。
<2>连接操作
target remote ip:port :远程连接,ip表示主机IP地址或主机名(如localhost),port表示端口号,即配置脚本中gdb_port指定端口号。
<3>文件操作
file <FILE> :载入文件FILE,注意:不会下载到目标板上。
load [FILE] :把文件下载到目标板上,如果不指定FILE,则下载之前指定过的(比如file 命令指定的,或是gdb 运行时指定的文件)。
<4>查看源程序
list <FUNCTION>: 列出某个函数FUNCTION。
list <LINENUM> :以当前源文件的某行LINENUM为中间显示一段源程序。
list 接着前一次继续显示。
break *<address> :在某个地址上设置断点,比如 break *0x84。
list - :显示前一次之前的源程序。
list <FILENAME:FUNCTION>或list <FILENAME:LINENUM>:显示指定文件的一段程序。
info source: 查看当前源程序。
info stack :查看堆栈信息。
info args: 查看当前的参数。
<5>断点操作
break <FUNCTION> :在函数入口设置断点。
break <LINENUM> :在当前源文件的某一行上设置断点。
break <FILENAME:LINENUM> :在指定源文件的某一行上设置断点。
info br :查看断点。
delete <number>: 删除断点。
diable <number>: 禁止断点。
enable <number> :使能断点。
<6>监视点(watch)操作
watch <EXPRESSION> :当指定变量被写时,程序被停止。
rwatch <EXPRESSION> :当指定变量被读时,程序被停止。
<7>数据操作
print < EXPRESSION > :查看数据。
set varible=value :设置变量。
x /NFU ADDR: 检查内存值。
① N 代表重复数
② F 代表输出格式
x :16 进制整数格式
d :有符号十进制整数格式
u :无符号十进制整数格式
f :浮点数格式
③ U 代表输出格式:
b :字节(byte)
h :双字节数值
w :四字节数值
g :八字节数值
比如“x /4ub 0x0”将会显示0 地址开始到4 个字节。
<8>执行程序
step :单步执行,会跟踪进入一个函数。
next :单步执行,指令则不会进入函数。
nexti :单步执行,执行一条汇编指令。
continue 继续执行程序,加载程序后也可以用来启动程序
<9>帮助
help [command] :列出帮助信息,或是列出某个命令的帮助信息。
<10>其他命令
monitor <command …> :调用gdb 服务器软件的命令,比如:“monitor mdw 0x0”就是调用openocd 本身的命令
“mdw 0x0”。
【2】 启动调试程序
[root@localhost ~]# arm-none-eabi-gdb
GNU gdb (Sourcery G++ Lite 2010.09-51) 7.2.50.20100908-cvs
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <>
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=i686-pc-linux-gnu --target=arm-none-eabi".
For bug reporting instructions, please see:
<https://support.codesourcery.com/GNUToolchain/>.
(gdb)
【3】建立gdb和openocd之间的连接
(gdb) target remote localhost:2331
Remote debugging using localhost:2331
0x33f08f58 in ?? ()
(gdb)
【4】停止开发板上其它可能运行的程序
(gdb) monitor halt
target state: halted
target halted in ARM state due to debug-request, current mode: System
cpsr: 0x6000005f pc: 0x33f08f7c
MMU: enabled, D-Cache: enabled, I-Cache: enabled
(gdb)
【5】禁止MMU
(gdb) monitor arm920t cp15 2 0
2: 00000000
(gdb) monitor step
target state: halted
target halted in ARM state due to single-step, current mode: System
cpsr: 0x6000005f pc: 0x33f08f80
MMU: disabled, D-Cache: disabled, I-Cache: disabled
(gdb)
【6】下载elf镜像文件
(gdb) load leds_elf
Loading section .text, size 0x168 lma 0x30000000
Start address 0x30000000, load size 360
Transfer rate: 4 KB/sec, 360 bytes/write.
(gdb)
【7】进入开始执行调试
<1>设置断点(break point)
(gdb) b main
Breakpoint 1 at 0x300000c8: file leds.c, line 19.
(gdb)
<2>单步运行(next)
(gdb) n
20 rGPBUP = 0x7ff;
<3>退出调试(quit命令)
(gdb) q
A debugging session is active.
Inferior 1 [Remote target] will be killed.
Quit anyway? (y or n) y
[root@localhost Leds]#
至此在命令行执行调试成功。