1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use crate::drivers;
use core::fmt::{Arguments, Result, Write};
use lock::Mutex;
struct SerialWriter;
static SERIAL_WRITER: Mutex<SerialWriter> = Mutex::new(SerialWriter);
impl Write for SerialWriter {
fn write_str(&mut self, s: &str) -> Result {
if let Some(uart) = drivers::all_uart().first() {
uart.write_str(s).unwrap();
} else {
crate::hal_fn::console::console_write_early(s);
}
Ok(())
}
}
struct DebugWriter;
static DEBUG_WRITER: Mutex<DebugWriter> = Mutex::new(DebugWriter);
impl Write for DebugWriter {
fn write_str(&mut self, s: &str) -> Result {
crate::hal_fn::console::console_write_early(s);
Ok(())
}
}
cfg_if! {
if #[cfg(feature = "graphic")] {
use crate::utils::init_once::InitOnce;
use alloc::sync::Arc;
use zcore_drivers::{scheme::DisplayScheme, utils::GraphicConsole};
static GRAPHIC_CONSOLE: InitOnce<Mutex<GraphicConsole>> = InitOnce::new();
static CONSOLE_WIN_SIZE: InitOnce<ConsoleWinSize> = InitOnce::new();
pub(crate) fn init_graphic_console(display: Arc<dyn DisplayScheme>) {
let info = display.info();
let cons = GraphicConsole::new(display);
let winsz = ConsoleWinSize {
ws_row: cons.rows() as u16,
ws_col: cons.columns() as u16,
ws_xpixel: info.width as u16,
ws_ypixel: info.height as u16,
};
CONSOLE_WIN_SIZE.init_once_by(winsz);
GRAPHIC_CONSOLE.init_once_by(Mutex::new(cons));
}
}
}
pub fn serial_write_str(s: &str) {
SERIAL_WRITER.lock().write_str(s).unwrap();
}
pub fn serial_write_fmt(fmt: Arguments) {
SERIAL_WRITER.lock().write_fmt(fmt).unwrap();
}
pub fn debug_write_str(s: &str) {
DEBUG_WRITER.lock().write_str(s).unwrap();
}
pub fn debug_write_fmt(fmt: Arguments) {
DEBUG_WRITER.lock().write_fmt(fmt).unwrap();
}
#[allow(unused_variables)]
pub fn graphic_console_write_str(s: &str) {
#[cfg(feature = "graphic")]
if let Some(cons) = GRAPHIC_CONSOLE.try_get() {
cons.lock().write_str(s).unwrap();
}
}
#[allow(unused_variables)]
pub fn graphic_console_write_fmt(fmt: Arguments) {
#[cfg(feature = "graphic")]
if let Some(cons) = GRAPHIC_CONSOLE.try_get() {
cons.lock().write_fmt(fmt).unwrap();
}
}
pub fn console_write_str(s: &str) {
serial_write_str(s);
graphic_console_write_str(s);
}
pub fn console_write_fmt(fmt: Arguments) {
serial_write_fmt(fmt);
graphic_console_write_fmt(fmt);
}
pub async fn console_read(buf: &mut [u8]) -> usize {
super::future::SerialReadFuture::new(buf).await
}
#[repr(C)]
#[derive(Clone, Copy, Default)]
pub struct ConsoleWinSize {
pub ws_row: u16,
pub ws_col: u16,
pub ws_xpixel: u16,
pub ws_ypixel: u16,
}
pub fn console_win_size() -> ConsoleWinSize {
#[cfg(feature = "graphic")]
if let Some(&winsz) = CONSOLE_WIN_SIZE.try_get() {
return winsz;
}
ConsoleWinSize::default()
}