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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
// Copyright 2021 Jacob Alexander // // Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or // http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or // http://opensource.org/licenses/MIT>, at your option. This file may not be // copied, modified, or distributed except according to those terms. #![no_std] pub use log; #[cfg(feature = "semihosting")] pub use cortex_m_semihosting; #[cfg(feature = "rtt")] pub use rtt_target; /// Logger Structure /// /// Example RTT Usage /// ``` /// use kiibohd_log::{log, Logger}; /// /// static LOGGER: Logger = Logger::new(log::LevelFilter::Info); /// /// fn main() { /// // Setup RTT logging /// let mut channels = rtt_target::rtt_init_default!(); /// /// // cortex-m or riscv /// //rtt_target::set_print_channel(channels.up.0); /// // otherwise use set_print_channel_cs /// log::set_logger(&LOGGER).unwrap(); /// /// // Example usage /// log::trace!("Trace message"); /// log::debug!("Debug message"); /// log::info!("Info message"); /// log::warn!("Warn message"); /// log::error!("Error message"); /// /// // Read downchannel /// let mut buf = [0u8; 16]; /// channels.down.0.read(&mut buf[..]); /// log::trace!("{:?}", buf); /// } /// ``` /// /// Example Semihosting Usage /// ``` /// use kiibohd_log::{log, Logger}; /// /// static LOGGER: Logger = Logger::new(log::LevelFilter::Info); /// /// fn main() { /// log::set_logger(&LOGGER).unwrap(); /// /// // Example usage /// log::trace!("Trace message"); /// log::debug!("Debug message"); /// log::info!("Info message"); /// log::warn!("Warn message"); /// log::error!("Error message"); /// } /// ``` pub struct Logger { level_filter: log::LevelFilter, } impl Logger { pub const fn new(level_filter: log::LevelFilter) -> Self { Self { level_filter } } } impl log::Log for Logger { fn enabled(&self, metadata: &log::Metadata) -> bool { self.level_filter.ge(&metadata.level()) } // Handle entry prefixes fn log(&self, record: &log::Record) { if self.enabled(record.metadata()) { #[cfg(any(feature = "rtt", feature = "semihosting"))] let color = match record.level() { log::Level::Error => "1;5;31", log::Level::Warn => "1;33", log::Level::Info => "1;32", log::Level::Debug => "1;35", log::Level::Trace => "1;90", }; #[cfg(any(feature = "rtt", feature = "semihosting"))] let dwt = unsafe { &*cortex_m::peripheral::DWT::ptr() }; #[cfg(feature = "rtt")] rtt_target::rprintln!( "{:10}:\x1b[{}m{:5}\x1b[0m:{}", dwt.get_cycle_count(), color, record.level(), record.args() ); #[cfg(feature = "semihosting")] cortex_m_semihosting::hprintln!( "{:10}:\x1b[{}m{:5}\x1b[0m:{}", dwt.get_cycle_count(), color, record.level(), record.args() ) .ok(); /* TODO (HaaTa) Add itm support #[cfg(feature = "itm")] { let itm = unsafe { &mut *cortex_m::peripheral::ITM::ptr() }; let stim = &mut itm.stim[0]; cortex_m::iprintln!(stim, "{}:\x1b[{}m{}\x1b[0m - {}", dwt.cyccnt.read(), color, record.level(), record.args() ); } */ } } fn flush(&self) {} }