mirror of
https://github.com/AmbiML/sparrow-kata-full.git
synced 2025-09-01 13:36:14 +00:00
Merge "Aligns UART API with Rust Read and Write"
GitOrigin-RevId: df407ae4bddb75b1bc43c35062947679c2b10c3a
This commit is contained in:
@@ -10,12 +10,10 @@ component DebugConsole {
|
||||
control;
|
||||
|
||||
dataport Buf tx_dataport;
|
||||
uses dataport_io_inf uart_tx;
|
||||
has mutex tx_mutex;
|
||||
uses rust_write_inf uart_write;
|
||||
|
||||
dataport Buf rx_dataport;
|
||||
uses dataport_io_inf uart_rx;
|
||||
has mutex rx_mutex;
|
||||
uses rust_read_inf uart_read;
|
||||
|
||||
provides LoggerInterface logger;
|
||||
uses ProcessControlInterface proc_ctrl;
|
||||
|
@@ -44,7 +44,7 @@ pub extern "C" fn pre_init() {
|
||||
#[no_mangle]
|
||||
pub extern "C" fn run() -> ! {
|
||||
trace!("run");
|
||||
let mut tx = kata_uart_client::Tx {};
|
||||
let mut rx = kata_uart_client::Rx {};
|
||||
let mut tx = kata_uart_client::Tx::new();
|
||||
let mut rx = kata_uart_client::Rx::new();
|
||||
kata_shell::repl(&mut tx, &mut rx);
|
||||
}
|
||||
|
@@ -4,19 +4,6 @@ use core::fmt::Write;
|
||||
use cstr_core::CStr;
|
||||
use kata_io as io;
|
||||
|
||||
// C interface to external UART driver.
|
||||
extern "C" {
|
||||
static rx_dataport: *mut cty::c_uchar;
|
||||
fn uart_rx_update(n: cty::size_t);
|
||||
fn rx_mutex_lock();
|
||||
fn rx_mutex_unlock();
|
||||
|
||||
static tx_dataport: *mut cty::c_uchar;
|
||||
fn uart_tx_update(n: cty::size_t);
|
||||
fn tx_mutex_lock();
|
||||
fn tx_mutex_unlock();
|
||||
}
|
||||
|
||||
// Console logging interface.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn logger_log(level: u8, msg: *const cstr_core::c_char) {
|
||||
@@ -30,44 +17,83 @@ pub extern "C" fn logger_log(level: u8, msg: *const cstr_core::c_char) {
|
||||
};
|
||||
if l <= log::max_level() {
|
||||
// TODO(sleffler): is the uart driver ok w/ multiple writers?
|
||||
let output: &mut dyn io::Write = &mut self::Tx {};
|
||||
let output: &mut dyn io::Write = &mut self::Tx::new();
|
||||
unsafe {
|
||||
let _ = writeln!(output, "{}", CStr::from_ptr(msg).to_str().unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Rx {}
|
||||
const DATAPORT_SIZE: usize = 4096;
|
||||
|
||||
pub struct Rx {
|
||||
dataport: &'static [u8],
|
||||
}
|
||||
|
||||
impl Rx {
|
||||
pub fn new() -> Rx {
|
||||
extern "C" {
|
||||
static rx_dataport: *mut cty::c_uchar;
|
||||
}
|
||||
Rx {
|
||||
dataport: unsafe { core::slice::from_raw_parts(rx_dataport, DATAPORT_SIZE) },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Read for Rx {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
unsafe {
|
||||
rx_mutex_lock();
|
||||
uart_rx_update(buf.len());
|
||||
let port = core::slice::from_raw_parts(rx_dataport, buf.len());
|
||||
buf.copy_from_slice(&port);
|
||||
rx_mutex_unlock();
|
||||
extern "C" {
|
||||
fn uart_read_read(limit: cty::size_t) -> cty::c_int;
|
||||
}
|
||||
let n = unsafe { uart_read_read(buf.len()) };
|
||||
if n >= 0 {
|
||||
let s = n as usize;
|
||||
buf[..s].copy_from_slice(&self.dataport[..s]);
|
||||
Ok(s)
|
||||
} else {
|
||||
Err(io::Error)
|
||||
}
|
||||
Ok(buf.len())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Tx {}
|
||||
pub struct Tx {
|
||||
dataport: &'static mut [u8],
|
||||
}
|
||||
|
||||
impl Tx {
|
||||
pub fn new() -> Tx {
|
||||
extern "C" {
|
||||
static tx_dataport: *mut cty::c_uchar;
|
||||
}
|
||||
Tx {
|
||||
dataport: unsafe { core::slice::from_raw_parts_mut(tx_dataport, DATAPORT_SIZE) },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Write for Tx {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
unsafe {
|
||||
tx_mutex_lock();
|
||||
let port = core::slice::from_raw_parts_mut(tx_dataport, buf.len());
|
||||
port.copy_from_slice(buf);
|
||||
uart_tx_update(buf.len());
|
||||
tx_mutex_unlock();
|
||||
extern "C" {
|
||||
fn uart_write_write(available: cty::size_t) -> cty::c_int;
|
||||
}
|
||||
self.dataport[..buf.len()].copy_from_slice(buf);
|
||||
let n = unsafe { uart_write_write(buf.len()) };
|
||||
if n >= 0 {
|
||||
Ok(n as usize)
|
||||
} else {
|
||||
Err(io::Error)
|
||||
}
|
||||
Ok(buf.len())
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
// Do nothing. This implementation has no internal buffering.
|
||||
Ok(())
|
||||
extern "C" {
|
||||
fn uart_write_flush() -> cty::c_int;
|
||||
}
|
||||
if unsafe { uart_write_flush() } == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(io::Error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user