-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
core::fmt
UART based logger for log
package
We can not use `ufmt` for formatting because there is no `ufmt` support for the required (sub) arguments of functions in the `Log` trait.
- Loading branch information
Showing
6 changed files
with
99 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// SPDX-FileCopyrightText: 2024 Google LLC | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
use crate::uart; | ||
|
||
// The logger utilizes core::fmt to format the log messages because ufmt formatting is not | ||
// compatible with (dependencies of) the log crate. | ||
use core::fmt::Write; | ||
|
||
/// A global logger instance to be used with the `log` crate. | ||
/// | ||
/// Use `set_logger` to set the `Uart` instance to be used for logging. | ||
/// # Safety | ||
/// Using this logger is only safe if there is only one thread of execution. | ||
/// Even though `UartLogger` is `Send` and `Sync`, The underlying `Uart` is not `Send` or `Sync`. | ||
pub static mut LOGGER: UartLogger = UartLogger { uart: None }; | ||
|
||
/// Wrapper for `Uart` to be used as a logger with the `log` crate | ||
/// Instead of making a new logger, use the `set_logger` method of the `LOGGER` instance. | ||
/// # Safety | ||
/// Using this logger is only safe if there is only one thread of execution. | ||
/// Even though `UartLogger` is `Send` and `Sync`, The underlying `Uart` is not `Send` or `Sync`. | ||
pub struct UartLogger { | ||
uart: Option<uart::Uart>, | ||
} | ||
|
||
impl UartLogger { | ||
/// Set the logger to use the given UART. | ||
/// # Safety | ||
/// Using this function and logger is only safe if there is only one thread of execution. | ||
/// This function is used to assign the `Uart` instance to a global (`static mut`), but `Uart` is not `Send` or `Sync`. | ||
pub unsafe fn set_logger(&mut self, uart: uart::Uart) { | ||
self.uart = Some(uart); | ||
} | ||
} | ||
|
||
impl log::Log for UartLogger { | ||
fn enabled(&self, metadata: &log::Metadata) -> bool { | ||
log::Level::Info <= metadata.level() | ||
} | ||
|
||
fn log(&self, record: &log::Record) { | ||
if self.enabled(record.metadata()) { | ||
unsafe { | ||
match &mut LOGGER.uart { | ||
Some(l) => { | ||
writeln!( | ||
l, | ||
"{} | {}:{} - {}", | ||
record.level(), | ||
record.file().unwrap(), | ||
record.line().unwrap(), | ||
record.args() | ||
) | ||
.ok(); | ||
} | ||
None => panic!("Logger not set"), | ||
} | ||
} | ||
} | ||
} | ||
|
||
fn flush(&self) {} | ||
} | ||
|
||
unsafe impl core::marker::Send for UartLogger {} | ||
unsafe impl core::marker::Sync for UartLogger {} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.