CLion Tips & Tricks

想要无线刷写和调试 MCU 吗? 只需使用您的 Raspberry Pi

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

在许多情况下,这种设置可以正常工作。 但嵌入式设备需要处理现实世界问题。 有时,我们会使用基于 MCU 的控制板管理高压或危险设备。 有时,这些设备安装在户外。 设备可能会在轮子上移动,也可能漂浮在水面上。 它们甚至可能安装在某个远程位置。 在这些情况下使用线缆进行设置通常不太方便,甚至可能会有危险。

当我开始开发户外设备时,我立即遇到了这个问题。 该如何解决呢? 我盘点了一下手头上的东西,发现了一块 Raspberry Pi 开发板。 我花了几个小时将它设置为无线调试探头,现在它运行得很棒。

最简单的无线设置原则

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

常规设置:

有线设置

无线设置:

无线设置

哪种开发板更合适?

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

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

Raspberry PI 操作系统和连接

首先,我们需要启动和运行 Raspberry Pi,并连接到 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 后进行远程访问。 更多详细信息

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

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

  • ssh pi@192.168.0.110
  • putty.exe pi@192.168.0.110

默认密码为 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,它就会显示在横幅上。

RaspberryPi

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

设置示例项目

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

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

硬件接线

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

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

注意! 如果您自行制作设备,请确保您的目标设备支持 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

设置

如您所见,不涉及任何额外组件 – 只涉及目标设备、电源、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 毫秒)

配置

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

片上调试

附加内容 – 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 接口。

设置 2

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,因此我们必须使用工具链调试器。

工具链

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

CMake 配置文件

在撰写这篇博文时(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 pi@192.168.0.110 openocd -f ~/rpi1-gpio-jtag.cfg -f target/gd32vf103.cfg

 

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

结论

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

您的 CLion 团队
JetBrains
The Drive to Develop

 

本博文英文原作者: