Created
March 25, 2021 22:42
-
-
Save ryankurte/445c6b197a4214f6e5b3be064718c537 to your computer and use it in GitHub Desktop.
Rust embedded static logging example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use core::fmt::Write; | |
use alloc::boxed::Box; | |
use embedded_hal::serial::{Write as SerialWrite}; | |
use stm32f4xx_hal::serial; | |
use log::{Log, Level, Metadata, Record}; | |
pub struct SerialLogger<E> { | |
pub level: Level, | |
pub writer: Option<Box<dyn SerialWrite<u8, Error=E>>>, | |
} | |
unsafe impl <E> Sync for SerialLogger<E> {} | |
unsafe impl <E> Send for SerialLogger<E> {} | |
static mut SERIAL_LOGGER: SerialLogger<serial::Error> = SerialLogger{level: Level::Info, writer: None}; | |
impl SerialLogger<serial::Error> { | |
pub fn init(level: Level, w: Box<dyn SerialWrite<u8, Error=serial::Error>>) { | |
unsafe { | |
// Set global SERIAL_LOGGER log context | |
SERIAL_LOGGER.level = level; | |
SERIAL_LOGGER.writer = Some(w); | |
// Attach to logger | |
let _ = log::set_logger(&SERIAL_LOGGER); | |
log::set_max_level(SERIAL_LOGGER.level.to_level_filter()); | |
} | |
} | |
} | |
impl <E> Log for SerialLogger<E> { | |
fn enabled(&self, metadata: &Metadata) -> bool { | |
metadata.level() <= self.level | |
} | |
fn log(&self, record: &Record) { | |
if self.enabled(record.metadata()) { | |
let _ = unsafe { | |
match record.module_path() { | |
Some(p) => write!(SERIAL_LOGGER, "[{}] {} - {}\r\n", record.level(), p, record.args()), | |
None => write!(SERIAL_LOGGER, "[{}] - {}\r\n", record.level(), record.args()) | |
} | |
}; | |
} | |
} | |
fn flush(&self) { } | |
} | |
impl <E>core::fmt::Write for SerialLogger<E> { | |
fn write_str(&mut self, s: &str) -> core::fmt::Result { | |
// Fetch writer (if bound) | |
let w = match &mut self.writer { | |
Some(w) => w, | |
None => return Err(core::fmt::Error), | |
}; | |
// Output string as bytes | |
for b in s.as_bytes() { | |
block!(w.try_write(*b)).map_err(|_| core::fmt::Error)?; | |
} | |
// Flush output buffers | |
block!(w.try_flush()).map_err(|_| core::fmt::Error)?; | |
Ok(()) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment