Skip to content

Commit

Permalink
[rust] add stdio module, stdin() and stdout() functions
Browse files Browse the repository at this point in the history
Stdin and Stdout structures implement embedded_io::Read and Write.

Signed-off-by: Zhouqi Jiang <luojia@hust.edu.cn>
  • Loading branch information
luojia65 committed Oct 3, 2024
1 parent ed57f0f commit 0b15258
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 35 deletions.
31 changes: 20 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 6 additions & 4 deletions rust/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,12 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
let (allwinner_rt_p, _allwinner_rt_c) = ::syterkit::allwinner_rt::__rom_init_params();
let c = ::syterkit::__clock_init(&allwinner_rt_p.ccu);
let (p, uart0, tx, rx) = ::syterkit::Peripherals::configure_uart0(allwinner_rt_p);
let mut serial = ::syterkit::allwinner_hal::uart::Serial::new(uart0, (tx, rx), ::syterkit::allwinner_hal::uart::Config::default(), &c, &p.ccu);
unsafe {
*::syterkit::CONSOLE.lock() = Some(::syterkit::SyterKitConsole { inner: serial })
};
let serial = ::syterkit::allwinner_hal::uart::Serial::new(uart0, (tx, rx), ::syterkit::allwinner_hal::uart::Config::default(), &c, &p.ccu);
let (serial_out, stdin) = serial.split();
{
*::syterkit::STDOUT.lock() = Some(::syterkit::SyterKitStdoutInner { inner: serial_out });
*::syterkit::STDIN.lock() = Some(::syterkit::SyterKitStdinInner { inner: stdin });
}
unsafe { __syterkit_macros__main(p, c) }
}
#[allow(non_snake_case)]
Expand Down
24 changes: 4 additions & 20 deletions rust/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
#![no_std]
use allwinner_hal::{gpio::Function, uart::Serial};
use allwinner_rt::soc::d1::UART0;
use embedded_io::Write;
use spin::Mutex;

#[macro_use]
mod macros;

pub mod mctl;
pub mod soc;
mod stdio;

pub use allwinner_hal::ccu::Clocks;
pub use syterkit_macros::entry;
Expand All @@ -35,24 +32,11 @@ pub fn show_banner() {
println!();
}

#[doc(hidden)]
pub static CONSOLE: Mutex<Option<SyterKitConsole<'static>>> = Mutex::new(None);

#[doc(hidden)]
pub struct SyterKitConsole<'a> {
pub inner: Serial<UART0, 0, (Function<'a, 'B', 8, 6>, Function<'a, 'B', 9, 6>)>,
}

unsafe impl<'a> Send for SyterKitConsole<'a> {}
pub use stdio::{stdin, stdout, Stdin, Stdout};

// macro internal, used in `print` and `println` macros in `macros.rs`.
// macro internal code, used by `print` and `println`.
#[doc(hidden)]
#[inline]
pub fn _print(args: core::fmt::Arguments) {
if let Some(serial) = &mut *CONSOLE.lock() {
serial.inner.write_fmt(args).unwrap();
}
}
pub use stdio::_print;

// macro internal code, used in `entry` proc macro.
#[doc(hidden)]
Expand Down
96 changes: 96 additions & 0 deletions rust/src/stdio.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
use allwinner_hal::{
gpio::Function,
uart::{ReceiveHalf, TransmitHalf},
};
use allwinner_rt::soc::d1::UART0;
use embedded_io::Write;
use spin::Mutex;

#[doc(hidden)]
pub static STDOUT: Mutex<Option<SyterKitStdoutInner>> = Mutex::new(None);
#[doc(hidden)]
pub static STDIN: Mutex<Option<SyterKitStdinInner>> = Mutex::new(None);

#[doc(hidden)]
pub struct SyterKitStdoutInner {
pub inner: TransmitHalf<UART0, 0, Function<'static, 'B', 8, 6>>,
}

unsafe impl Send for SyterKitStdoutInner {}

#[doc(hidden)]
pub struct SyterKitStdinInner {
pub inner: ReceiveHalf<UART0, 0, Function<'static, 'B', 9, 6>>,
}

unsafe impl Send for SyterKitStdinInner {}

// macro internal, used in `print` and `println` macros in `macros.rs`.
#[doc(hidden)]
#[inline]
pub fn _print(args: core::fmt::Arguments) {
if let Some(serial) = &mut *STDOUT.lock() {
serial.inner.write_fmt(args).ok();
}
}

/// A handle to the global standard output stream of the current runtime.
pub struct Stdout {
inner: spin::MutexGuard<'static, Option<SyterKitStdoutInner>>,
}

impl embedded_io::ErrorType for Stdout {
type Error = core::convert::Infallible;
}

impl embedded_io::Write for Stdout {
#[inline]
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
if let Some(stdout) = &mut *self.inner {
stdout.inner.write_all(buf).ok();
}
Ok(buf.len())
}
#[inline]
fn flush(&mut self) -> Result<(), Self::Error> {
if let Some(stdout) = &mut *self.inner {
stdout.inner.flush().ok();
}
Ok(())
}
}

/// A handle to the standard input stream of a runtime.
pub struct Stdin {
inner: spin::MutexGuard<'static, Option<SyterKitStdinInner>>,
}

impl embedded_io::ErrorType for Stdin {
type Error = core::convert::Infallible;
}

impl embedded_io::Read for Stdin {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
if let Some(stdin) = &mut *self.inner {
stdin.inner.read(buf).ok();
}
Ok(buf.len())
}
}

/// Constructs a new handle to the standard output of the current environment.
#[inline]
pub fn stdout() -> Stdout {
Stdout {
inner: STDOUT.lock(),
}
}

/// Constructs a new handle to the standard input of the current environment.
#[inline]
pub fn stdin() -> Stdin {
Stdin {
inner: STDIN.lock(),
}
}

0 comments on commit 0b15258

Please sign in to comment.