From 18458bbf27971e14b19a9a187769af0c7b5d7f7c Mon Sep 17 00:00:00 2001 From: Victoria Fischer Date: Mon, 9 Mar 2026 10:07:13 +0100 Subject: [PATCH] tracing: first implementation of rtos-trace glue --- src/tracing.rs | 177 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 src/tracing.rs diff --git a/src/tracing.rs b/src/tracing.rs new file mode 100644 index 0000000..1ef462d --- /dev/null +++ b/src/tracing.rs @@ -0,0 +1,177 @@ +#![allow(static_mut_refs)] + +use log::*; + +use crate::logging::RenderbugLogger; + +#[derive(Debug)] +struct TracedTask { + id: u32, + name: &'static str, + priority: u32, + running: bool, + ready: bool +} + +impl TracedTask { + fn new(id: u32) -> Self { + Self { + id, + name: "", + priority: 0, + running: false, + ready: false + } + } +} + +pub struct Tracer {} + +struct TracerState { + tasks: [core::mem::MaybeUninit; 16], + num_tasks: usize, +} + +static mut TRACER_STATE: TracerState = TracerState::new(); + +impl TracerState { + const fn new() -> Self { + Self { + tasks: [const { core::mem::MaybeUninit::uninit() }; 16], + num_tasks: 0, + } + } + + fn get_task(&mut self, id: u32) -> &mut TracedTask { + for i in 0..self.num_tasks { + let info = unsafe { &mut *self.tasks[i].as_mut_ptr() }; + if info.id == id { + return info; + } + } + + // Otherwise, we register a new task + if self.num_tasks < self.tasks.len() { + self.tasks[self.num_tasks].write(TracedTask::new(id)); + self.num_tasks += 1; + } else { + panic!("too many tasks registered"); + } + + unsafe { &mut *self.tasks[self.num_tasks - 1].as_mut_ptr() } + } +} + +impl rtos_trace::RtosTrace for Tracer { + fn start() { + warn!("rtos start"); + } + + fn stop() { + warn!("rtos stop"); + } + + fn task_new(id: u32) { + let task = unsafe { TRACER_STATE.get_task(id) }; + warn!("rtos new task {task:?}"); + } + + fn task_send_info(id: u32, info: rtos_trace::TaskInfo) { + let task = unsafe { TRACER_STATE.get_task(id) }; + task.name = info.name; + task.priority = info.priority; + warn!("rtos task info for task {task:?}"); + } + + fn task_new_stackless(id: u32, name: &'static str, priority: u32) { + let task = unsafe { TRACER_STATE.get_task(id) }; + task.name = name; + task.priority = priority; + warn!("rtos new task {task:?} {name}"); + } + + fn task_terminate(id: u32) { + let task = unsafe { TRACER_STATE.get_task(id) }; + warn!("rtos terminate {task:?}") + } + + fn task_exec_begin(id: u32) { + let task = unsafe { TRACER_STATE.get_task(id) }; + task.running = true; + warn!("rtos exec {task:?}") + } + + fn task_exec_end() { + warn!("rtos exec end"); + } + + fn task_ready_begin(id: u32) { + let task = unsafe { TRACER_STATE.get_task(id) }; + task.ready = true; + warn!("rtos ready {task:?}") + } + + fn task_ready_end(id: u32) { + let task = unsafe { TRACER_STATE.get_task(id) }; + task.ready = false; + warn!("rtos suspend {task:?}") + } + + fn system_idle() { + warn!("rtos system idle"); + } + + fn isr_enter() { + warn!("rtos isr enter"); + } + + fn isr_exit() { + warn!("rtos isr exit"); + } + + fn isr_exit_to_scheduler() { + warn!("rtos isr exit to scheduler"); + } + + fn name_marker(id: u32, name: &'static str) { + warn!("rtos name marker {id}: {name}"); + } + + fn marker(id: u32) { + warn!("rtos marker {}", Self::name_for_marker(id)); + } + + fn marker_begin(id: u32) { + match id { + //1..2 => trace!("rtos marker begin {}", Self::name_for_marker(id)), + _ => { + warn!("rtos marker begin {}", Self::name_for_marker(id)); + RenderbugLogger::set_level(LevelFilter::Trace); + } + } + + } + + fn marker_end(id: u32) { + match id { + //1..2 => trace!("rtos marker end {}", Self::name_for_marker(id)), + _ => { + warn!("rtos marker end {}", Self::name_for_marker(id)); + RenderbugLogger::reset_level(); + }, + } + } +} + +impl Tracer { + const fn name_for_marker(id: u32) -> &'static str { + match id { + 0 => "run scheduler", + 1 => "yield task", + 2 => "timer tick", + 3 => "process timer queue", + 4 => "process embassy timer queue", + _ => "unknown", + } + } +}