Skip to main content

ax_plat/
console.rs

1//! Console input and output.
2
3use core::fmt::{Arguments, Result, Write};
4
5/// Console input and output interface.
6#[def_plat_interface]
7pub trait ConsoleIf {
8    /// Writes given bytes to the console.
9    fn write_bytes(bytes: &[u8]);
10
11    /// Reads bytes from the console into the given mutable slice.
12    ///
13    /// Returns the number of bytes read.
14    fn read_bytes(bytes: &mut [u8]) -> usize;
15
16    /// Returns the IRQ number for the console input interrupt.
17    ///
18    /// Returns `None` if input interrupt is not supported.
19    #[cfg(feature = "irq")]
20    fn irq_num() -> Option<usize>;
21}
22
23struct EarlyConsole;
24
25impl Write for EarlyConsole {
26    fn write_str(&mut self, s: &str) -> Result {
27        write_bytes(s.as_bytes());
28        Ok(())
29    }
30}
31
32/// Lock for console operations to prevent mixed output from concurrent execution
33pub static CONSOLE_LOCK: ax_kspin::SpinNoIrq<()> = ax_kspin::SpinNoIrq::new(());
34
35/// Simple console print operation.
36#[macro_export]
37macro_rules! console_print {
38    ($($arg:tt)*) => {
39        $crate::console::__simple_print(format_args!($($arg)*));
40    }
41}
42
43/// Simple console print operation, with a newline.
44#[macro_export]
45macro_rules! console_println {
46    () => { $crate::ax_print!("\n") };
47    ($($arg:tt)*) => {
48        $crate::console::__simple_print(format_args!("{}\n", format_args!($($arg)*)));
49    }
50}
51
52#[doc(hidden)]
53pub fn __simple_print(fmt: Arguments) {
54    let _guard = CONSOLE_LOCK.lock();
55    EarlyConsole.write_fmt(fmt).unwrap();
56    drop(_guard);
57}