Import https://github.com/tock/libtock-rs at commit 828c19d into third_party/libtock-drivers/.
This commit is contained in:
82
third_party/libtock-drivers/src/console.rs
vendored
Normal file
82
third_party/libtock-drivers/src/console.rs
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
use crate::callback::Identity0Consumer;
|
||||
use crate::executor;
|
||||
use crate::futures;
|
||||
use crate::result::TockResult;
|
||||
use crate::syscalls;
|
||||
use core::cell::Cell;
|
||||
use core::fmt;
|
||||
use core::mem;
|
||||
|
||||
const DRIVER_NUMBER: usize = 1;
|
||||
|
||||
mod command_nr {
|
||||
pub const WRITE: usize = 1;
|
||||
}
|
||||
|
||||
mod subscribe_nr {
|
||||
pub const SET_ALARM: usize = 1;
|
||||
}
|
||||
|
||||
mod allow_nr {
|
||||
pub const SHARE_BUFFER: usize = 1;
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct ConsoleDriver;
|
||||
|
||||
impl ConsoleDriver {
|
||||
pub fn create_console(self) -> Console {
|
||||
Console {
|
||||
allow_buffer: [0; 64],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Console {
|
||||
allow_buffer: [u8; 64],
|
||||
}
|
||||
|
||||
impl Console {
|
||||
pub fn write<S: AsRef<[u8]>>(&mut self, text: S) -> TockResult<()> {
|
||||
let mut not_written_yet = text.as_ref();
|
||||
while !not_written_yet.is_empty() {
|
||||
let num_bytes_to_print = self.allow_buffer.len().min(not_written_yet.len());
|
||||
self.allow_buffer[..num_bytes_to_print]
|
||||
.copy_from_slice(¬_written_yet[..num_bytes_to_print]);
|
||||
self.flush(num_bytes_to_print)?;
|
||||
not_written_yet = ¬_written_yet[num_bytes_to_print..];
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn flush(&mut self, num_bytes_to_print: usize) -> TockResult<()> {
|
||||
let shared_memory = syscalls::allow(
|
||||
DRIVER_NUMBER,
|
||||
allow_nr::SHARE_BUFFER,
|
||||
&mut self.allow_buffer[..num_bytes_to_print],
|
||||
)?;
|
||||
|
||||
let is_written = Cell::new(false);
|
||||
let mut is_written_alarm = || is_written.set(true);
|
||||
let subscription = syscalls::subscribe::<Identity0Consumer, _>(
|
||||
DRIVER_NUMBER,
|
||||
subscribe_nr::SET_ALARM,
|
||||
&mut is_written_alarm,
|
||||
)?;
|
||||
|
||||
syscalls::command(DRIVER_NUMBER, command_nr::WRITE, num_bytes_to_print, 0)?;
|
||||
|
||||
unsafe { executor::block_on(futures::wait_until(|| is_written.get())) };
|
||||
|
||||
mem::drop(subscription);
|
||||
mem::drop(shared_memory);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Write for Console {
|
||||
fn write_str(&mut self, string: &str) -> Result<(), fmt::Error> {
|
||||
self.write(string).map_err(|_| fmt::Error)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user