Logging

It would be nice to be able to use the logging macros from the log crate. We can do this by implementing the Log trait.

  1. use crate::pl011::Uart;
  2. use core::fmt::Write;
  3. use log::{LevelFilter, Log, Metadata, Record, SetLoggerError};
  4. use spin::mutex::SpinMutex;
  5. static LOGGER: Logger = Logger { uart: SpinMutex::new(None) };
  6. struct Logger {
  7.     uart: SpinMutex<Option<Uart>>,
  8. }
  9. impl Log for Logger {
  10.     fn enabled(&self, _metadata: &Metadata) -> bool {
  11.         true
  12.     }
  13.     fn log(&self, record: &Record) {
  14.         writeln!(
  15.             self.uart.lock().as_mut().unwrap(),
  16.             "[{}] {}",
  17.             record.level(),
  18.             record.args()
  19.         )
  20.         .unwrap();
  21.     }
  22.     fn flush(&self) {}
  23. }
  24. /// Initialises UART logger.
  25. pub fn init(uart: Uart, max_level: LevelFilter) -> Result<(), SetLoggerError> {
  26.     LOGGER.uart.lock().replace(uart);
  27.     log::set_logger(&LOGGER)?;
  28.     log::set_max_level(max_level);
  29.     Ok(())
  30. }
  • The unwrap in log is safe because we initialise LOGGER before calling set_logger.