systemview_target/
lib.rs

1//! RTOS tracing trait implementation for SEGGER SystemView.
2//!
3//! SEGGER SystemView can be used for non-commercial project for free and is
4//! available [`here`](https://www.segger.com/products/development-tools/systemview/).
5//!
6//! # Features
7//!
8//! - `callbacks-os`: Check if RTOS supports tracing callbacks from SystemView.
9//! - `callbacks-os-time`: Check if RTOS supports timestamp callback from SystemView.
10//! - `callbacks-app`: Check if your application supports callback from SystemView.
11//! - `log`: Activates global `log` over RTT.
12//! - `cortex-m`: Enables Arm Cortex-M support.
13//!
14//! # Usage
15//!
16//! If you are using an RTOS which supports [`rtos-trace`](https://docs.rs/rtos-trace/)
17//! add the following dependencies:
18//!
19//! ```toml
20//! # Cargo.toml
21//! [dependencies]
22//! rtos-trace = "0.1"
23//! systemview-target = { version = "0.1", features = ["log", "callbacks-app", "callbacks-os", "callbacks-os-time", "cortex-m"] }
24//! log = { version = "0.4", features = ["max_level_trace", "release_max_level_warn"] }
25//! ```
26//!
27//! and add to your code
28//! ```ignore
29//! // for tracing
30//! use systemview_target::SystemView;
31//! rtos_trace::global_trace!{SystemView}
32//!
33//! static LOGGER: systemview_target::SystemView = systemview_target::SystemView::new();
34//!
35//! fn main() -> ! {
36//!     LOGGER.init();
37//!     // for logs
38//!     log::set_logger(&LOGGER).ok();
39//!     log::set_max_level(log::LevelFilter::Trace);
40//!     /*..*/
41//! }
42//! ```
43
44#![no_std]
45
46#[cfg(not(any(feature = "cortex-m")))]
47compile_error!("You must select a target architecture. Supported are: cortex-m");
48
49#[cfg(feature = "log")]
50pub mod log;
51mod macros;
52mod stub;
53mod wrapper;
54
55use core::ptr::null;
56#[cfg(feature = "log")]
57pub use heapless;
58pub use rtos_trace::RtosTrace;
59use rtos_trace::TaskInfo;
60use wrapper::*;
61
62pub struct SystemView;
63
64impl SystemView {
65    pub const fn new() -> SystemView {
66        SystemView
67    }
68
69    pub fn init(&self) {
70        unsafe {
71            SEGGER_SYSVIEW_Conf();
72        }
73    }
74
75    pub fn send_system_description(desc: &str) {
76        unsafe {
77            SEGGER_SYSVIEW_SendSysDesc(desc.as_ptr());
78        }
79    }
80}
81
82impl RtosTrace for SystemView {
83    fn start() {
84        unsafe {
85            SEGGER_SYSVIEW_Start();
86        }
87    }
88
89    fn stop() {
90        unsafe {
91            SEGGER_SYSVIEW_Stop();
92        }
93    }
94
95    fn task_new(id: u32) {
96        unsafe {
97            SEGGER_SYSVIEW_OnTaskCreate(id);
98        }
99    }
100
101    fn task_send_info(id: u32, info: TaskInfo) {
102        let name = if info.name.is_empty() {
103            null()
104        } else {
105            info.name.as_ptr()
106        };
107        let info = SEGGER_SYSVIEW_TASKINFO {
108            TaskID: id,
109            sName: name,
110            Prio: info.priority,
111            StackBase: info.stack_base as u32,
112            StackSize: info.stack_size as u32,
113            StackUsage: 0,
114        };
115        unsafe {
116            SEGGER_SYSVIEW_SendTaskInfo(&info);
117        }
118    }
119
120    fn task_new_stackless(id: u32, name: &'static str, priority: u32) {
121        Self::task_new(id);
122        Self::task_send_info(
123            id,
124            TaskInfo {
125                name,
126                priority,
127                stack_base: 0,
128                stack_size: 0,
129            },
130        );
131    }
132
133    fn task_terminate(id: u32) {
134        unsafe {
135            SEGGER_SYSVIEW_OnTaskTerminate(id);
136        }
137    }
138
139    fn task_exec_begin(id: u32) {
140        unsafe {
141            SEGGER_SYSVIEW_OnTaskStartExec(id);
142        }
143    }
144
145    fn task_exec_end() {
146        unsafe {
147            SEGGER_SYSVIEW_OnTaskStopExec();
148        }
149    }
150
151    fn task_ready_begin(id: u32) {
152        unsafe {
153            SEGGER_SYSVIEW_OnTaskStartReady(id);
154        }
155    }
156
157    fn task_ready_end(id: u32) {
158        unsafe {
159            SEGGER_SYSVIEW_OnTaskStopReady(id, 0);
160        }
161    }
162
163    fn system_idle() {
164        unsafe {
165            SEGGER_SYSVIEW_OnIdle();
166        }
167    }
168
169    fn isr_enter() {
170        unsafe {
171            SEGGER_SYSVIEW_RecordEnterISR();
172        }
173    }
174
175    fn isr_exit() {
176        unsafe {
177            SEGGER_SYSVIEW_RecordExitISR();
178        }
179    }
180
181    fn isr_exit_to_scheduler() {
182        unsafe {
183            SEGGER_SYSVIEW_RecordExitISRToScheduler();
184        }
185    }
186
187    fn name_marker(id: u32, name: &'static str) {
188        unsafe {
189            SEGGER_SYSVIEW_NameMarker(id, name.as_ptr());
190        }
191    }
192
193    fn marker(id: u32) {
194        unsafe {
195            SEGGER_SYSVIEW_Mark(id);
196        }
197    }
198
199    fn marker_begin(id: u32) {
200        unsafe {
201            SEGGER_SYSVIEW_MarkStart(id);
202        }
203    }
204
205    fn marker_end(id: u32) {
206        unsafe {
207            SEGGER_SYSVIEW_MarkStop(id);
208        }
209    }
210}
211
212impl Default for SystemView {
213    fn default() -> Self {
214        Self::new()
215    }
216}