1#![doc = include_str!("../README.md")]
2#![cfg_attr(not(test), no_std)]
3
4pub use rtt_target;
5
6use once_cell::sync::OnceCell;
7use rtt_target::{rprintln, rtt_init_print};
8
9struct Logger {
10 level_filter: log::LevelFilter,
11}
12
13impl log::Log for Logger {
14 fn enabled(&self, metadata: &log::Metadata) -> bool {
16 metadata.level() <= self.level_filter
17 }
18
19 fn log(&self, record: &log::Record) {
21 if self.enabled(record.metadata()) {
22 rprintln!(
23 "{:<5} [{}] {}",
24 record.level(),
25 record.target(),
26 record.args()
27 );
28 }
29 }
30
31 fn flush(&self) {
33 }
35}
36
37static LOGGER: OnceCell<Logger> = OnceCell::new();
38
39pub fn init() {
41 init_with_level(log::LevelFilter::Trace);
42}
43
44pub fn init_with_level(level_filter: log::LevelFilter) {
46 if LOGGER.get().is_some() {
48 return;
49 }
50 let logger = LOGGER.get_or_init(|| Logger { level_filter });
51 rtt_init_print!();
52
53 #[cfg(any(not(target_has_atomic = "ptr"), feature = "racy_init"))]
55 unsafe {
56 init_racy(logger);
57 }
58
59 #[cfg(all(target_has_atomic = "ptr", not(feature = "racy_init")))]
61 init_default(logger);
62}
63
64#[cfg(all(target_has_atomic = "ptr", not(feature = "racy_init")))]
65fn init_default(logger: &'static Logger) {
66 log::set_logger(logger).ok();
67 log::set_max_level(logger.level_filter);
68}
69
70#[cfg(any(not(target_has_atomic = "ptr"), feature = "racy_init"))]
77unsafe fn init_racy(logger: &'static Logger) {
78 log::set_logger_racy(logger).ok();
79 log::set_max_level_racy(logger.level_filter);
80}