Add support for rtos-trace behind a feature flag

This commit is contained in:
Quentin Smith 2022-08-09 16:25:42 -04:00
parent b7b4c84067
commit a3c1522ce6
4 changed files with 64 additions and 1 deletions

View File

@ -53,6 +53,7 @@ time-tick-16mhz = ["time"]
[dependencies] [dependencies]
defmt = { version = "0.3", optional = true } defmt = { version = "0.3", optional = true }
log = { version = "0.4.14", optional = true } log = { version = "0.4.14", optional = true }
rtos-trace = { version = "0.1.2", optional = true }
embedded-hal-02 = { package = "embedded-hal", version = "0.2.6" } embedded-hal-02 = { package = "embedded-hal", version = "0.2.6" }
embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.8", optional = true} embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.8", optional = true}

View File

@ -22,6 +22,8 @@ use core::{mem, ptr};
use atomic_polyfill::{AtomicU32, Ordering}; use atomic_polyfill::{AtomicU32, Ordering};
use critical_section::CriticalSection; use critical_section::CriticalSection;
#[cfg(feature = "rtos-trace")]
use rtos_trace::trace;
use self::run_queue::{RunQueue, RunQueueItem}; use self::run_queue::{RunQueue, RunQueueItem};
use self::util::UninitCell; use self::util::UninitCell;
@ -306,6 +308,9 @@ impl Executor {
/// - `task` must NOT be already enqueued (in this executor or another one). /// - `task` must NOT be already enqueued (in this executor or another one).
#[inline(always)] #[inline(always)]
unsafe fn enqueue(&self, cs: CriticalSection, task: NonNull<TaskHeader>) { unsafe fn enqueue(&self, cs: CriticalSection, task: NonNull<TaskHeader>) {
#[cfg(feature = "rtos-trace")]
trace::task_ready_begin(task.as_ptr() as u32);
if self.run_queue.enqueue(cs, task) { if self.run_queue.enqueue(cs, task) {
(self.signal_fn)(self.signal_ctx) (self.signal_fn)(self.signal_ctx)
} }
@ -323,6 +328,9 @@ impl Executor {
pub(super) unsafe fn spawn(&'static self, task: NonNull<TaskHeader>) { pub(super) unsafe fn spawn(&'static self, task: NonNull<TaskHeader>) {
task.as_ref().executor.set(self); task.as_ref().executor.set(self);
#[cfg(feature = "rtos-trace")]
trace::task_new(task.as_ptr() as u32);
critical_section::with(|cs| { critical_section::with(|cs| {
self.enqueue(cs, task); self.enqueue(cs, task);
}) })
@ -365,9 +373,15 @@ impl Executor {
return; return;
} }
#[cfg(feature = "rtos-trace")]
trace::task_exec_begin(p.as_ptr() as u32);
// Run the task // Run the task
task.poll_fn.read()(p as _); task.poll_fn.read()(p as _);
#[cfg(feature = "rtos-trace")]
trace::task_exec_end();
// Enqueue or update into timer_queue // Enqueue or update into timer_queue
#[cfg(feature = "time")] #[cfg(feature = "time")]
self.timer_queue.update(p); self.timer_queue.update(p);
@ -381,6 +395,9 @@ impl Executor {
let next_expiration = self.timer_queue.next_expiration(); let next_expiration = self.timer_queue.next_expiration();
driver::set_alarm(self.alarm, next_expiration.as_ticks()); driver::set_alarm(self.alarm, next_expiration.as_ticks());
} }
#[cfg(feature = "rtos-trace")]
trace::system_idle();
} }
/// Get a spawner that spawns tasks in this executor. /// Get a spawner that spawns tasks in this executor.
@ -425,3 +442,21 @@ pub(crate) unsafe fn register_timer(at: Instant, waker: &core::task::Waker) {
let expires_at = task.expires_at.get(); let expires_at = task.expires_at.get();
task.expires_at.set(expires_at.min(at)); task.expires_at.set(expires_at.min(at));
} }
#[cfg(feature = "rtos-trace")]
impl rtos_trace::RtosTraceOSCallbacks for Executor {
fn task_list() {
// We don't know what tasks exist, so we can't send them.
}
#[cfg(feature = "time")]
fn time() -> u64 {
Instant::now().as_micros()
}
#[cfg(not(feature = "time"))]
fn time() -> u64 {
0
}
}
#[cfg(feature = "rtos-trace")]
rtos_trace::global_os_callbacks!{Executor}

View File

@ -19,4 +19,25 @@ pub use embassy_macros::{main, task};
/// Implementation details for embassy macros. DO NOT USE. /// Implementation details for embassy macros. DO NOT USE.
pub mod export { pub mod export {
pub use atomic_polyfill as atomic; pub use atomic_polyfill as atomic;
#[cfg(feature = "rtos-trace")]
pub use rtos_trace::trace;
/// Expands the given block of code when `embassy-executor` is compiled with
/// the `rtos-trace` feature.
#[doc(hidden)]
#[macro_export]
#[cfg(feature = "rtos-trace")]
macro_rules! rtos_trace {
($($tt:tt)*) => { $($tt)* };
}
/// Does not expand the given block of code when `embassy-executor` is
/// compiled without the `rtos-trace` feature.
#[doc(hidden)]
#[macro_export]
#[cfg(not(feature = "rtos-trace"))]
macro_rules! rtos_trace {
($($tt:tt)*) => {};
}
} }

View File

@ -19,7 +19,13 @@ pub fn run(name: syn::Ident) -> Result<TokenStream, TokenStream> {
let func = HANDLER.func.load(::embassy_executor::export::atomic::Ordering::Relaxed); let func = HANDLER.func.load(::embassy_executor::export::atomic::Ordering::Relaxed);
let ctx = HANDLER.ctx.load(::embassy_executor::export::atomic::Ordering::Relaxed); let ctx = HANDLER.ctx.load(::embassy_executor::export::atomic::Ordering::Relaxed);
let func: fn(*mut ()) = ::core::mem::transmute(func); let func: fn(*mut ()) = ::core::mem::transmute(func);
func(ctx) ::embassy_executor::rtos_trace! {
::embassy_executor::export::trace::isr_enter();
}
func(ctx);
::embassy_executor::rtos_trace! {
::embassy_executor::export::trace::isr_exit();
}
} }
static TAKEN: ::embassy_executor::export::atomic::AtomicBool = ::embassy_executor::export::atomic::AtomicBool::new(false); static TAKEN: ::embassy_executor::export::atomic::AtomicBool = ::embassy_executor::export::atomic::AtomicBool::new(false);