Browse Source

Use AsRef and AsMut to give access to the Probe from the

specific interfaces
master
Dominik Boehi 2 years ago
parent
commit
a2bfd8b371
  1. 93
      cli/src/info.rs
  2. 22
      probe-rs/src/architecture/arm/communication_interface.rs
  3. 16
      probe-rs/src/architecture/riscv/communication_interface.rs
  4. 16
      probe-rs/src/probe/daplink/mod.rs
  5. 22
      probe-rs/src/probe/ftdi/mod.rs
  6. 18
      probe-rs/src/probe/jlink/mod.rs
  7. 45
      probe-rs/src/probe/mod.rs
  8. 18
      probe-rs/src/probe/stlink/mod.rs
  9. 34
      probe-rs/src/session.rs

93
cli/src/info.rs

@ -2,9 +2,10 @@ use crate::{common::open_probe, SharedOptions};
use probe_rs::{
architecture::arm::{
ap::{APClass, BaseaddrFormat, MemoryAP, BASE, BASE2, IDR},
ap::{GenericAP, MemoryAP},
m0::Demcr,
memory::Component,
ApInformation,
},
CoreRegister,
};
@ -37,61 +38,55 @@ pub(crate) fn show_info_of_device(shared_options: &SharedOptions) -> Result<()>
*/
/*
let mut state = ArmCommunicationInterfaceState::new();
let mut interface = probe.get_arm_interface(&mut state)?;
let mut interface = probe.into_arm_interface()?;
if let Some(interface) = &mut interface {
println!("\nAvailable Access Ports:");
for access_port in valid_access_ports(interface) {
let idr = interface.read_ap_register(access_port, IDR::default())?;
println!("{:#x?}", idr);
let num_access_ports = interface.num_access_ports();
if idr.CLASS == APClass::MEMAP {
let access_port: MemoryAP = access_port.into();
for ap_index in 0..num_access_ports {
let access_port = GenericAP::from(ap_index as u8);
let base_register = interface.read_ap_register(access_port, BASE::default())?;
let ap_information = interface.ap_information(access_port).unwrap();
if !base_register.present {
// No debug entry present
println!("No debug entry present.");
continue;
}
//let idr = interface.read_ap_register(access_port, IDR::default())?;
//println!("{:#x?}", idr);
match ap_information {
ApInformation::MemoryAp {
debug_base_address, ..
} => {
let access_port: MemoryAP = access_port.into();
let base_address = *debug_base_address;
let mut memory = interface.memory_interface(access_port)?;
// Enable
// - Data Watchpoint and Trace (DWT)
// - Instrumentation Trace Macrocell (ITM)
// - Embedded Trace Macrocell (ETM)
// - Trace Port Interface Unit (TPIU).
let mut demcr = Demcr(memory.read_word_32(Demcr::ADDRESS)?);
demcr.set_dwtena(true);
memory.write_word_32(Demcr::ADDRESS, demcr.into())?;
let mut baseaddr = if BaseaddrFormat::ADIv5 == base_register.Format {
let base2 = interface.read_ap_register(access_port, BASE2::default())?;
u64::from(base2.BASEADDR) << 32
} else {
0
};
baseaddr |= u64::from(base_register.BASEADDR << 12);
let mut memory = interface.reborrow().memory_interface(access_port)?;
// Enable
// - Data Watchpoint and Trace (DWT)
// - Instrumentation Trace Macrocell (ITM)
// - Embedded Trace Macrocell (ETM)
// - Trace Port Interface Unit (TPIU).
let mut demcr = Demcr(memory.read_word_32(Demcr::ADDRESS)?);
demcr.set_dwtena(true);
memory.write_word_32(Demcr::ADDRESS, demcr.into())?;
let component_table = Component::try_parse(&mut memory, baseaddr as u64);
component_table
.iter()
.for_each(|entry| println!("{:#08x?}", entry));
// let mut reader = crate::memory::romtable::RomTableReader::new(&link_ref, baseaddr as u64);
// for e in reader.entries() {
// if let Ok(e) = e {
// println!("ROM Table Entry: Component @ 0x{:08x}", e.component_addr());
// }
// }
let component_table = Component::try_parse(&mut memory, base_address);
component_table
.iter()
.for_each(|entry| println!("{:#08x?}", entry));
// let mut reader = crate::memory::romtable::RomTableReader::new(&link_ref, baseaddr as u64);
// for e in reader.entries() {
// if let Ok(e) = e {
// println!("ROM Table Entry: Component @ 0x{:08x}", e.component_addr());
// }
// }
}
ApInformation::Other { .. } => println!("Unknown Type of access port"),
}
}
} else {
@ -100,7 +95,5 @@ pub(crate) fn show_info_of_device(shared_options: &SharedOptions) -> Result<()>
)
}
*/
Ok(())
}

22
probe-rs/src/architecture/arm/communication_interface.rs

@ -70,7 +70,7 @@ pub trait Register: Clone + From<u32> + Into<u32> + Sized + Debug {
const NAME: &'static str;
}
pub trait DAPAccess: DebugProbe {
pub trait DAPAccess: DebugProbe + AsRef<dyn DebugProbe> + AsMut<dyn DebugProbe> {
/// Reads the DAP register on the specified port and address
fn read_register(&mut self, port: PortType, addr: u16) -> Result<u32, DebugProbeError>;
@ -124,10 +124,12 @@ pub trait DAPAccess: DebugProbe {
Ok(())
}
fn as_probe(self: Box<Self>) -> Box<dyn DebugProbe>;
fn into_probe(self: Box<Self>) -> Box<dyn DebugProbe>;
}
pub trait ArmProbeInterface: SwoAccess + Debug {
pub trait ArmProbeInterface:
SwoAccess + AsRef<dyn DebugProbe> + AsMut<dyn DebugProbe> + Debug
{
fn memory_interface<'interface>(
&'interface mut self,
access_port: MemoryAP,
@ -222,7 +224,19 @@ impl ArmProbeInterface for ArmCommunicationInterface {
}
fn close(self: Box<Self>) -> Probe {
Probe::from_attached_probe(self.probe.as_probe())
Probe::from_attached_probe(self.probe.into_probe())
}
}
impl<'a> AsRef<dyn DebugProbe + 'a> for ArmCommunicationInterface {
fn as_ref(&self) -> &(dyn DebugProbe + 'a) {
self.probe.as_ref().as_ref()
}
}
impl<'a> AsMut<dyn DebugProbe + 'a> for ArmCommunicationInterface {
fn as_mut(&mut self) -> &mut (dyn DebugProbe + 'a) {
self.probe.as_mut().as_mut()
}
}

16
probe-rs/src/architecture/riscv/communication_interface.rs

@ -9,7 +9,7 @@ use crate::architecture::riscv::*;
use crate::DebugProbeError;
use crate::{MemoryInterface, Probe};
use crate::{probe::JTAGAccess, CoreRegisterAddress, Error as ProbeRsError};
use crate::{probe::JTAGAccess, CoreRegisterAddress, DebugProbe, Error as ProbeRsError};
use std::{
convert::TryInto,
@ -624,7 +624,19 @@ impl<'probe> RiscvCommunicationInterface {
}
pub fn close(self) -> Probe {
Probe::from_attached_probe(self.probe.as_probe())
Probe::from_attached_probe(self.probe.into_probe())
}
}
impl<'a> AsRef<dyn DebugProbe + 'a> for RiscvCommunicationInterface {
fn as_ref(&self) -> &(dyn DebugProbe + 'a) {
self.probe.as_ref().as_ref()
}
}
impl<'a> AsMut<dyn DebugProbe + 'a> for RiscvCommunicationInterface {
fn as_mut(&mut self) -> &mut (dyn DebugProbe + 'a) {
self.probe.as_mut().as_mut()
}
}

16
probe-rs/src/probe/daplink/mod.rs

@ -555,11 +555,23 @@ impl DebugProbe for DAPLink {
true
}
fn has_jtag_interface(&self) -> bool {
fn has_riscv_interface(&self) -> bool {
false
}
}
impl<'a> AsRef<dyn DebugProbe + 'a> for DAPLink {
fn as_ref(&self) -> &(dyn DebugProbe + 'a) {
self
}
}
impl<'a> AsMut<dyn DebugProbe + 'a> for DAPLink {
fn as_mut(&mut self) -> &mut (dyn DebugProbe + 'a) {
self
}
}
impl DAPAccess for DAPLink {
/// Reads the DAP register on the specified port and address.
fn read_register(&mut self, port: PortType, addr: u16) -> Result<u32, DebugProbeError> {
@ -668,7 +680,7 @@ impl DAPAccess for DAPLink {
Ok(())
}
fn as_probe(self: Box<Self>) -> Box<dyn DebugProbe> {
fn into_probe(self: Box<Self>) -> Box<dyn DebugProbe> {
self
}
}

22
probe-rs/src/probe/ftdi/mod.rs

@ -1,11 +1,9 @@
use crate::architecture::{
arm::{DAPAccess, SwoAccess},
riscv::communication_interface::RiscvCommunicationInterface,
arm::SwoAccess, riscv::communication_interface::RiscvCommunicationInterface,
};
use crate::probe::{JTAGAccess, ProbeCreationError};
use crate::{
DebugProbe, DebugProbeError, DebugProbeInfo, DebugProbeSelector, DebugProbeType, Memory,
WireProtocol,
DebugProbe, DebugProbeError, DebugProbeInfo, DebugProbeSelector, DebugProbeType, WireProtocol,
};
use bitvec::order::Lsb0;
use bitvec::vec::BitVec;
@ -527,7 +525,7 @@ impl DebugProbe for FtdiProbe {
Ok(None)
}
fn has_jtag_interface(&self) -> bool {
fn has_riscv_interface(&self) -> bool {
true
}
}
@ -575,7 +573,19 @@ impl JTAGAccess for FtdiProbe {
Ok(r)
}
fn as_probe(self: Box<Self>) -> Box<dyn DebugProbe> {
fn into_probe(self: Box<Self>) -> Box<dyn DebugProbe> {
self
}
}
impl AsRef<dyn DebugProbe> for FtdiProbe {
fn as_ref(&self) -> &(dyn DebugProbe + 'static) {
self
}
}
impl AsMut<dyn DebugProbe> for FtdiProbe {
fn as_mut(&mut self) -> &mut (dyn DebugProbe + 'static) {
self
}
}

18
probe-rs/src/probe/jlink/mod.rs

@ -621,7 +621,7 @@ impl DebugProbe for JLink {
self.supported_protocols.contains(&WireProtocol::Swd)
}
fn has_jtag_interface(&self) -> bool {
fn has_riscv_interface(&self) -> bool {
self.supported_protocols.contains(&WireProtocol::Jtag)
}
}
@ -676,7 +676,19 @@ impl JTAGAccess for JLink {
self.jtag_idle_cycles = idle_cycles;
}
fn as_probe(self: Box<Self>) -> Box<dyn DebugProbe> {
fn into_probe(self: Box<Self>) -> Box<dyn DebugProbe> {
self
}
}
impl<'a> AsRef<dyn DebugProbe + 'a> for JLink {
fn as_ref(&self) -> &(dyn DebugProbe + 'a) {
self
}
}
impl<'a> AsMut<dyn DebugProbe + 'a> for JLink {
fn as_mut(&mut self) -> &mut (dyn DebugProbe + 'a) {
self
}
}
@ -944,7 +956,7 @@ impl DAPAccess for JLink {
Err(DebugProbeError::Timeout)
}
fn as_probe(self: Box<Self>) -> Box<dyn DebugProbe> {
fn into_probe(self: Box<Self>) -> Box<dyn DebugProbe> {
self
}
}

45
probe-rs/src/probe/mod.rs

@ -163,6 +163,13 @@ impl Probe {
}
}
pub fn from_specific_probe(probe: Box<dyn DebugProbe>) -> Self {
Probe {
inner: probe,
attached: false,
}
}
/// Get a list of all debug probes found.
/// This can be used to select the debug probe which
/// should be used.
@ -206,13 +213,6 @@ impl Probe {
))
}
pub fn from_specific_probe(probe: Box<dyn DebugProbe>) -> Self {
Probe {
inner: probe,
attached: false,
}
}
// /// Tries to mass erase a locked nRF52 chip, this process may timeout, if it does, the chip
// /// might be unlocked or not, it is advised to try again if flashing fails
// pub fn nrf_recover(&mut self) -> Result<(), DebugProbeError> {
@ -349,6 +349,8 @@ impl Probe {
self.inner.speed()
}
/// Check if the probe has an interface to
/// debug ARM chips.
pub fn has_arm_interface(&self) -> bool {
self.inner.has_arm_interface()
}
@ -364,8 +366,10 @@ impl Probe {
}
}
pub fn has_jtag_interface(&self) -> bool {
self.inner.has_jtag_interface()
/// Check if the probe has an interface to
/// debug RISCV chips.
pub fn has_riscv_interface(&self) -> bool {
self.inner.has_riscv_interface()
}
pub fn into_riscv_interface(
@ -439,6 +443,7 @@ pub trait DebugProbe: Send + Sync + fmt::Debug {
/// Selects the transport protocol to be used by the debug probe.
fn select_protocol(&mut self, protocol: WireProtocol) -> Result<(), DebugProbeError>;
/// Check if the proble offers an interface to debug ARM chips.
fn has_arm_interface(&self) -> bool;
fn get_arm_interface<'probe>(
@ -449,7 +454,7 @@ pub trait DebugProbe: Send + Sync + fmt::Debug {
self: Box<Self>,
) -> Result<Option<RiscvCommunicationInterface>, DebugProbeError>;
fn has_jtag_interface(&self) -> bool;
fn has_riscv_interface(&self) -> bool;
fn get_interface_swo(&self) -> Option<&dyn SwoAccess>;
@ -671,7 +676,7 @@ impl DebugProbe for FakeProbe {
false
}
fn has_jtag_interface(&self) -> bool {
fn has_riscv_interface(&self) -> bool {
false
}
}
@ -692,7 +697,19 @@ impl DAPAccess for FakeProbe {
Err(DebugProbeError::CommandNotSupportedByProbe)
}
fn as_probe(self: Box<Self>) -> Box<dyn DebugProbe> {
fn into_probe(self: Box<Self>) -> Box<dyn DebugProbe> {
self
}
}
impl<'a> AsRef<dyn DebugProbe + 'a> for FakeProbe {
fn as_ref(&self) -> &(dyn DebugProbe + 'a) {
self
}
}
impl<'a> AsMut<dyn DebugProbe + 'a> for FakeProbe {
fn as_mut(&mut self) -> &mut (dyn DebugProbe + 'a) {
self
}
}
@ -701,7 +718,7 @@ impl DAPAccess for FakeProbe {
///
/// This trait should be implemented by all probes which offer low-level access to
/// the JTAG protocol, i.e. directo control over the bytes sent and received.
pub trait JTAGAccess: std::fmt::Debug {
pub trait JTAGAccess: DebugProbe + AsRef<dyn DebugProbe> + AsMut<dyn DebugProbe> {
fn read_register(&mut self, address: u32, len: u32) -> Result<Vec<u8>, DebugProbeError>;
/// For Riscv, and possibly other interfaces, the JTAG interface has to remain in
@ -722,7 +739,7 @@ pub trait JTAGAccess: std::fmt::Debug {
len: u32,
) -> Result<Vec<u8>, DebugProbeError>;
fn as_probe(self: Box<Self>) -> Box<dyn DebugProbe>;
fn into_probe(self: Box<Self>) -> Box<dyn DebugProbe>;
}
#[derive(PartialEq, Debug, Copy, Clone)]

18
probe-rs/src/probe/stlink/mod.rs

@ -252,7 +252,7 @@ impl DebugProbe for STLink<STLinkUSBDevice> {
true
}
fn has_jtag_interface(&self) -> bool {
fn has_riscv_interface(&self) -> bool {
false
}
}
@ -318,7 +318,19 @@ impl DAPAccess for STLink<STLinkUSBDevice> {
}
}
fn as_probe(self: Box<Self>) -> Box<dyn DebugProbe> {
fn into_probe(self: Box<Self>) -> Box<dyn DebugProbe> {
self
}
}
impl<'a> AsRef<dyn DebugProbe + 'a> for STLink<STLinkUSBDevice> {
fn as_ref(&self) -> &(dyn DebugProbe + 'a) {
self
}
}
impl<'a> AsMut<dyn DebugProbe + 'a> for STLink<STLinkUSBDevice> {
fn as_mut(&mut self) -> &mut (dyn DebugProbe + 'a) {
self
}
}
@ -908,7 +920,7 @@ mod test {
_read_data: &mut [u8],
_timeout: std::time::Duration,
) -> Result<usize, DebugProbeError> {
todo!()
unimplemented!("Not implemented for MockUSB")
}
}

34
probe-rs/src/session.rs

@ -14,14 +14,14 @@ use crate::config::{
ChipInfo, MemoryRegion, RawFlashAlgorithm, RegistryError, Target, TargetSelector,
};
use crate::core::{Architecture, CoreState, SpecificCoreState};
use crate::{AttachMethod, Core, CoreType, Error, Probe};
use crate::{AttachMethod, Core, CoreType, DebugProbe, Error, Probe};
use anyhow::anyhow;
use std::time::Duration;
#[derive(Debug)]
pub struct Session {
target: Target,
interface_state: ArchitectureInterface,
interface: ArchitectureInterface,
cores: Vec<(SpecificCoreState, CoreState)>,
}
@ -55,13 +55,14 @@ impl ArchitectureInterface {
ArchitectureInterface::Riscv(state) => core.attach_riscv(core_state, state),
}
}
}
fn get_probe(&self) -> &Probe {
todo!()
}
fn get_probe_mut(&mut self) -> &mut Probe {
todo!()
impl<'a> AsMut<dyn DebugProbe + 'a> for ArchitectureInterface {
fn as_mut(&mut self) -> &mut (dyn DebugProbe + 'a) {
match self {
ArchitectureInterface::Arm(interface) => interface.as_mut().as_mut(),
ArchitectureInterface::Riscv(interface) => interface.as_mut(),
}
}
}
@ -85,7 +86,7 @@ impl Session {
let mut session = Session {
target,
interface_state: ArchitectureInterface::Arm(interface.unwrap()),
interface: ArchitectureInterface::Arm(interface.unwrap()),
cores: vec![core],
};
@ -97,10 +98,7 @@ impl Session {
reset_catch_set(&mut session.core(0)?)?;
// Deassert the reset pin
session
.interface_state
.get_probe_mut()
.target_reset_deassert()?;
session.interface.as_mut().target_reset_deassert()?;
// Wait for the core to be halted
let mut core = session.core(0)?;
@ -124,7 +122,7 @@ impl Session {
let mut session = Session {
target,
interface_state: ArchitectureInterface::Riscv(interface.unwrap()),
interface: ArchitectureInterface::Riscv(interface.unwrap()),
cores: vec![core],
};
@ -171,7 +169,7 @@ impl Session {
.get_mut(n)
.ok_or_else(|| Error::CoreNotFound(n))?;
self.interface_state.attach(core, core_state)
self.interface.attach(core, core_state)
}
/// Returns a list of the flash algotithms on the target.
@ -187,7 +185,7 @@ impl Session {
pub fn get_arm_interface<'session>(
&'session mut self,
) -> Result<&'session mut Box<dyn ArmProbeInterface>, Error> {
let interface = match &mut self.interface_state {
let interface = match &mut self.interface {
ArchitectureInterface::Arm(state) => state,
_ => return Err(Error::ArchitectureRequired(&["ARMv7", "ARMv8"])),
};
@ -276,7 +274,7 @@ impl Session {
/// Return the `Architecture` of the currently connected chip.
pub fn architecture(&self) -> Architecture {
match self.interface_state {
match self.interface {
ArchitectureInterface::Arm(_) => Architecture::Arm,
ArchitectureInterface::Riscv(_) => Architecture::Riscv,
}
@ -341,7 +339,7 @@ fn get_target_from_selector(
}
}
if found_chip.is_none() && probe.as_ref().unwrap().has_jtag_interface() {
if found_chip.is_none() && probe.as_ref().unwrap().has_riscv_interface() {
let interface = probe.take().unwrap().into_riscv_interface()?;
if let Some(mut interface) = interface {

Loading…
Cancel
Save