1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
//! An [`EmbeddedProfiler`] implementation that toggles the given pin.
//!
//! This profiler is geared towards systems that have very limited resources and
//! just want to profile a function via an oscilloscope or logic analyzer. The
//! analyzer takes any GPIO that implements the
//! [`OutputPin`](embedded_hal::digital::v2::OutputPin) trait
//!
//! ## Example Usage
//!
//!```no_run
//! # struct MyPin;
//! # type MyPinError = ();
//! # impl embedded_hal::digital::v2::OutputPin for MyPin { type Error = ();
//! # fn set_low(&mut self) -> Result<(), Self::Error> { Ok(()) }
//! # fn set_high(&mut self) -> Result<(), Self::Error> { Ok(()) } }
//! # let pin = MyPin;
//! let ep_pin_toggle = cortex_m::singleton!(: ep_pin_toggle::EPPinToggle<MyPinError, MyPin> =
//! ep_pin_toggle::EPPinToggle::new(pin)).unwrap();
//! unsafe {
//! embedded_profiling::set_profiler(ep_pin_toggle).unwrap();
//! }
//! // (...)
//! embedded_profiling::profile("print_profile", || println!("Hello, world"));
//! ```
//!
//! ## Features
//!
//! ### `proc-macros`
//!
//! enables the `proc-macros` feature in [`embedded-profiling`](embedded_profiling). Enables
//! the [`embedded_profiling::profile_function`] procedural macro.
//!
//! [`embedded_profiling::profile_function`]: https://docs.rs/embedded-profiling/latest/embedded_profiling/attr.profile_function.html
#![cfg_attr(not(test), no_std)]
use core::cell::RefCell;
use embedded_hal::digital::v2::OutputPin;
use embedded_profiling::{EPInstant, EmbeddedProfiler};
/// Implements [`EmbeddedProfiler`] by toggling the given pin.
pub struct EPPinToggle<E, P>
where
P: OutputPin<Error = E>,
{
pin: RefCell<P>,
}
impl<E, P> EPPinToggle<E, P>
where
P: OutputPin<Error = E>,
{
/// Creates a new [`EPPinToggle`] with the given `pin`.
pub fn new(pin: P) -> Self {
Self {
pin: RefCell::new(pin),
}
}
/// Consumes [`EPPinToggle`], returning the `pin`.
pub fn free(self) -> P {
self.pin.into_inner()
}
}
impl<E, P> EmbeddedProfiler for EPPinToggle<E, P>
where
P: OutputPin<Error = E>,
{
fn read_clock(&self) -> EPInstant {
EPInstant::from_ticks(0)
}
fn at_start(&self) {
self.pin.borrow_mut().set_high().ok();
}
fn at_end(&self) {
self.pin.borrow_mut().set_low().ok();
}
}
