OpenOCD 通过 JTAG 调试树莓派

43 篇文章 47 订阅
9 篇文章 1 订阅

硬件环境

Linux 主机 + JLink v8 + 树莓派

OpenOCD 简介

在这里插入图片描述
OpenOCD(Open On-Chip Debugger)开源片上调试器,是一款开源软件,旨在提供针对嵌入式设备的调试、系统编程、边界扫描功能。
OpenOCD 的功能是在仿真器的辅助下完成的,仿真器是必须的。
更多详细介绍请看这里

安装 OpenOCD

下载源码,编译,安装
https://openocd.sourceforge.io/

硬件连接

主机通过 USB 连接 JLink,JLink 另一端接在树莓派上(JLink 可以理解为:USB + JTAG)。树莓派上留有 JTAG 引脚,但是没有标准的 JTAG 插槽,所以需要使用杜邦线将 JLink 和 树莓派连接起来,引脚对应如下:
在这里插入图片描述
由于杜邦线连线比较乱,所以我打了个板,这样线就不乱了
在这里插入图片描述 在这里插入图片描述

树莓派引脚设置为 JTAG 功能

这里是个坑。一般芯片引脚都有多个功能,树莓派的 JTAG 功能所对应的引脚,其第一功能也不是 JTAG。所以要先设置这些引脚的功能模式,使其处于 JTAG 模式。代码如下

#include <sys/mman.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

#define BCM2835_PERI_BASE 0x3f000000
#define GPIO_BASE (BCM2835_PERI_BASE + 0x200000)

#define GPIO_ALT_FUNCTION_4 0b011
#define GPIO_ALT_FUNCTION_5 0b010

volatile unsigned *m_pAltFunctionRegisters;

void SetGPIOFunction(int GPIO, int functionCode)
{
	int registerIndex = GPIO / 10;
	int bit = (GPIO % 10) * 3;

	unsigned oldValue = m_pAltFunctionRegisters[registerIndex];
	unsigned mask = 0b111 << bit;
	printf("Changing function of GPIO%d from %x to %x\n", GPIO, (oldValue >> bit) & 0b111, functionCode);
	m_pAltFunctionRegisters[registerIndex] = (oldValue & ~mask) | ((functionCode << bit) & mask);
}

int main()
{
	int fd;

	fd = open("/dev/mem", O_RDWR | O_SYNC);
	if (fd < 0)
		return -1;

	m_pAltFunctionRegisters = (volatile unsigned *)mmap(NULL, 0x18, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO_BASE);
	if (m_pAltFunctionRegisters == MAP_FAILED)
		return -1;

	close(fd);

	if (m_pAltFunctionRegisters == MAP_FAILED)
	{
		printf("Cannot open /dev/mem! Re-run me as root!\n");
		return 1;
	}

	SetGPIOFunction(22, GPIO_ALT_FUNCTION_4);
	SetGPIOFunction(4, GPIO_ALT_FUNCTION_5);
	SetGPIOFunction(27, GPIO_ALT_FUNCTION_4);
	SetGPIOFunction(25, GPIO_ALT_FUNCTION_4);
	SetGPIOFunction(23, GPIO_ALT_FUNCTION_4);
	SetGPIOFunction(24, GPIO_ALT_FUNCTION_4);

	if (m_pAltFunctionRegisters != MAP_FAILED)
		munmap((void *)m_pAltFunctionRegisters, 0x18);

	printf("Successfully enabled JTAG pins. You can start debugging now.\n");

	return 0;
}

交叉编译,放入树莓派中运行就行了。

启动 OpenOCD

$ sudo ../src/openocd -f interface/jlink.cfg -f board/myrpi3b+.cfg

如果未连接 JLink,会报如下错误

$ sudo ../src/openocd -f interface/jlink.cfg -f board/myrpi3b+.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
DEPRECATED! use 'adapter speed' not 'adapter_khz'
Warn : DEPRECATED! use '-baseaddr' not '-ctibase'
Warn : DEPRECATED! use '-baseaddr' not '-ctibase'
Warn : DEPRECATED! use '-baseaddr' not '-ctibase'
Warn : DEPRECATED! use '-baseaddr' not '-ctibase'
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Error: No J-Link device found

如果未连接树莓派,会报如下错误

$ sudo ../src/openocd -f interface/jlink.cfg -f board/myrpi3b+.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
DEPRECATED! use 'adapter speed' not 'adapter_khz'
Warn : DEPRECATED! use '-baseaddr' not '-ctibase'
Warn : DEPRECATED! use '-baseaddr' not '-ctibase'
Warn : DEPRECATED! use '-baseaddr' not '-ctibase'
Warn : DEPRECATED! use '-baseaddr' not '-ctibase'
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 1000 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
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

如果树莓派未处于 JTAG 模式,会报如下错误

$ sudo ../src/openocd -f interface/jlink.cfg -f board/myrpi3b+.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
DEPRECATED! use 'adapter speed' not 'adapter_khz'
Warn : DEPRECATED! use '-baseaddr' not '-ctibase'
Warn : DEPRECATED! use '-baseaddr' not '-ctibase'
Warn : DEPRECATED! use '-baseaddr' not '-ctibase'
Warn : DEPRECATED! use '-baseaddr' not '-ctibase'
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 = 3.267 V
Info : clock speed 1000 kHz
Error: JTAG scan chain interrogation failed: all zeroes
Error: Check JTAG interface, timings, target power, etc.
Error: Trying to use configured scan chain anyway...
Error: rpi3.tap: IR capture error; saw 0x00 not 0x01
Warn : Bypassing JTAG setup events due to errors
Error: Invalid ACK (0) in DAP response

下面是正常连接的 log

$ sudo ../src/openocd -f interface/jlink.cfg -f board/myrpi3b+.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
DEPRECATED! use 'adapter speed' not 'adapter_khz'
Warn : DEPRECATED! use '-baseaddr' not '-ctibase'
Warn : DEPRECATED! use '-baseaddr' not '-ctibase'
Warn : DEPRECATED! use '-baseaddr' not '-ctibase'
Warn : DEPRECATED! use '-baseaddr' not '-ctibase'
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 = 3.267 V
Info : clock speed 1000 kHz
Info : JTAG tap: rpi3.tap tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd), part: 0xba00, ver: 0x4)
Info : rpi3.a53.0: hardware has 6 breakpoints, 4 watchpoints
Info : rpi3.a53.1: hardware has 6 breakpoints, 4 watchpoints
Info : rpi3.a53.2: hardware has 6 breakpoints, 4 watchpoints
Info : rpi3.a53.3: hardware has 6 breakpoints, 4 watchpoints
Info : starting gdb server for rpi3.a53.0 on 3333
Info : Listening on port 3333 for gdb connections
Info : starting gdb server for rpi3.a53.1 on 3334
Info : Listening on port 3334 for gdb connections
Info : starting gdb server for rpi3.a53.2 on 3335
Info : Listening on port 3335 for gdb connections
Info : starting gdb server for rpi3.a53.3 on 3336
Info : Listening on port 3336 for gdb connections

接着就可以通过 telnet 或 gdb 连接 OpenOCD 进行调试了。telnet 和 gdb 相当于是客户端,OpenOCD 相当于是服务端

telnet 方式

$ 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
> resume

gdb 方式

$ 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
0x81031bbf in ?? ()
(gdb) c
Continuing.

gdb 连接后,一上来就会将板子 hold 住,我们输入 continue 指令,板子继续运行。
更多调试方法和命令后面有机会再介绍。

  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
OpenOCD是一款开源的片上调试器,用于嵌入设备的调试、系统编程边界扫描功能。它的功能是仿真器的辅助下完成的,此需要连接一个仿真器。常见的连接方式是使用JLink作为仿真器,通过USB连接到主机,然后使用杜邦线将JLink与树莓派连接起来。树莓派上需要将引脚设置为JTAG功能,以便与JLink进行通信。关于具体的引脚连接方式,请参考引用中提到的引脚对应关系。 对于配置OpenOCD,有两种基本方法。一种是通过命令行中的多个"-f file"或"-c command"来进行配置。另一种是在当前文件夹中创建一个名为"openocd.cfg"的用户配置文件,并在其中进行配置。具体的配置方法可以根据需要选择使用引用中提到的方法。 希望以上回答对您有帮助!123 #### 引用[.reference_title] - *1* *2* [OpenOCD 通过 JTAG 调试树莓派](https://blog.csdn.net/lyndon_li/article/details/124083860)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}} ] [.reference_item] - *3* [JTAG篇(4)——OpenOCDJTAG TAP通信](https://blog.csdn.net/u010170039/article/details/124851465)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}} ] [.reference_item] [ .reference_list ]
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Li-Yongjun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值