JetBrains

CLion 教程 | 使用开源调试工具 OpenOCD 实现树莓派对 MCU 的远程调试

Image

嵌入式开发者如何设置进行编程所需的一切呢?典型的有线设置包括放在开发者桌上的设备,以及将其连接到调试探头的带状线缆,调试探头又通过 USB 线缆连接到开发者的计算机上的探头专用软件和 IDE。

在许多情况下,这种设置可以正常工作。但嵌入式设备在现实世界的运用可没这么简单。有时,我们会使用基于 MCU 的控制板管理高压或危险设备。有时,这些设备安装在户外。设备可能会在轮子上移动,也可能漂浮在水面上,甚至还可能安装在某个远程位置。在这些情况下,使用有线设置不仅不方便,而且可能造成危险。

当我开始开发户外设备时,我很快遇到了这个问题。我检查了自己手头上的资源,发现了一块树莓派(Raspberry Pi)开发板。我花了几个小时将它设置为无线调试探头,现在它完美运行。在这篇教程中,我们就来看看这一切是如何实现的。

最简单的无线设置原则

每个基于 ARM 的 MCU 都有一个双线调试接口 (SWD) 和一条复位线。这三条线都应该连接到调试探头。在我的无线设置中,我使用 Raspberry Pi GPIO 排针直接连接到设备。在软件方面,我的树莓派运行开源的片上刷写和调试实用工具 OpenOCD 作为远程 GDB 服务器,并通过 Wi-Fi 将一个与 CLion IDE 捆绑的调试器与其相连。开放网络通信可能不安全,因此我将 GDB 与 OpenOCD 之间的 TCP 通道包装为 SSH 隧道。下面的示意图展示了两种设置之间的差异。

常规设置:

Image

无线设置:

Image

哪种开发板更合适?

在我的设置中,我使用了 Raspberry Pi Zero W,我认为这是一个非常好的选择。它很小巧。附带板载 Wi-Fi 模组。功耗相对较低。无需风扇冷却。购买方便。而且,运行速度够快。但是,与 RPi 2+ 相比,这块开发板有几个缺点。它的 CPU 速度较慢,从头开始设置可能需要更长的时间。此外,RPi Zero W 仅支持 2.4GHz Wi-Fi 网络,不支持 5GHz。

您可以使用任何您喜欢的树莓派开发板。唯一的主要区别是需要调整的网络设置和 OpenOCD 配置参数:bcm2835gpio_peripheral_base 和 bcm2835gpio_speed_coeffs。

树莓派操作系统和连接

首先,我们需要启动和运行树莓派,并连接到 Wi-Fi 网络。这需要一张空的 SD 卡,4 GB 应该足够了。

第一步是将操作系统镜像复制到 SD 卡。最好选择 Raspberry Pi OS (32-bit) Lite。您可以在这里找到 Windows、Linux 和 macOS 的官方安装说明。

将镜像写入 SD 卡后,下一步是确保将开发板连接到 Wi-Fi 网络。弹出 SD 卡并将其插入读卡器,然后按照以下说明设置 Wi-Fi。(请注意,RPi Zero W 仅支持 2.4GHz Wi-Fi。)

接下来,将名为 ssh 的文件写入 SD 卡的根文件夹。文件的内容并不重要,即使是空文件也可以。这将激活 ssh 服务器,以便在启动 Raspberry 后进行远程访问。 更多详细信息。

现在,我们可以将卡插入树莓派并将其打开。如果一切正常,几分钟后,开发板将显示为网络中的一个新 Wi-Fi 设备。可以在 Wi-Fi 路由器的 DHCP 状态页面查看其 IP 地址。建议在该页面为开发板设置一个永久 IP 地址。在我的示例中,地址为 192.168.0.110。

为了控制开发板,我们需要一个 SSH 客户端。在 Linux 和 macOS 上使用 ssh 工具,在 Windows 上使用 putty 工具:

默认密码为 raspberry。我们强烈建议您登录开发板后立即更改密码。可以使用 passwd 命令更改密码。

下一步是更新 Raspberry OS。这很耗时,但我还是建议您进行更新。最好让所有 Linux 软件保持最新。可以使用命令:

sudo apt update; sudo apt -y full-upgrade; sudo apt -y autoremove --purge

进行更新。重启开发板 (sudo reboot),然后使用新密码重新登录。

OpenOCD 安装

由于没有为 Raspberry 预构建的 OpenOCD 二进制软件包,我们需要自己构建。此过程可能需要一些时间,请耐心等待。

首先,必须使用以下命令安装 Git、构建工具和库:

sudo apt install -y git gcc binutils make libtool pkg-config autoconf automake texinfo libgpiod-dev libusb-1.0

接下来,我们需要下载 OpenOCD 源。对于我们的目的,我们只需要最新修订,对 Git 仓库进行浅克隆就足够了。以下命令将在 openocd-git 文件夹中创建该克隆:

git clone --depth 1 git://git.code.sf.net/p/openocd/code openocd-git

我们来配置、构建并安装实际的实用工具。应逐个调用以下序列中的命令:

cd openocd-git
./bootstrap
 ./configure --enable-linuxgpiod  --enable-bcm2835gpio --enable-sysfsgpio
make
sudo make install

等这些命令运行完毕后,OpenOCD 就准备就绪了。

最终 Raspberry 设置

OpenOCD 是一个用于系统内编程和片上调试的实用工具。它支持多种不同的微控制器核心以及不同的刷写接口和不同的协议。OpenOCD 使用三种类型的配置文件:

  • 探头接口配置。

  • 目标设备核心配置。

  • 开发板配置,通常包括对探头接口的引用、对核心配置的引用以及可选的调整。

我们不会触及核心,但我们确实需要探头接口配置。以下命令会在 pi 用户主目录下创建一个名为 rpi1-gpio.cfg 的配置。

cat <<EOF > ~/rpi1-gpio.cfg
#
# Config for using Raspberry Pi's expansion header
#
# This is best used with a fast enough buffer but also
# is suitable for direct connection if the target voltage
# matches RPi's 3.3V and the cable is short enough.
#
# Do not forget the GND connection, pin 6 of the expansion header.
#

adapter driver bcm2835gpio

bcm2835gpio_peripheral_base 0x20000000

# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET
# These depend on system clock, calibrated for stock 700MHz
# bcm2835gpio_speed SPEED_COEFF SPEED_OFFSET
bcm2835gpio_speed_coeffs 113714 28

# Each of the SWD lines need a gpio number set: swclk swdio
# Header pin numbers: 22 18
bcm2835gpio_swd_nums 25 24

# If you define trst or srst, use appropriate reset_config

# Header pin number: 26
# bcm2835gpio_trst_num 7
# reset_config trst_only

# Header pin number: 12
bcm2835gpio_srst_num 18
reset_config srst_only srst_push_pull

# If you have both connected,
# reset_config trst_and_srst srst_push_pull

transport select swd

EOF

从上面的配置文件中,我们可以看到 GPIO 排针引脚分配:

Pin 6  -> GND
Pin 12 -> !RESET
Pin 18 -> SWDIO
Pin 22 -> SWCLK

还有最后一个可选步骤。 无线探头的引脚分配可能很容易忘记,但我们可以进行方便的提醒。 以下命令会添加一个带有引脚分配的登录横幅。

cat <<EOF1 >>~/.profile
cat <<EOF
RPi GPIO Header Pinout
+--------+
|  1   2 |  +5V
|  3   4 |
|  5   6 |  GND
|  7   8 |
|  9  10 |
| 11  12 |  RESET
| 13  14 |
| 15  16 |  TMS
| 17  18 |  SWDIO/TDI
| 19  20 |
| 21  22 |  SWCLK/TCK
| 23  24 |  TDO
| 25  26 |
| 27  28 |
| 29  30 |
| 31  32 |
| 33  34 |
| 35  36 |
| 37  38 |
| 39  40 |
+--------+
EOF
EOF1

下次我们忘记引脚分配时,只需重新登录 Raspberry,它就会显示在横幅上。

Image

现在,我们已经完成了 Raspberry 软件的设置。接下来,我们将继续介绍硬件和固件示例项目。但在此之前,我们需要考虑最后一点。

设置示例项目

尝试此示例需要 CLion IDE 和 ARM 嵌入式工具链。设置它们的说明分别可以在这里和这里找到。

对于示例项目,我将使用焊接到 STM32F3-Discovery 开发板上的 MCU,但使用 RPi 而非板载 ST-LINK 接口。示例项目可以从 GitHub 仓库克隆。该项目用 C 和 C++17 编写。

硬件接线

首先,将两根跳线从 ST-LINK 连接器上拆下。板载刷写探头现在已经与 MCU 断开。

本演示的目标 MCU 使用 GPIO 排针的引脚 2,由树莓派本身供电。

注意!如果您自行制作设备,请确保您的目标设备支持 5 V 电源电压,且功耗不超过 200 mA。否则,请使用其他电源方案。

因此,接线应如下所示:

Rpi Pin 6  -> GND   -> DISCO GND
Rpi Pin 12 -> RESET -> DISCO nRST
Rpi Pin 18 -> SWDIO -> DISCO PA13
Rpi Pin 22 -> SWCLK -> DISCO PA14
Rpi Pin 2  -> PWR   -> DISCO 5V
Image

如您所见,不涉及任何额外组件 – 只涉及目标设备、电源、RPi 和一些电线。

启动

演示项目应该运行本地安装的 OpenOCD,并使用常规的有线设置。

我们使用以下参数创建一个 Embedded GDB Server(嵌入式 GDB 服务器)类型的备用运行配置。

  • Target(目标)– 从列表中选择一个;默认情况下应该只有一个。

  • Executable(可执行文件)– 从列表中选择一个;默认情况下应该只有一个。

  • Debugger(调试器)– 捆绑的或来自 ARM 工具链的均可。

  • Target remote args(目标远程实参)– tcp::3333。GDB 服务器将尝试连接到本地主机,端口为 3333。

  • GDB server(GDB 服务器)– 指向您的 plink(Windows + putty) 或 ssh(Linux、macOS)实用工具的路径

  • GDB server args(GDB 服务器实参)– -t -pw somepassword-L 3333:127.0.0.1:3333 pi@your_rpi_ip_address openocd -f rpi1-gpio.cfg -f target/stm32f3x.cfg

请注意,您必须使用自己的 RPi IP 地址和密码。此外,您可以使用非 target/stm32f3x.cfg 的目标配置文件。

GDB 服务器实参是这些参数中最麻烦的。我们来逐一介绍一下它们的各个元素。

  • -t 会为在 RPi (OpenOCD) 启动的实用工具保留一个伪终端。

  • -pw somepassword 会提供一个 ssh 密码。请使用您自己的密码。

  • pi@your_rpi_ip_address 会提供 RPi 开发板的用户名和 IP 地址。请使用您自己的地址。

  • -L 3333:127.0.0.1:3333 会组织加密的 SSH 隧道。RPi 开发板上的本地端口 3333 会被透明地转发到开发者计算机的端口 3333。

  • openocd -f rpi1-gpio.cfg -f target/stm32f3x.cfg 会使用我们的接口配置和 STM32F3 系列内核在 RPi 上启动 OpenOCD。

现在,我们还剩最后一项需要设置:

Advanced GDB Server Options -> Startup Delay – 1000 ms(高级 GDB 服务器选项 -> 启动延迟 – 1000 毫秒)

Image

完成!只需点击 Debug(调试)按钮 – MCU 固件将被编译和刷写,调试器会话将启动。

Image

附加内容 – JTAG 和 RISC-V

您有没有注意到,在引脚分配提示上,一些额外的引脚上标有典型的 JTAG 信号?这是有意为之,因为也支持 JTAG 接口。我们来使用 JTAG 接口。

以下脚本会生成一个 JTAG 配置文件:

cat <<EOF >~/rpi1-gpio-jtag.cfg
#
# Config for using Raspberry Pi's expansion header
#
# This is best used with a fast enough buffer but also
# is suitable for direct connection if the target voltage
# matches RPi's 3.3V and the cable is short enough.
#
# Do not forget the GND connection, pin 6 of the expansion header.
#

adapter driver bcm2835gpio

bcm2835gpio_peripheral_base 0x20000000

# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET
# These depend on system clock, calibrated for stock 700MHz
# bcm2835gpio_speed SPEED_COEFF SPEED_OFFSET
bcm2835gpio_speed_coeffs 113714 28

# Each of the JTAG lines need a gpio number set: tck tms tdi tdo
# Header pin numbers: 22 16 18 24
bcm2835gpio_jtag_nums 25 23 24 8

# If you define trst or srst, use appropriate reset_config

# Header pin number: 26
# bcm2835gpio_trst_num 7
# reset_config trst_only

# Header pin number: 12
bcm2835gpio_srst_num 18
reset_config srst_only srst_push_pull

# If you have both connected,
# reset_config trst_and_srst srst_push_pull

adapter speed 600
EOF

在本例中,我连接了由 GD32VF103 芯片驱动的 Longan Nano 开发板,该芯片是 RISC-V 内核,因此没有 SWD 接口。

Image
Rpi Pin 1  -> 3.3V  -> Longan 3V3 <strong>Be careful! Pin 2 5V might damage your board</strong>
Rpi Pin 6  -> GND   -> Longan GND
Rpi Pin 16 -> TMS   -> Longan TMS
Rpi Pin 18 -> TDI   -> Longan TDI
Rpi Pin 22 -> TCK   -> Longan TCK
Rpi Pin 24 -> TDO   -> Longan TDO

我使用了从 xPack 仓库下载的 Risc-V 工具链。捆绑的调试器不支持 Risc-V,因此我们必须使用工具链调试器。

Image

不要忘记切换 CMake 设置页面上的工具链

Image

在撰写这篇博文时(2021 年 3 月),OpenOCD master 分支对 RISC-V 芯片的支持还不是特别好,因此 OpenOCD 应该从特定的 Risc-V 复刻克隆,并如上所示进行构建。

示例项目位于 GitHub 上,并且已经在其中创建运行配置。RISC-V MCU 的此运行配置与上面提到的 STM32F3 的配置非常相似,但它使用的 GDB 服务器实参略有不同,这些实参引用不同的传输和不同的 MCU:

-t -pw raspberry -L 3333:127.0.0.1:3333 [email protected] openocd -f ~/rpi1-gpio-jtag.cfg -f target/gd32vf103.cfg

现在,您需要做的就是设置自己的密码和 RPi 网络地址。

结论

树莓派是一款非常流行且易用的单板 Linux 计算机。它通常用于 DIY 项目。OpenOCD 是一个开源程序,用于刷写、调试和测试微控制器,包括 ARM 和 RISC-V 内核以及许多其他内核。与 CLion 一起使用时,这些资源会使嵌入式开发更容易、更愉悦,在某些情况下甚至更安全。这篇博文中介绍的无线设置既适用于业余爱好项目,也适用于专业项目。

本博文英文原作者:Ilia Motornyi

CLion 相关阅读

Image
Image
Image
Image

关于 CLion

CLion 是用于 Windows、Linux 和 macOS 上 C 或 C++开发的智能 IDE。CLion 了解现代 C++ 标准并提供预处理程序支持。它还集成了 GDB/LDB 和一套单元测试框架。 

进一步了解 CLion

Image

⏬ 戳「阅读原文」了解更多