acid/firmware2/src/logging.rs

120 lines
3 KiB
Rust
Raw Normal View History

2025-12-31 01:08:12 +01:00
use core::cell::RefCell;
use core::fmt::Write;
2025-12-31 00:54:48 +01:00
use critical_section::{CriticalSection, Mutex};
2025-12-31 01:08:12 +01:00
use esp_hal::uart::UartTx;
use esp_hal::Blocking;
use log::{LevelFilter, Log};
static ALT_LOGGER_UART: Mutex<RefCell<Option<UartTx<'static, Blocking>>>> = Mutex::new(RefCell::new(None));
2025-12-31 01:08:12 +01:00
pub fn with_uart_tx<R>(f: impl FnOnce(CriticalSection<'_>, &'_ mut UartTx<'static, Blocking>) -> R) -> R {
2025-12-31 00:54:48 +01:00
critical_section::with(|cs| {
let mut uart = ALT_LOGGER_UART.borrow(cs).borrow_mut();
2025-12-31 01:08:12 +01:00
let uart = uart.as_mut().unwrap();
2025-12-31 00:54:48 +01:00
2025-12-31 01:08:12 +01:00
(f)(cs, uart)
2025-12-31 00:54:48 +01:00
})
}
struct AlternativeLogger;
impl Log for AlternativeLogger {
#[allow(unused)]
fn enabled(&self, _: &log::Metadata) -> bool {
// Filtered by `log` already
true
}
#[allow(unused)]
fn log(&self, record: &log::Record) {
2025-12-31 00:54:48 +01:00
with_uart_tx(|cs, uart| {
print_log_record(uart, record);
})
}
fn flush(&self) {}
}
2025-12-31 00:54:48 +01:00
const RESET: &str = "\u{001B}[0m";
const RED: &str = "\u{001B}[31m";
const GREEN: &str = "\u{001B}[32m";
const YELLOW: &str = "\u{001B}[33m";
const BLUE: &str = "\u{001B}[34m";
const CYAN: &str = "\u{001B}[35m";
2026-01-05 04:16:05 +01:00
#[cfg(feature = "rtt-log")]
#[allow(unused)]
use ::rtt_target::{rprint as print, rprintln as println};
#[cfg(feature = "alt-log")]
2026-01-01 03:59:24 +01:00
#[allow(unused)]
macro_rules! println {
() => {{
do_print(Default::default());
}};
($($arg:tt)*) => {{
do_print(::core::format_args!($($arg)*));
}};
}
2026-01-01 03:59:24 +01:00
#[allow(unused)]
fn do_print(args: core::fmt::Arguments<'_>) {
2025-12-31 01:08:12 +01:00
with_uart_tx(|_, uart| {
uart.write_fmt(args).unwrap();
uart.write_str("\n").unwrap();
uart.flush().unwrap();
})
}
fn print_log_record(uart: &mut UartTx<'_, Blocking>, record: &log::Record) {
let color = match record.level() {
log::Level::Error => RED,
log::Level::Warn => YELLOW,
log::Level::Info => GREEN,
log::Level::Debug => BLUE,
log::Level::Trace => CYAN,
};
let reset = RESET;
let args = format_args!("{}{:>5} - {}{}\n", color, record.level(), record.args(), reset);
uart.write_fmt(args).unwrap();
uart.flush().unwrap();
}
2026-01-05 04:16:05 +01:00
#[cfg(feature = "rtt-log")]
use panic_rtt_target as _;
#[cfg(feature = "alt-log")]
#[panic_handler]
fn panic_handler(info: &core::panic::PanicInfo) -> ! {
use esp_backtrace::Backtrace;
println!("{RED}");
2025-12-31 22:24:26 +01:00
println!("=============== CUSTOM PANIC HANDLER ==============");
println!("{info}{RESET}");
println!("");
println!("Backtrace:");
println!("");
let backtrace = Backtrace::capture();
for frame in backtrace.frames() {
println!("0x{:x}", frame.program_counter());
}
loop {}
}
pub fn setup_alternative_logging(alt_uart: UartTx<'static, Blocking>, level_filter: LevelFilter)
{
critical_section::with(|cs| {
*ALT_LOGGER_UART.borrow(cs).borrow_mut() = Some(alt_uart);
});
unsafe {
log::set_logger_racy(&AlternativeLogger).unwrap();
log::set_max_level_racy(level_filter);
}
}