Skip to content
This repository has been archived by the owner on Jan 30, 2024. It is now read-only.

Allow listing and selecting probe #49

Merged
merged 1 commit into from
Sep 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ To support multiple devices, or permit overriding default behavior, you may pref
`${PROBE_RUN_CHIP}` environment variable, and set `runner` (or
`CARGO_TARGET_${TARGET_ARCH}_RUNNER`) to `probe-run`.

If you have several probes connected, you can specify which one to use by adding
the --probe option to the `runner` or setting the `${PROBE_RUN_PROBE}` environment
variable with a value containing either `${VID}:${PID}` or `${VID}:${PID}:${SERIAL}`:

```console
probe-run --probe '0483:3748' --chip ${PROBE_RUN_CHIP}
PROBE_RUN_PROBE='1366:0101:123456' cargo run
```

To list all connected probes, run `probe-run --list-probes`.

2. Enable debug info

Next check that debug info is enabled for all profiles.
Expand Down
55 changes: 52 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use object::{
use probe_rs::config::{registry, MemoryRegion};
use probe_rs::{
flashing::{self, Format},
Core, CoreRegisterAddress, MemoryInterface, Probe, Session,
Core, CoreRegisterAddress, DebugProbeInfo, DebugProbeSelector, MemoryInterface, Probe, Session,
};
use probe_rs_rtt::{Rtt, ScanRegion, UpChannel};
use structopt::StructOpt;
Expand All @@ -50,17 +50,25 @@ struct Opts {
#[structopt(long)]
list_chips: bool,

/// Lists all the connected probes and exit.
#[structopt(long)]
list_probes: bool,

/// Enable defmt decoding.
#[cfg(feature = "defmt")]
#[structopt(long, conflicts_with = "no_flash")]
defmt: bool,

/// The chip to program.
#[structopt(long, required_unless("list-chips"), env = "PROBE_RUN_CHIP")]
#[structopt(long, required_unless_one(&["list-chips", "list-probes"]), env = "PROBE_RUN_CHIP")]
chip: Option<String>,

/// The probe to use (eg. VID:PID or VID:PID:Serial).
#[structopt(long, env = "PROBE_RUN_PROBE")]
probe: Option<String>,

/// Path to an ELF firmware file.
#[structopt(name = "ELF", parse(from_os_str), required_unless("list-chips"))]
#[structopt(name = "ELF", parse(from_os_str), required_unless_one(&["list-chips", "list-probes"]))]
elf: Option<PathBuf>,

/// Skip writing the application binary to flash.
Expand All @@ -73,6 +81,10 @@ fn notmain() -> Result<i32, anyhow::Error> {

let opts: Opts = Opts::from_args();

if opts.list_probes {
return print_probes();
}

if opts.list_chips {
return print_chips();
}
Expand Down Expand Up @@ -217,10 +229,19 @@ fn notmain() -> Result<i32, anyhow::Error> {
log::debug!("initial registers: {:x?}", registers);

let probes = Probe::list_all();
let probes = if let Some(probe_opt) = opts.probe.as_deref() {
let selector = probe_opt.try_into()?;
probes_filter(&probes, &selector)
} else {
probes
};
if probes.is_empty() {
bail!("no probe was found")
}
log::debug!("found {} probes", probes.len());
if probes.len() > 1 {
bail!("more than one probe found; use --probe to specify which one to use");
}
let probe = probes[0].open()?;
log::info!("opened probe");
let mut sess = probe.attach(target)?;
Expand Down Expand Up @@ -624,6 +645,34 @@ fn backtrace(
Ok(top_exception)
}

fn probes_filter(probes: &[DebugProbeInfo], selector: &DebugProbeSelector) -> Vec<DebugProbeInfo> {
probes
.iter()
.filter(|&p| {
p.vendor_id == selector.vendor_id
&& p.product_id == selector.product_id
&& (selector.serial_number == None || p.serial_number == selector.serial_number)
})
.map(|p| p.clone())
.collect()
}

fn print_probes() -> Result<i32, anyhow::Error> {
let probes = Probe::list_all();

if !probes.is_empty() {
println!("The following devices were found:");
probes
.iter()
.enumerate()
.for_each(|(num, link)| println!("[{}]: {:?}", num, link));
} else {
println!("No devices were found.");
}

Ok(0)
}

fn print_chips() -> Result<i32, anyhow::Error> {
let registry = registry::families().expect("Could not retrieve chip family registry");
for chip_family in registry {
Expand Down