Skip to content

Commit

Permalink
Update RTT collector
Browse files Browse the repository at this point in the history
  • Loading branch information
jonlamb-gh committed Mar 29, 2024
1 parent e615a3f commit f72935b
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 12 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "modality-trace-recorder-plugin"
version = "0.9.0"
version = "0.10.0"
edition = "2021"
authors = ["Jon Lamb <jon@auxon.io>"]
description = "A Modality reflector plugin suite and ingest adapter library for Percepio's TraceRecorder data"
Expand Down
69 changes: 59 additions & 10 deletions src/bin/rtt_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use modality_trace_recorder_plugin::{
use probe_rs::{
config::MemoryRegion,
probe::{list::Lister, DebugProbeSelector, WireProtocol},
rtt::{Rtt, UpChannel},
Core, Permissions, Session,
rtt::{Rtt, ScanRegion, UpChannel},
Core, Permissions, Session, VectorCatchCondition,
};
use std::{
fs, io,
Expand Down Expand Up @@ -41,6 +41,14 @@ struct Opts {
)]
pub attach_timeout: Option<humantime::Duration>,

/// Use the provided RTT control block address instead of scanning the target memory for it.
#[clap(
long,
name = "control-block-address",
help_heading = "STREAMING PORT CONFIGURATION"
)]
pub control_block_address: Option<u32>,

/// Disable sending control plane commands to the target.
/// By default, CMD_SET_ACTIVE is sent on startup and shutdown to
/// start and stop tracing on the target.
Expand Down Expand Up @@ -167,6 +175,9 @@ async fn do_main() -> Result<(), Box<dyn std::error::Error>> {
if let Some(to) = opts.attach_timeout {
trc_cfg.plugin.rtt_collector.attach_timeout = Some(to.into());
}
if let Some(addr) = opts.control_block_address {
trc_cfg.plugin.rtt_collector.control_block_address = addr.into();
}
if opts.disable_control_plane {
trc_cfg.plugin.rtt_collector.disable_control_plane = true;
}
Expand Down Expand Up @@ -231,30 +242,54 @@ async fn do_main() -> Result<(), Box<dyn std::error::Error>> {
probe.select_protocol(trc_cfg.plugin.rtt_collector.protocol)?;
probe.set_speed(trc_cfg.plugin.rtt_collector.speed)?;

if trc_cfg.plugin.rtt_collector.reset {
debug!("Reseting target");
probe.target_reset_assert()?;
probe.target_reset_deassert()?;
}

debug!(
chip = chip,
core = trc_cfg.plugin.rtt_collector.core,
"Attaching to chip"
);
let mut session = probe.attach(chip, Permissions::default())?;

let rtt_scan_regions = session.target().rtt_scan_regions.clone();
let mut rtt_scan_region = if rtt_scan_regions.is_empty() {
ScanRegion::Ram
} else {
ScanRegion::Ranges(rtt_scan_regions)
};
if let Some(user_provided_addr) = trc_cfg.plugin.rtt_collector.control_block_address {
debug!(
rtt_addr = user_provided_addr,
"Using explicit RTT control block address"
);
rtt_scan_region = ScanRegion::Exact(user_provided_addr);
}

let memory_map = session.target().memory_map.clone();
let mut core = session.core(trc_cfg.plugin.rtt_collector.core)?;

if trc_cfg.plugin.rtt_collector.reset {
debug!("Reset and halt core");
core.reset_and_halt(Duration::from_millis(100))?;
}

// Disable any previous vector catching (i.e. user just ran probe-rs run or a debugger)
core.disable_vector_catch(VectorCatchCondition::All)?;
core.clear_all_hw_breakpoints()?;

let mut rtt = match trc_cfg.plugin.rtt_collector.attach_timeout {
Some(to) if !to.0.is_zero() => attach_retry_loop(&mut core, &memory_map, to.0)?,
Some(to) if !to.0.is_zero() => {
attach_retry_loop(&mut core, &memory_map, &rtt_scan_region, to.0)?
}
_ => {
debug!("Attaching to RTT");
Rtt::attach(&mut core, &memory_map)?
}
};

if trc_cfg.plugin.rtt_collector.reset {
debug!("Run core");
core.run()?;
}

let up_channel = rtt
.up_channels()
.take(trc_cfg.plugin.rtt_collector.up_channel)
Expand Down Expand Up @@ -350,13 +385,14 @@ async fn do_main() -> Result<(), Box<dyn std::error::Error>> {
fn attach_retry_loop(
core: &mut Core,
memory_map: &[MemoryRegion],
scan_region: &ScanRegion,
timeout: humantime::Duration,
) -> Result<Rtt, Error> {
debug!(timeout = %timeout, "Attaching to RTT");
let timeout: Duration = timeout.into();
let start = Instant::now();
while Instant::now().duration_since(start) <= timeout {
match Rtt::attach(core, memory_map) {
match Rtt::attach_region(core, memory_map, scan_region) {
Ok(rtt) => return Ok(rtt),
Err(e) => {
if matches!(e, probe_rs::rtt::Error::ControlBlockNotFound) {
Expand Down Expand Up @@ -428,6 +464,19 @@ impl io::Read for TrcRttReader {
.read(&mut core, &mut buf[bytes_fulfilled..])
.map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))?;
bytes_fulfilled += rtt_bytes_read;

// NOTE: this is what probe-rs does
//
// Poll RTT with a frequency of 10 Hz if we do not receive any new data.
// Once we receive new data, we bump the frequency to 1kHz.
//
// If the polling frequency is too high, the USB connection to the probe
// can become unstable. Hence we only pull as little as necessary.
if rtt_bytes_read != 0 {
std::thread::sleep(Duration::from_millis(1));
} else {
std::thread::sleep(Duration::from_millis(100));
}
}

Ok(bytes_fulfilled)
Expand Down
2 changes: 2 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ impl Default for ItmCollectorConfig {
#[serde(rename_all = "kebab-case", default)]
pub struct RttCollectorConfig {
pub attach_timeout: Option<HumanTime>,
pub control_block_address: Option<u32>,
pub disable_control_plane: bool,
pub restart: bool,
pub up_channel: usize,
Expand All @@ -145,6 +146,7 @@ impl Default for RttCollectorConfig {
fn default() -> Self {
Self {
attach_timeout: None,
control_block_address: None,
disable_control_plane: false,
restart: false,
up_channel: Self::DEFAULT_UP_CHANNEL,
Expand Down

0 comments on commit f72935b

Please sign in to comment.