summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortaitep <taitep@taitep.se>2025-12-21 21:25:29 +0100
committertaitep <taitep@taitep.se>2025-12-21 21:25:29 +0100
commit24dcf5d5bd0beac3d4785a618c8f9c86840031d1 (patch)
tree273303cf629139e3f2a269827d8422592c316695
parent209e44ae64a1af10063b1c589377e136c644ec8f (diff)
Improve UART by using nonblocking stdin
-rw-r--r--Cargo.lock31
-rw-r--r--Cargo.toml1
-rw-r--r--src/basic_uart.rs48
3 files changed, 54 insertions, 26 deletions
diff --git a/Cargo.lock b/Cargo.lock
index a77c839..8ff751b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -9,6 +9,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
[[package]]
+name = "bitflags"
+version = "2.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
+
+[[package]]
+name = "cfg_aliases"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
+
+[[package]]
name = "libc"
version = "0.2.176"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -24,9 +42,22 @@ dependencies = [
]
[[package]]
+name = "nix"
+version = "0.30.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
+dependencies = [
+ "bitflags",
+ "cfg-if",
+ "cfg_aliases",
+ "libc",
+]
+
+[[package]]
name = "trve"
version = "0.0.0"
dependencies = [
"anyhow",
"memmap2",
+ "nix",
]
diff --git a/Cargo.toml b/Cargo.toml
index 003b0b5..c4c3ece 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -6,3 +6,4 @@ edition = "2024"
[dependencies]
anyhow = "1.0.100"
memmap2 = "0.9.8"
+nix = { version = "0.30.1", features = ["fs"] }
diff --git a/src/basic_uart.rs b/src/basic_uart.rs
index 3c9e064..f178574 100644
--- a/src/basic_uart.rs
+++ b/src/basic_uart.rs
@@ -1,30 +1,35 @@
use std::collections::VecDeque;
-use std::io::{Read, stdin};
+use std::io;
+use std::os::fd::AsFd;
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
+use nix::fcntl::fcntl;
+use nix::fcntl::{FcntlArg, OFlag};
use trve::consts::{Byte, DWord, HWord, Word};
use trve::mem::{MemAccessFault, MemDeviceInterface, PageNum};
/// byte 0: rx/tx
/// byte 1: status (------rt, r=rxready, t=txready)/none
pub struct BasicUart {
- buffers: Mutex<UartBuffers>,
-}
-
-struct UartBuffers {
- rx: VecDeque<u8>,
- tx: VecDeque<u8>,
+ rx_buf: Mutex<VecDeque<u8>>,
}
impl BasicUart {
pub fn new() -> Self {
+ // Make sure stdin is nonblocking
+ let stdin = io::stdin();
+ let fd = stdin.as_fd();
+ let flags = fcntl(fd, FcntlArg::F_GETFL).unwrap();
+ fcntl(
+ fd,
+ FcntlArg::F_SETFL(OFlag::from_bits_truncate(flags) | OFlag::O_NONBLOCK),
+ )
+ .unwrap();
+
BasicUart {
- buffers: Mutex::new(UartBuffers {
- rx: VecDeque::new(),
- tx: VecDeque::new(),
- }),
+ rx_buf: Mutex::new(VecDeque::new()),
}
}
@@ -44,32 +49,23 @@ impl BasicUart {
}
fn write(&self, byte: u8) {
- let mut bufs = self.buffers.lock().unwrap();
- bufs.tx.push_back(byte);
+ print!("{}", byte as char);
}
fn read(&self) -> u8 {
- let mut bufs = self.buffers.lock().unwrap();
- bufs.rx.pop_front().unwrap_or(0)
+ self.rx_buf.lock().unwrap().pop_front().unwrap_or(0)
}
fn can_read(&self) -> bool {
- let bufs = self.buffers.lock().unwrap();
- !bufs.rx.is_empty()
+ !self.rx_buf.lock().unwrap().is_empty()
}
pub fn poll(&self) {
- let mut bufs = self.buffers.lock().unwrap();
-
- while let Some(byte) = bufs.tx.pop_front() {
- print!("{}", byte as char);
- }
+ let mut rx_buf = self.rx_buf.lock().unwrap();
let mut buffer = [0u8; 1];
- if let Ok(n) = stdin().read(&mut buffer) {
- if n > 0 {
- bufs.rx.push_back(buffer[0]);
- }
+ while let Ok(1) = nix::unistd::read(io::stdin().as_fd(), &mut buffer) {
+ rx_buf.push_back(buffer[0]);
}
}
}