Skip to content

Commit 0b15258

Browse files
committed
[rust] add stdio module, stdin() and stdout() functions
Stdin and Stdout structures implement embedded_io::Read and Write. Signed-off-by: Zhouqi Jiang <[email protected]>
1 parent ed57f0f commit 0b15258

File tree

4 files changed

+126
-35
lines changed

4 files changed

+126
-35
lines changed

Cargo.lock

+20-11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/macros/src/lib.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,12 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
8080
let (allwinner_rt_p, _allwinner_rt_c) = ::syterkit::allwinner_rt::__rom_init_params();
8181
let c = ::syterkit::__clock_init(&allwinner_rt_p.ccu);
8282
let (p, uart0, tx, rx) = ::syterkit::Peripherals::configure_uart0(allwinner_rt_p);
83-
let mut serial = ::syterkit::allwinner_hal::uart::Serial::new(uart0, (tx, rx), ::syterkit::allwinner_hal::uart::Config::default(), &c, &p.ccu);
84-
unsafe {
85-
*::syterkit::CONSOLE.lock() = Some(::syterkit::SyterKitConsole { inner: serial })
86-
};
83+
let serial = ::syterkit::allwinner_hal::uart::Serial::new(uart0, (tx, rx), ::syterkit::allwinner_hal::uart::Config::default(), &c, &p.ccu);
84+
let (serial_out, stdin) = serial.split();
85+
{
86+
*::syterkit::STDOUT.lock() = Some(::syterkit::SyterKitStdoutInner { inner: serial_out });
87+
*::syterkit::STDIN.lock() = Some(::syterkit::SyterKitStdinInner { inner: stdin });
88+
}
8789
unsafe { __syterkit_macros__main(p, c) }
8890
}
8991
#[allow(non_snake_case)]

rust/src/lib.rs

+4-20
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
#![no_std]
2-
use allwinner_hal::{gpio::Function, uart::Serial};
3-
use allwinner_rt::soc::d1::UART0;
4-
use embedded_io::Write;
5-
use spin::Mutex;
62

73
#[macro_use]
84
mod macros;
95

106
pub mod mctl;
117
pub mod soc;
8+
mod stdio;
129

1310
pub use allwinner_hal::ccu::Clocks;
1411
pub use syterkit_macros::entry;
@@ -35,24 +32,11 @@ pub fn show_banner() {
3532
println!();
3633
}
3734

38-
#[doc(hidden)]
39-
pub static CONSOLE: Mutex<Option<SyterKitConsole<'static>>> = Mutex::new(None);
40-
41-
#[doc(hidden)]
42-
pub struct SyterKitConsole<'a> {
43-
pub inner: Serial<UART0, 0, (Function<'a, 'B', 8, 6>, Function<'a, 'B', 9, 6>)>,
44-
}
45-
46-
unsafe impl<'a> Send for SyterKitConsole<'a> {}
35+
pub use stdio::{stdin, stdout, Stdin, Stdout};
4736

48-
// macro internal, used in `print` and `println` macros in `macros.rs`.
37+
// macro internal code, used by `print` and `println`.
4938
#[doc(hidden)]
50-
#[inline]
51-
pub fn _print(args: core::fmt::Arguments) {
52-
if let Some(serial) = &mut *CONSOLE.lock() {
53-
serial.inner.write_fmt(args).unwrap();
54-
}
55-
}
39+
pub use stdio::_print;
5640

5741
// macro internal code, used in `entry` proc macro.
5842
#[doc(hidden)]

rust/src/stdio.rs

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
use allwinner_hal::{
2+
gpio::Function,
3+
uart::{ReceiveHalf, TransmitHalf},
4+
};
5+
use allwinner_rt::soc::d1::UART0;
6+
use embedded_io::Write;
7+
use spin::Mutex;
8+
9+
#[doc(hidden)]
10+
pub static STDOUT: Mutex<Option<SyterKitStdoutInner>> = Mutex::new(None);
11+
#[doc(hidden)]
12+
pub static STDIN: Mutex<Option<SyterKitStdinInner>> = Mutex::new(None);
13+
14+
#[doc(hidden)]
15+
pub struct SyterKitStdoutInner {
16+
pub inner: TransmitHalf<UART0, 0, Function<'static, 'B', 8, 6>>,
17+
}
18+
19+
unsafe impl Send for SyterKitStdoutInner {}
20+
21+
#[doc(hidden)]
22+
pub struct SyterKitStdinInner {
23+
pub inner: ReceiveHalf<UART0, 0, Function<'static, 'B', 9, 6>>,
24+
}
25+
26+
unsafe impl Send for SyterKitStdinInner {}
27+
28+
// macro internal, used in `print` and `println` macros in `macros.rs`.
29+
#[doc(hidden)]
30+
#[inline]
31+
pub fn _print(args: core::fmt::Arguments) {
32+
if let Some(serial) = &mut *STDOUT.lock() {
33+
serial.inner.write_fmt(args).ok();
34+
}
35+
}
36+
37+
/// A handle to the global standard output stream of the current runtime.
38+
pub struct Stdout {
39+
inner: spin::MutexGuard<'static, Option<SyterKitStdoutInner>>,
40+
}
41+
42+
impl embedded_io::ErrorType for Stdout {
43+
type Error = core::convert::Infallible;
44+
}
45+
46+
impl embedded_io::Write for Stdout {
47+
#[inline]
48+
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
49+
if let Some(stdout) = &mut *self.inner {
50+
stdout.inner.write_all(buf).ok();
51+
}
52+
Ok(buf.len())
53+
}
54+
#[inline]
55+
fn flush(&mut self) -> Result<(), Self::Error> {
56+
if let Some(stdout) = &mut *self.inner {
57+
stdout.inner.flush().ok();
58+
}
59+
Ok(())
60+
}
61+
}
62+
63+
/// A handle to the standard input stream of a runtime.
64+
pub struct Stdin {
65+
inner: spin::MutexGuard<'static, Option<SyterKitStdinInner>>,
66+
}
67+
68+
impl embedded_io::ErrorType for Stdin {
69+
type Error = core::convert::Infallible;
70+
}
71+
72+
impl embedded_io::Read for Stdin {
73+
#[inline]
74+
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
75+
if let Some(stdin) = &mut *self.inner {
76+
stdin.inner.read(buf).ok();
77+
}
78+
Ok(buf.len())
79+
}
80+
}
81+
82+
/// Constructs a new handle to the standard output of the current environment.
83+
#[inline]
84+
pub fn stdout() -> Stdout {
85+
Stdout {
86+
inner: STDOUT.lock(),
87+
}
88+
}
89+
90+
/// Constructs a new handle to the standard input of the current environment.
91+
#[inline]
92+
pub fn stdin() -> Stdin {
93+
Stdin {
94+
inner: STDIN.lock(),
95+
}
96+
}

0 commit comments

Comments
 (0)