想要无线刷写和调试 MCU 吗? 只需使用您的 Raspberry Pi
嵌入式开发者如何设置进行编程所需的一切? 典型的有线设置包括放在开发者桌上的设备,以及将其连接到调试探头的带状线缆,调试探头又通过 USB 线缆连接到开发者的计算机。 计算机运行探头专用软件和 IDE。
在许多情况下,这种设置可以正常工作。 但嵌入式设备需要处理现实世界问题。 有时,我们会使用基于 MCU 的控制板管理高压或危险设备。 有时,这些设备安装在户外。 设备可能会在轮子上移动,也可能漂浮在水面上。 它们甚至可能安装在某个远程位置。 在这些情况下使用线缆进行设置通常不太方便,甚至可能会有危险。
当我开始开发户外设备时,我立即遇到了这个问题。 该如何解决呢? 我盘点了一下手头上的东西,发现了一块 Raspberry Pi 开发板。 我花了几个小时将它设置为无线调试探头,现在它运行得很棒。
- 最简单的无线设置原则
- 哪种开发板更合适?
- Raspberry PI 操作系统和连接
- OpenOCD 安装
- 最终 Raspberry 设置
- 设置示例项目
- 硬件接线
- 启动
- 附加内容 – JTAG 和 RISC-V
最简单的无线设置原则
每个基于 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_base 和 bcm2835gpio_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,它就会显示在横幅上。
现在,我们已经完成了 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 接口。
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 设置页面上的工具链
在撰写这篇博文时(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
本博文英文原作者: