Skip to content

Commit

Permalink
add configurable cycle delay and maximum time for probe reappearing
Browse files Browse the repository at this point in the history
  • Loading branch information
tarfu committed Oct 3, 2023
1 parent 5277555 commit 1e71305
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 8 deletions.
6 changes: 5 additions & 1 deletion teleprobe/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ pub struct Target {
pub speed: Option<u32>,
pub up: bool,
#[cfg(feature = "power_reset")]
pub power_reset: bool
pub power_reset: bool,
#[cfg(feature = "power_reset")]
pub cycle_delay_seconds: f64,
#[cfg(feature = "power_reset")]
pub max_settle_time_millis: u64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down
16 changes: 15 additions & 1 deletion teleprobe/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,21 @@ pub struct Target {
pub speed: Option<u32>,
#[cfg(feature = "power_reset")]
#[serde(default)]
pub power_reset: bool
pub power_reset: bool,
#[cfg(feature = "power_reset")]
#[serde(default = "default_cycle_delay_seconds")]
pub cycle_delay_seconds: f64,
#[cfg(feature = "power_reset")]
#[serde(default = "default_max_settle_time_millis")]
pub max_settle_time_millis: u64,
}

fn default_cycle_delay_seconds() -> f64 {
1.0
}

fn default_max_settle_time_millis() -> u64 {
2000
}

#[derive(Clone, Serialize, Deserialize)]
Expand Down
39 changes: 33 additions & 6 deletions teleprobe/src/probe/mod.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
mod specifier;

use std::fmt;
use std::process::Command;
use std::sync::Mutex;
use std::time::Instant;
use anyhow::{bail, Result};
use clap::Parser;
use probe_rs::{DebugProbeInfo, MemoryInterface, Permissions, Probe, Session};
pub use specifier::ProbeSpecifier;

static UHUBCTL_MUTEX: Mutex<()> = Mutex::new(());

const SETTLE_REPROBE_INTERVAL: std::time::Duration = std::time::Duration::from_millis(100);

#[derive(Clone, Parser)]
pub struct Opts {
/// The probe to use (specified by eg. `VID:PID`, `VID:PID:Serial`, or just `Serial`).
Expand All @@ -31,6 +35,14 @@ pub struct Opts {
#[cfg(feature = "power_reset")]
#[clap(long)]
pub power_reset: bool,

#[cfg(feature = "power_reset")]
#[clap(long, default_value = "1")]
pub cycle_delay_seconds: f64,

#[cfg(feature = "power_reset")]
#[clap(long, default_value = "2000")]
pub max_settle_time_millis: u64,
}

pub fn list() -> Result<()> {
Expand Down Expand Up @@ -59,15 +71,29 @@ pub fn connect(opts: &Opts) -> Result<Session> {
#[cfg(feature = "power_reset")]
{
if opts.power_reset {
if probes[0].serial_number.is_none(){
if probes[0].serial_number.is_none() {
bail!("power reset requires a serial number");
}
log::debug!("probe power reset");
if let Err(err) = power_reset(&probes[0].serial_number.as_ref().unwrap()){
if let Err(err) = power_reset(&probes[0].serial_number.as_ref().unwrap(), 0.5) {
log::warn!("power reset failed for: {}", err);
}


let end = Instant::now() + std::time::Duration::from_millis(opts.max_settle_time_millis);
probes = vec![];
while Instant::now() < end && probes.is_empty() {
std::thread::sleep(SETTLE_REPROBE_INTERVAL);
probes = match get_probe(&opts) {
Ok(p) => {p}
Err(_) => {probes}
}
}
if probes.is_empty() {
bail!("Probe not reappeared after power reset")
}

}
probes = get_probe(&opts)?;
}


Expand Down Expand Up @@ -170,11 +196,13 @@ pub fn probes_filter(probes: &[DebugProbeInfo], selector: &ProbeSpecifier) -> Ve
}

#[cfg(feature = "power_reset")]
fn power_reset(probe_serial: &str) -> Result<()> {
fn power_reset(probe_serial: &str, cycle_delay_seconds: f64) -> Result<()> {
let _guard = UHUBCTL_MUTEX.lock();
let output = Command::new("uhubctl")
.arg("-a")
.arg("cycle")
.arg("-d")
.arg(format!("{:.2}", cycle_delay_seconds))
.arg("-s")
.arg(probe_serial)
.output();
Expand All @@ -183,10 +211,9 @@ fn power_reset(probe_serial: &str) -> Result<()> {
match output {
Ok(output) => {
if output.status.success() {
std::thread::sleep(std::time::Duration::from_millis(1000));
Ok(())
} else {
bail!("uhubctl failed for serial \'{}\': {}", probe_serial, String::from_utf8_lossy(&output.stderr))
bail!("uhubctl failed for serial \'{}\' with delay {}: {}", cycle_delay_seconds, probe_serial, String::from_utf8_lossy(&output.stderr))
}
}
Err(e) => bail!("uhubctl failed: {}", e)
Expand Down
8 changes: 8 additions & 0 deletions teleprobe/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,10 @@ async fn handle_run(name: String, args: RunArgs, elf: Bytes, cx: Arc<Mutex<Conte
speed: target.speed,
#[cfg(feature = "power_reset")]
power_reset: target.power_reset,
#[cfg(feature = "power_reset")]
cycle_delay_seconds: target.cycle_delay_seconds,
#[cfg(feature = "power_reset")]
max_settle_time_millis: target.max_settle_time_millis,
};

let timeout = {
Expand Down Expand Up @@ -222,6 +226,10 @@ fn targets(cx: Arc<Mutex<Context>>) -> api::TargetList {
up: is_up,
#[cfg(feature = "power_reset")]
power_reset: target.power_reset,
#[cfg(feature = "power_reset")]
cycle_delay_seconds: target.cycle_delay_seconds,
#[cfg(feature = "power_reset")]
max_settle_time_millis: target.max_settle_time_millis,
});
}

Expand Down

0 comments on commit 1e71305

Please sign in to comment.