本文介绍openocd开源软件的安装以及搭配JTAG对Xilinx u500VC707devkit的调试

PC OS: Ubuntu20.04 LTS

Target ARCH: riscv64

JTAG: Olimex-ARM-USB-TINY-H

OpenOCD version: OpenOCD v0.10.0


1、OpenOCD简介

  OpenOCD(Open On-Chip Debugger)是一款开源的开放式片上调试软件,需要在调试适配器(如: JTAG、SWD等)的配合下可以对片上系统进行相应调试,以及在嵌入式设备上测试系统内程序或边界接扫描测试。

2、下载OpenOCD

  可以通过OpenOCD官网下载源码,已经有很多平台提供配套目标平台的OpenOCD源码,也可以通过这些来下载带有相应目标平台配置文件的OpenOCD,本文主要介绍支持riscv64OpenOCD下载和使用。

riscv-openocd下载链接: https://github.com/sifive/riscv-openocd

通过git下载:

git clone https://github.com/sifive/riscv-openocd.git

3、编译与安装

<1> 进入riscv-openocd源码目录

imaginemiracle@:openocd$ cd riscv-openocd
imaginemiracle@:riscv-openocd$ ls
AUTHORS ChangeLog COPYING HACKING NEWS-0.10.0 NEWS-0.5.0 NEWS-0.9.0 README.Windows TODO
AUTHORS.ChangeLog config_subdir.m4 doc jimtcl NEWS-0.2.0 NEWS-0.6.0 NEWTAPS src tools
bootstrap configure.ac Doxyfile.in Makefile.am NEWS-0.3.0 NEWS-0.7.0 README tcl uncrustify.cfg
BUGS contrib guess-rev.sh NEWS NEWS-0.4.0 NEWS-0.8.0 README.OSX testing

<2> 执行bootstrap生成configure文件,通过configure配置OpenOCD,主要需要配置OpenOCD支持的调试器的类型,笔者使用的JTAGFTDI类型,因此需要OpenOCD支持FTDI

[注] 通过查看JTAG手册了解所使用的JTAG是什么类型,通过./configure --help 命令查看所需要开启的类型以及其它配置参数

#创建安装目录
imaginemiracle@:riscv-openocd$ mkdir install_IM
#执行bootstrap
imaginemiracle@:riscv-openocd$ ./bootstrap

bootstrap执行的正常输出:

+ aclocal
+ libtoolize --automake --copy
+ autoconf
+ autoheader
+ automake --gnu --add-missing --copy
configure.ac:26: installing './compile'
configure.ac:37: installing './config.guess'
configure.ac:37: installing './config.sub'
configure.ac:16: installing './install-sh'
configure.ac:16: installing './missing'
Makefile.am:46: warning: wildcard $(srcdir: non-POSIX variable name
Makefile.am:46: (probably a GNU make extension)
Makefile.am: installing './INSTALL'
Makefile.am: installing './depcomp'
Makefile.am:23: installing './mdate-sh'
Makefile.am:23: installing './texinfo.tex'
Setting up submodules
Submodule 'jimtcl' (https://github.com/msteveb/jimtcl) registered for path 'jimtcl'
Cloning into '/media/imaginemiracle/Disk_D/Linux_Workspace/riscv-project/File_System_test/openocd/riscv-openocd/jimtcl'...
Submodule path 'jimtcl': checked out '51f65c6d38fbf86e1f0b036ad336761fd2ab7fa0'
Submodule path 'jimtcl': checked out '51f65c6d38fbf86e1f0b036ad336761fd2ab7fa0'
Generating build system...
libtoolize: putting auxiliary files in AC_CONFIG_AUX_DIR, 'build-aux'.
libtoolize: copying file 'build-aux/config.guess'
libtoolize: copying file 'build-aux/config.sub'
libtoolize: copying file 'build-aux/install-sh'
libtoolize: copying file 'build-aux/ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'm4'.
libtoolize: copying file 'm4/libtool.m4'
libtoolize: copying file 'm4/ltoptions.m4'
libtoolize: copying file 'm4/ltsugar.m4'
libtoolize: copying file 'm4/ltversion.m4'
libtoolize: copying file 'm4/lt~obsolete.m4'
configure.ac:42: installing 'build-aux/ar-lib'
configure.ac:37: installing 'build-aux/compile'
configure.ac:30: installing 'build-aux/missing'
Makefile.am: installing './INSTALL'
libjaylink/Makefile.am: installing 'build-aux/depcomp'
Bootstrap complete. Quick build instructions:
./configure ....

成功生成configure文件

#配置安装目录路径必须为绝对路径
imaginemiracle@:riscv-openocd$ ./configure --prefix=/home/imaginemiracle/Disk_D/Linux_Workspace/riscv-project/File_System_test/openocd/openocd-0.10.0/install_IM/ --enable-ftdi
###################只显示关键输出####################
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating libjaylink/Makefile
config.status: creating libjaylink/version.h
config.status: creating libjaylink.pc
config.status: creating Doxyfile
config.status: creating config.h
config.status: executing depfiles commands
config.status: executing libtool commands

看到成功成生Makefile文件且没有报错,则说明配置成功。

<3> 配置成功后直接编译并安装即可

直接使用make; make install编译并安装

#编译后并且安装
imaginemiracle@:riscv-openocd$ make; make install

make; make install直接通过,则跳过<4>这一节直接看下一节的openocd使用介绍。

<4> 编译openocd可能会遇到如下几种错误

<4.1> 报错 1: src/svf/svf.c:663:7: error: this statement may fall through [-Werror=implicit-fallthrough=]

#错误1
src/svf/svf.c: In function ‘svf_read_command_from_file’:
src/svf/svf.c:663:7: error: this statement may fall through [-Werror=implicit-fallthrough=]
663 | i = -1;
| ~~^~~~
src/svf/svf.c:664:4: note: here
664 | case '\r':
| ^~~~
src/svf/svf.c:667:8: error: this statement may fall through [-Werror=implicit-fallthrough=]
667 | if (!cmd_pos)
| ^
src/svf/svf.c:669:4: note: here
669 | default:
| ^~~~~~~
cc1: all warnings being treated as errors

解决方案 1: 通过源码分析可以看出,这块的报错只是因为在switch case语句中一个case没有写break,编译器识别到可能会跳到下一个case语句中,因此在这里直接忽略该错误继续编译即可。

imaginemiracle@:openocd$ make -j8 CFLAGS='-Wno-implicit-fallthrough'

<4.2> 报错 2: src/target/arm_disassembler.c:1499:30: error: bitwise comparison always evaluates to false [-Werror=tautological-compare]

#错误2
src/target/arm_disassembler.c: In function ‘evaluate_misc_instr’:
src/target/arm_disassembler.c:1499:30: error: bitwise comparison always evaluates to false [-Werror=tautological-compare]
1499 | if (((opcode & 0x00600000) == 0x00100000) && (x == 0)) {
| ^~
src/target/arm_disassembler.c:1521:29: error: bitwise comparison always evaluates to false [-Werror=tautological-compare]
1521 | if ((opcode & 0x00600000) == 0x00300000) {
| ^~
src/target/arm_disassembler.c:1542:30: error: bitwise comparison always evaluates to false [-Werror=tautological-compare]
1542 | if (((opcode & 0x00600000) == 0x00100000) && (x == 1)) {
| ^~

解决方案 2: 按照道理说这种写法是没什么问题的,但还是会报错,因此将报错的三个位置进行修改,修改后的代码如下。

imaginemiracle@:openocd$ vim src/target/arm_disassembler.c +1499
//File src/target/arm_disassembler.c +1499:In function 'evaluate_misc_instr'
/* SMLAW < y> */
//============================Alter by me==============================
if (!(((opcode & 0x00600000) - 0x00100000)) && (x == 0)) {
//============================ End Alter ==============================
uint8_t Rd, Rm, Rs, Rn;
instruction->type = ARM_SMLAWy;
Rd = (opcode & 0xf0000) >> 16;
Rm = (opcode & 0xf);
Rs = (opcode & 0xf00) >> 8;
Rn = (opcode & 0xf000) >> 12; snprintf(instruction->text,
128,
"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLAW%s%s r%i, r%i, r%i, r%i",
address,
opcode,
(y) ? "T" : "B",
COND(opcode),
Rd,
Rm,
Rs,
Rn);
} /* SMUL < x><y> */
//============================Alter by me==============================
if (!((opcode & 0x00600000) - 0x00300000)) {
//============================ End Alter ==============================
uint8_t Rd, Rm, Rs;
instruction->type = ARM_SMULxy;
Rd = (opcode & 0xf0000) >> 16;
Rm = (opcode & 0xf);
Rs = (opcode & 0xf00) >> 8; snprintf(instruction->text,
128,
"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s%s r%i, r%i, r%i",
address,
opcode,
(x) ? "T" : "B",
(y) ? "T" : "B",
COND(opcode),
Rd,
Rm,
Rs);
} /* SMULW < y> */
//============================Alter by me==============================
if (!(((opcode & 0x00600000) - 0x00100000)) && (x == 1)) {
//============================ End Alter ==============================
uint8_t Rd, Rm, Rs;
instruction->type = ARM_SMULWy;
Rd = (opcode & 0xf0000) >> 16;
Rm = (opcode & 0xf);
Rs = (opcode & 0xf00) >> 8; snprintf(instruction->text,
128,
"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s r%i, r%i, r%i",
address,
opcode,
(y) ? "T" : "B",
COND(opcode),
Rd,
Rm,
Rs);
}

<4.3> 报错 3: src/target/nds32_cmd.c:824:21: error: ‘sprintf’ writing a terminating nul past the end of the destination [-Werror=format-overflow=]

#错误3
src/target/nds32_cmd.c: In function ‘jim_nds32_bulk_read’:
src/target/nds32_cmd.c:824:21: error: ‘sprintf’ writing a terminating nul past the end of the destination [-Werror=format-overflow=]
824 | sprintf(data_str, "0x%08" PRIx32 " ", data[i]);
| ^~~~~~~
src/target/nds32_cmd.c:824:38: note: format string is defined here
824 | sprintf(data_str, "0x%08" PRIx32 " ", data[i]);
| ^
src/target/nds32_cmd.c:824:3: note: ‘sprintf’ output 12 bytes into a destination of size 11
824 | sprintf(data_str, "0x%08" PRIx32 " ", data[i]);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

解决方案 3: 从错误类型format-overflow,格式溢出,一看就是不重要的错误,直接忽略就好继续编译。

imaginemiracle@:openocd$ make -j8 CFLAGS='-Wno-implicit-fallthrough -Wno-format-overflow'

<4.4> 报错 4: /usr/include/x86_64-linux-gnu/sys/sysctl.h:21:2: error: #warning "The <sys/sysctl.h> header is deprecated and will be removed." [-Werror=cpp]

#错误4
In file included from src/helper/options.c:38:
/usr/include/x86_64-linux-gnu/sys/sysctl.h:21:2: error: #warning "The <sys/sysctl.h> header is deprecated and will be removed." [-Werror=cpp]
21 | #warning "The <sys/sysctl.h> header is deprecated and will be removed."
| ^~~~~~~
cc1: all warnings being treated as errors

解决方案 4: 可以看出这里是使用了Linux已经移除的头文件<sys/sysctl.h>报错的,因此进入报错文件,做以下修改。

imaginemiracle@:openocd$ vim src/helper/options.c +38
//File src/helper/options.c +38
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif #include "configuration.h"
#include "log.h"
#include "command.h" #include <getopt.h> #include <limits.h>
#include <stdlib.h>
#if IS_DARWIN
#include <libproc.h>
#endif
//===================Alter by me===================
#ifdef HAVE_SYS_SYSCTL_H
//#include <sys/sysctl.h>
#endif
#if IS_WIN32 && !IS_CYGWIN
#include <windows.h>
#endif
//=================== End Alter ===================
static int help_flag, version_flag;

4、OpenOCD的使用

4.1、OpenOCD的配置

安装成功后则会在配置的安装目录里生成如下文件,这里的openocd就是需要用到的可执行程序将它拷贝到需要执行的目录,或者直接在当前目录使用也可以。([注]: 若未配置安装路径,默认安装到“./src目录”中)

imaginemiracle@:openocd$ cd install_IM/
imaginemiracle@:install_IM$ ls
bin share
imaginemiracle@:install_IM$ ls bin/
openocd
imaginemiracle@:openocd$ cp install_IM/bin/openocd ./

使用openocd+JTAG需要用到两个配置文件,分别是JTAG的配置文件和目标平台的配置文件。一般JTAG厂商都会提供购买到的JTAGopenocd配置文件,这里就可以直接使用。

<1> JTAG设备配置文件

前文提到笔者所使用的JTAG型号为Olimex-ARM-USB-TINY-H,其配置文件如下:

# File olimex-arm-usb-tiny-h.cfg
#
# Olimex ARM-USB-TINY-H
#
# http://www.olimex.com/dev/arm-usb-tiny-h.html
# interface ftdi
#interface jlink
ftdi_device_desc "Olimex OpenOCD JTAG ARM-USB-TINY-H"
ftdi_vid_pid 0x15ba 0x002a ftdi_layout_init 0x0808 0x0a1b
ftdi_layout_signal nSRST -oe 0x0200
ftdi_layout_signal nTRST -data 0x0100 -oe 0x0100
ftdi_layout_signal LED -data 0x0800

当电脑链接上JTAG后,还需要安装JTAG的驱动,若“lsusb”可以查看到JTAG设备,则说明驱动安装成功。

imaginemiracle@:openocd$ lsusb
Bus 002 Device 002: ID 0424:5744 Microchip Technology, Inc. (formerly SMSC) Hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 004: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
Bus 001 Device 003: ID 0424:2744 Microchip Technology, Inc. (formerly SMSC) Hub
Bus 001 Device 007: ID 413c:2113 Dell Computer Corp. Dell KB216 Wired Keyboard
Bus 001 Device 006: ID 413c:301a Dell Computer Corp. Dell MS116 USB Optical Mouse
Bus 001 Device 008: ID 15ba:002a Olimex Ltd. ARM-USB-TINY-H JTAG interface
Bus 001 Device 002: ID 10c4:ea60 Silicon Labs CP210x UART Bridge
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

这里的ID后面的值分别为USB设备的VIDPID,这里的值应该与JTAG配置文件中的vid_pid相同才可。

<2> 目标平台配置文件

OpenOCD的配置文件使用的是tcl语言,这里的目标平台配置文件是笔者仿照其它配置文件修改的。

# File riscv64_IM.cfg
proc init_targets {} {
adapter_khz 1000
reset_config trst_and_srst
set _CHIPNAME riscv
jtag newtap $_CHIPNAME cpu -irlen 5 set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME riscv -endian little -chain-position $_TARGETNAME -coreid 0
# $_TARGETNAME configure -rtos riscv
# $_TARGETNAME configure -work-area-phys 0x3ff0000 -work-area-size 0x10000 -work-area-backup 1
# $_TARGETNAME riscv expose_csrs 3008-3015,4033-4034
} proc sw_reset_halt {} {
reset halt
}

4.2、OpenOCD链接JTAG

有了JTAG和目标平台的两个配置文件后,就可以启动OpenOCD连接本地JTAG设备了,启动命令如下:

imaginemiracle@:riscv-openocd$ sudo ./src/openocd -s ./tcl -f ./tcl/interface/ftdi/olimex-arm-usb-tiny-h.cfg -f ./tcl/target/riscv64_IM.cfg
[sudo] password for imaginemiracle:
Open On-Chip Debugger 0.10.0+dev-01145-gb7bd3f8d4 (2021-01-12-17:54)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
sw_reset_halt
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : auto-selecting first available session transport "jtag". To override use 'transport select <transport>'.
0
Info : clock speed 1000 kHz
Info : TAP riscv.cpu has invalid IDCODE (0xfffffffe)
Info : datacount=2 progbufsize=16
Info : Disabling abstract command reads from CSRs.
Info : Examined RISC-V core; found 4 harts
Info : hart 0: XLEN=64, misa=0x800000000014112d
Info : hart 1: currently disabled
Info : hart 2: currently disabled
Info : hart 3: currently disabled
Info : Listening on port 3333 for gdb connections

连接到本地:

imaginemiracle@:riscv-openocd$ telnet localhost 4444
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
>

如上进入openocd的命令行则说明OpenOCD+JTAG的整个软件环境搭建完成。

4.3、OpenOCD的一些简单命令

OpenOCD常用命令

halt	-暂停CPU
reset -复位目标板
resume -恢复运行
resume 0x123456 -从0x123456地址恢复运行
reg <register> -打印register寄存器的值 load_image <File Name> <Addr> -烧写二进制文件到指定地址
例: load_image image.bin 0x4000000 -烧写image.bin到0x4000000 dump_image <File Name> <Addr> <Size> -将内存从地址Addr开始的Size字节数据读出,保存到文件File Name中 verify_image <File Name> <Addr> [bin|ihex|elf] -将文件File Name与内存Addr开始的数据进行比较,格式可选,bin、ihex、elf step [Addr] -不加地址:从当前位置单步执行; 加地址:从Addr处单步执行
poll -查询目标板当前状态
bp <Addr> <Length> [hw] -在Addr地址设置断点,指令长度为Length,hw代表硬件断点
rbp <Addr> -删除Addr处的断点 mdw <Addr> [Count] -显示从物理地址Addr开始的Count(缺省则默认为1)个字(4Bytes)
mdh <Addr> [Count] -显示从物理地址Addr开始的Count(缺省则默认为1)个半字(2Bytes)
mdb <Addr> [Count] -显示从物理地址Addr开始的Count(缺省则默认为1)个字节(1Byte)
mww <Addr> <Value> -向物理地址Addr写入Value,大小:一个字(4Bytes)
mwh <Addr> <Value> -向物理地址Addr写入Value,大小:一个半字(2Bytes)
mwb <Addr> <Value> -向物理地址Addr写入Value,大小:一个字节(1Bytes)

OpenOCD安装与使用(JTAG调试)的更多相关文章

  1. openocd安装与调试

    环境: 硬件:PC机<------>ARM仿真器v8.00<------>已下载好bit流的Xinlinx SoC开发板(其上有arm cortex-a9核) 软件:Redha ...

  2. C#创建、安装、卸载、调试Windows Service(Windows 服务)的简单教程

    前言:Microsoft Windows 服务能够创建在它们自己的 Windows 会话中可长时间运行的可执行应用程序.这些服务可以在计算机启动时自动启动,可以暂停和重新启动而且不显示任何用户界面.这 ...

  3. wamp下安装php的xdebug调试的方法

    wamp下安装php的xdebug调试的方法 将下载好的php_xdebug-2.1.2-5.2-vc6.dll放在D:/wamp/php/ext/php_xdebug-2.1.2-5.2-vc6.d ...

  4. ARM JTAG 调试原理

    ARM JTAG 调试原理 JTAG的接口是一种特殊的4/5个接脚接口连到芯片上 ,所以在电路版上的很多芯片可以将他们的JTAG接脚 通过Daisy Chain的方式连在一起,并且Probe只需连接到 ...

  5. Python idle安装与使用教程 调试、下载

    Python idle安装与使用教程 调试.下载 今天我们就来讲一下如何安装Python idle编辑器,也它的调试和使用. 第一步,我们先去下载一个Python idle程序安装包. 本节讲的是wi ...

  6. (二)ADS1.2的安装教程以及使用 调试 (不会 AXD 调试工具)

    安装教程: 参考百度 http://jingyan.baidu.com/article/cdddd41c7db85253cb00e1ae.html 具体使用看: 杨铸的那本书(嵌入式底层软件驱动开发) ...

  7. 【C编译器】MinGw安装与使用(调试问题待续)

    不想装vs2005之类的,想要一个轻量级的C语言编译器,希望将焦点放在如何写好代码上: 本人信奉:代码质量是靠设计和检视保证的,不是靠调试: 1.安装MinGW http://www.mingw.or ...

  8. c#创建、安装、卸载、调试windows服务的简单事例

    最近工作中用到了windows服务,对其有深刻理解和丰富经验谈不上,本篇文章只是简单陈诉用c#创建.安装.卸载.调试windows服务的步骤. 一.创建windows服务 1.用VS创建windows ...

  9. .net windows 服务创建、安装、卸载和调试

    原文:http://blog.csdn.net/angle860123/article/details/17375895 windows服务应用程序是一种长期运行在操作系统后台的程序,它对于服务器环境 ...

随机推荐

  1. 最简 Spring AOP 源码分析!

    前言 最近在研究 Spring 源码,Spring 最核心的功能就是 IOC 容器和 AOP.本文定位是以最简的方式,分析 Spring AOP 源码. 基本概念 上面的思维导图能够概括了 Sprin ...

  2. NOI Online #2 提高组 游戏

    没用二项式反演的菜比. 题目链接 Solution 非平局代表的树上祖先关系是比较好统计,(可以在处理一个点时,考虑用他去匹配他的子树中的东西)而平局的关系比较难统计.我们不妨求出至少 \(k\) 个 ...

  3. 【学习笔记】K 短路问题详解

    \(k\) 短路问题简介 所谓"\(k\) 短路"问题,即给定一张 \(n\) 个点,\(m\) 条边的有向图,给定起点 \(s\) 和终点 \(t\),求出所有 \(s\to t ...

  4. 转:什么是Shingling算法

    shingling算法用于计算两个文档的相似度,例如,用于网页去重.维基百科对w-shingling的定义如下: In natural language processing a w-shinglin ...

  5. activiti环境安装

    使用Eclipse安装activiti插件的时候,没有安装成功,参考这边文章才成功,链接:https://jingyan.baidu.com/article/4dc408480d4201c8d846f ...

  6. 使用数据泵,在不知道sys用户密码的情况下导出导入

    expdp \"/as sysdba\" directory=my_dir logfile=expdp.log dumpfile=expdp_scott.dmp schemas=s ...

  7. pandas 学习 第14篇:索引和选择数据

    数据框和序列结构中都有轴标签,轴标签的信息存储在Index对象中,轴标签的最重要的作用是: 唯一标识数据,用于定位数据 用于数据对齐 获取和设置数据集的子集. 本文重点关注如何对序列(Series)和 ...

  8. idea导入配置SSM项目,并进行打包

    idea确实是一个功能强大的开发工具,但是配置项目太复杂,每次都要花费很长的时间在配置上. 关于SSM项目导入,配置,打包,看这篇就够了,百试不爽.

  9. react第五单元(事件系统-原生事件-react中的合成事件-详解事件的冒泡和捕获机制)

    第五单元(事件系统-原生事件-react中的合成事件-详解事件的冒泡和捕获机制) 课程目标 深入理解和掌握事件的冒泡及捕获机制 理解react中的合成事件的本质 在react组件中合理的使用原生事件 ...

  10. Spark性能调优篇六之调节数据本地化等待时长

    数据本地化等待时长调节的优化 在项目该如何使用? 通过 spark.locality.wait 参数进行设置,默认为3s,6s,10s. 项目中代码展示: new SparkConf().set(&q ...