#run #probe #knurling #backtrace #devices #programs #cargo-runner

no-std app probe-run

像本地程序一样运行嵌入式程序

28 个版本

0.3.11 2024年1月30日
0.3.10 2023年8月1日
0.3.9 2023年5月5日
0.3.7 2023年3月29日
0.1.7 2020年11月26日

#1986 in 嵌入式开发

Download history 63/week @ 2024-04-06 64/week @ 2024-04-13 44/week @ 2024-04-20 46/week @ 2024-04-27 34/week @ 2024-05-04 28/week @ 2024-05-11 55/week @ 2024-05-18 36/week @ 2024-05-25 42/week @ 2024-06-01 50/week @ 2024-06-08 60/week @ 2024-06-15 52/week @ 2024-06-22 37/week @ 2024-06-29 34/week @ 2024-07-06 30/week @ 2024-07-13 9/week @ 2024-07-20

每月116 次下载

MIT/Apache

2.5MB
2.5K SLoC

包含 (ELF exe/lib, 1.5MB) tests/test_elfs/levels-with-timestamp, (ELF exe/lib, 1MB) tests/test_elfs/hello-raw, (ELF exe/lib, 1MB) tests/test_elfs/hello-rzcobs, (ELF exe/lib, 1.5MB) tests/test_elfs/levels-rzcobs, (ELF exe/lib, 1MB) tests/test_elfs/overflow-no-flip-link, (ELF exe/lib, 1MB) tests/test_elfs/overflow-rzcobs 和更多

⚠️ 截至2023年11月10日 probe-run 处于维护模式。我们建议 everyone 切换到 probe-rs。阅读以下文章了解为什么以及如何迁移: https://ferrous-systems.com/blog/probe-run-deprecation/

probe-run

像本地程序一样运行嵌入式程序

probe-run 是一个自定义的 Cargo 运行器,它可以在嵌入式设备上透明地运行 Rust 固件。

probe-runprobe-rs 驱动,因此支持 probe-rs 支持的所有设备和探头。

功能

  • 作为 Cargo 运行器,集成到 cargo run
  • 显示通过 RTT 从设备流出的程序输出。
  • 退出固件并在硬件断点(例如 bkpt)、Rust 崩溃和不可恢复的硬件异常(例如 HardFault)上打印堆栈跟踪。

安装

要安装 probe-run,请使用 cargo install probe-run

在 Linux 上,您可能需要在安装 probe-run 之前从您的软件包管理器安装 libudevlibusb

# ubuntu
$ sudo apt install -y libusb-1.0-0-dev libudev-dev

# fedora
$ sudo dnf install -y libusbx-devel systemd-devel

使用最新的 probe-rs

probe-runprobe-rs 库继承了设备支持。如果你的目标芯片没有出现在 probe-run --list-chips 的输出中,可能是以下原因:

  1. 最新的 git 版本的 probe-rs 支持你的芯片,但 crates.io 上的最新版本不支持。你可以尝试使用最新的 probe-rs 版本构建 probe-run;请参阅下面的说明。
  2. probe-rs 还不支持该设备。你需要在 probe-rs 问题跟踪器 中请求支持。

要针对最新的 git 版本 probe-rs 构建 probe-run 并安装它,请按照以下步骤操作:

$ # clone the latest version of probe-run; line below uses version v0.3.3
$ git clone --depth 1 --branch v0.3.3 https://github.com/knurling-rs/probe-run

$ cd probe-run

$ # modify Cargo.toml to use the git version of probe-rs
$ # append these lines to Cargo.toml; command below is UNIX-y
$ cat >> Cargo.toml << STOP
[patch.crates-io]
probe-rs = { git = "https://github.com/probe-rs/probe-rs" }
STOP

$ # install this patched version
$ cargo install --path .

请注意,你可能需要修改 probe-rs-rtt 和/或 probe-run 自身才能编译 probe-run。由于我们只支持未修改的 Cargo.toml 中的 crates.io 版本的 probe-rs,因此我们无法在此情况下提供进一步的帮助。

设置

注意 对于 Cargo 项目,我们建议从 app-template 开始。

1. 设置 Cargo 运行器

使用 probe-run 的推荐方法是将其设置为应用程序的 Cargo 运行器。

将以下两行添加到你的 Cargo 配置文件(.cargo/config.toml)中,并设置特定于目标芯片的 --chip 值。在这种情况下,对于 nRF52840,是 nRF52840_xxAA

[target.'cfg(all(target_arch = "arm", target_os = "none"))']
runner = "probe-run --chip nRF52840_xxAA"
#                          ^^^^^^^^^^^^^

要列出所有支持的芯片,请运行 probe-run --list-chips

1.1 环境变量

为了支持多个设备或允许覆盖默认行为,你可能更喜欢以下操作:

  1. 设置环境变量 ${PROBE_RUN_CHIP},并将 runner(或 CARGO_TARGET_${TARGET_ARCH}_RUNNER)设置为 probe-run
  2. 设置 runner(或 CARGO_TARGET_${TARGET_ARCH}_RUNNER)到 probe-run
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
runner = "probe-run"

1.2 多个探针

如果你连接了多个探针,你可以通过在 runner 中添加 --probe 选项或设置环境变量 ${PROBE_RUN_PROBE} 来指定要使用哪个探针,该环境变量的值包含以下内容之一:${VID}:${PID}${VID}:${PID}:${SERIAL}

// --probe
$ probe-run --probe '0483:3748' --chip ${PROBE_RUN_CHIP}

// PROBE_RUN_PROBE
$ PROBE_RUN_PROBE='1366:0101:123456' cargo run

要列出所有连接的探头,请运行 probe-run --list-probes

2. 启用调试信息

接下来,检查是否为所有配置文件启用了调试信息。如果您正在使用 cortex-m-quickstart 模板,则已满足此要求。如果不是,请检查或添加以下行到 Cargo.toml

[dependencies]
...
panic-probe = { version = "0.2", features = ["print-rtt"] }

# Cargo.toml
[profile.dev]
debug = 1 # default is `true`; not needed if not already overridden

[profile.release]
debug = 1 # default is `false`; using `true` is also OK as symbols reside on the host, not the target

3. 注意旧依赖项

cortex-m 依赖项必须是版本 0.6.3 或更高版本。不支持旧版本。检查您的 Cargo.lock 文件以确定是否有旧版本。如果 Cargo.lock 文件中出现了旧版本,请运行 cargo update 命令来更新 cortex-m 依赖项。

4. 运行

一切就绪。现在您可以使用 cargo run 命令运行您的固件。例如,

use cortex_m::asm;
use cortex_m_rt::entry;
use panic_probe as _;
use rtt_target::rprintln;

#[entry]
fn main() -> ! {
    rtt_init_print!(); // You may prefer to initialize another way
    rprintln!("Hello, world!");
    loop { asm::bkpt() }
}

将输出

$ cargo run --bin hello
    Finished dev [unoptimized + debuginfo] target(s) in 0.07s
     Running `probe-run --chip nRF52840_xxAA target/thumbv7em-none-eabihf/debug/hello`
  (HOST) INFO  flashing program (30.22 KiB)
  (HOST) INFO  success!
────────────────────────────────────────────────────────────────────────────────
INFO:hello -- Hello, world!
────────────────────────────────────────────────────────────────────────────────
  (HOST) INFO  exiting because the device halted.
To see the backtrace at the exit point repeat this run with
`probe-run --chip nRF52840_xxAA target/thumbv7em-none-eabihf/debug/hello --force-backtrace`

堆栈回溯

当设备引发硬故障异常,例如恐慌或栈溢出时,probe-run 将打印回溯并退出,退出代码非零。

此回溯遵循从 std::panic! 获取的 std 回溯的格式,但包括 <异常入口> 行来指示异常/中断发生的位置。

#![no_main]
#![no_std]

use cortex_m::asm;
#[entry]
fn main() -> ! {
    // trigger a hard fault exception with the UDF instruction.
    asm::udf()
}
    Finished dev [optimized + debuginfo] target(s) in 0.04s
     Running `probe-run --chip nRF52840_xxAA target/thumbv7em-none-eabihf/debug/hard-fault`
  (HOST) INFO  flashing program (30.08 KiB)
  (HOST) INFO  success!
────────────────────────────────────────────────────────────────────────────────
stack backtrace:
   0: HardFaultTrampoline
      <exception entry>
   1: __udf
   2: cortex_m::asm::udf
        at /<...>/cortex-m-0.6.4/src/asm.rs:104
   3: panic::__cortex_m_rt_main
        at src/bin/hard-fault.rs:12
   4: main
        at src/bin/hard-fault.rs:8
   5: ResetTrampoline
        at /<...>3/cortex-m-rt-0.6.13/src/lib.rs:547
   6: Reset
        at /<...>/cortex-m-rt-0.6.13/src/lib.rs:550

如果我们查看 cargo run 命令输出的返回码,我们会看到它是非零的

$ echo $?
134

⚠️ 注意 当您使用 probe-run 运行应用程序时,HardFault 处理器(默认或用户定义)将 不会 执行。

回溯选项

--backtrace

--backtrace 标志是可选的,可以传递以下值

  • --backtrace=always - 强制回溯(如果您希望在程序成功运行结束后看到回溯)
  • --backtrace=never - 禁用回溯
  • --backtrace=auto - 默认,如果程序崩溃或栈溢出,则显示回溯

按照这种方式运行(强制回溯的示例)

$ cargo run --bin hello --backtrace=always

--backtrace-limit

--backtrace-limit 标志是可选的,默认值为 50。可以设置任何数字。

--backtrace-limit=0 是接受的,表示 "无限制"。

要显示显示 5 个框架的缩短回溯,请运行

$ cargo run --bin panic --backtrace-limit=5

注意:如果设置了 --backtrace=never,则设置 --backtrace-limit 无效。

故障排除

"错误:未找到探头。"

首先,检查您的硬件

  • 确保您的开发板具有板载的 硬件 调试器。如果没有,您需要一个与 JTAG 或 SWD 接口一起工作的独立硬件调试器。一些板子有 USB micro-B 或 Type-C 连接器,但只配备了 引导加载程序 固件,允许您通过 USB 大容量存储加载新程序,而不是具有专用的板载 JTAG 或 SWD 到 USB 芯片;probe-run 不能与这些板一起使用。
  • 确保它连接到您的开发板上的正确端口
  • 确保您使用了 数据 线缆 - 一些线缆仅用于充电!如果有疑问,请尝试使用不同的线缆。
  • 确保已安装调试器的正确驱动程序(st-link 或 j-link)

如果这不能解决问题,请尝试以下操作

[仅限 Linux] udev 规则尚未设置

检查您的设备是否显示在 lsusb

$ lsusb
Bus 001 Device 008: ID 1366:1015 SEGGER J-Link

如果您的设备显示如下示例,请跳转到下一个故障排除部分

如果它没有显示,您需要授予系统以非root用户身份访问设备的权限,以便 probe-run 能够找到您的设备。

为了授予这些权限,您需要添加一组新的udev规则。

要了解如何为nRF52840开发套件执行此操作,请参阅我们嵌入式培训材料中的安装说明

之后,您的设备应该在 probe-run --list-probes 中显示,类似于这样

$ probe-run --list-probes
The following devices were found:
[0]: J-Link (J-Link) (VID: 1366, PID: 1015, Serial: <redacted>, JLink)

没有外部或板载调试器存在

要使用 probe-run,您需要一个位于您的PC和微控制器之间的“探针”(也称为“调试器”)。

大多数开发板,尤其是较大的开发板,都有“板载”探针:如果您的开发板产品描述中提到了类似J-Link或ST-Link的板载调试器,那么您就可以开始了。使用这些板,您只需要使用USB线将PC连接到开发板,然后您就可以使用 probe-run 了!

如果您的开发板不是这种情况,请检查数据表以确认是否暴露了SWD或JTAG引脚。如果它们是暴露的,您可以将“独立”探针设备连接到微控制器,然后通过USB将探针连接到您的PC。一些独立探针的例子是:ST-Link和J-Link。

请注意,如果您的板没有预装用于插入调试器的接头,这可能需要一些焊接。

错误:RTT通道0未找到

这可能会显示为 Error: RTT 控制块未在目标内存.

您的代码或您使用的库(例如RTIC)可能在空闲时将CPU置于睡眠状态。您可以通过代替睡眠进行忙碌循环来验证这是否是问题。当使用RTIC时,您可以通过向您的应用程序添加空闲处理程序来实现这一点

#[idle]
fn idle(_ctx: idle::Context) -> ! {
     loop {}
}

假设您仍想睡眠以节省电力,您需要配置微控制器,以便即使在CPU睡眠时,RTT也能得到处理。如何执行此操作因微控制器而异。

在运行RTIC的STM32G0上,可以通过修改您的init函数来设置 dmaen 位在 RCC.ahbenr 上。例如。

#[init]
fn init(ctx: init::Context) -> init::LateResources {
     ctx.device.RCC.ahbenr.write(|w| w.dmaen().set_bit());
     ...
}

defmt版本不匹配

最终用户

按照错误消息中的说明解决不匹配。

开发者

如果您正在使用 probe-run 进行黑客攻击,您可以在运行时将 PROBE_RUN_IGNORE_VERSION 环境变量设置为 true1 以禁用版本检查。

开发者信息

运行您本地修改的 probe-run

为了方便复制粘贴,这里有一个示例,说明如何尝试您的本地 probe_run 修改。

$ cd probe-run/
$ PROBE_RUN_IGNORE_VERSION=1 cargo run -- --chip nRF52840_xxAA --backtrace-limit=10 hello
  ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ                                   ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ ˆˆˆˆˆ
  environment variables                                        extra flags             binary to be
  (optional)                                                   (optional)              flashed & run

运行快照测试

在打开PR之前,请尽可能在 tests 中运行快照测试,以检查您的更改是否以意外的方式改变了probe-run。

您可以通过连接nRF52840开发套件并运行以下操作来实现此操作

$ cargo test -- --ignored

支持我们

probe-runKnurling项目的一部分,这是Ferrous Systems努力改进用于开发嵌入式系统工具的工作。

如果您认为我们的工作很有用,请考虑通过GitHub Sponsors来赞助。

许可证

许可协议为以下之一

任选其一。

贡献

除非您明确说明,否则根据 Apache-2.0 许可证定义,您有意提交并包含在作品中的任何贡献,都将按照上述许可证授权,不附加任何额外的条款或条件。

依赖项

~25–39MB
~520K SLoC