-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
522 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -52,5 +52,5 @@ pub trait LCDHL { | |
} | ||
``` | ||
|
||
LCD 是结构体,定义了 gpiohs | ||
LCD 用的是 SPI 总线, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
mod pipe; | ||
mod stdio; | ||
|
||
use crate::mmu::UserBuffer; | ||
pub trait File : Send + Sync { | ||
fn read(&self, buf: UserBuffer) -> usize; | ||
fn write(&self, buf: UserBuffer) -> usize; | ||
} | ||
|
||
pub use pipe::{Pipe, make_pipe}; | ||
pub use stdio::{Stdin, Stdout}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
use super::File; | ||
use alloc::sync::{Arc, Weak}; | ||
use spin::Mutex; | ||
use crate::mmu::{ | ||
UserBuffer, | ||
}; | ||
use crate::task::suspend_current_and_run_next; | ||
|
||
pub struct Pipe { | ||
readable: bool, | ||
writable: bool, | ||
buffer: Arc<Mutex<PipeRingBuffer>>, | ||
} | ||
|
||
impl Pipe { | ||
pub fn read_end_with_buffer(buffer: Arc<Mutex<PipeRingBuffer>>) -> Self { | ||
Self { | ||
readable: true, | ||
writable: false, | ||
buffer, | ||
} | ||
} | ||
pub fn write_end_with_buffer(buffer: Arc<Mutex<PipeRingBuffer>>) -> Self { | ||
Self { | ||
readable: false, | ||
writable: true, | ||
buffer, | ||
} | ||
} | ||
} | ||
|
||
const RING_BUFFER_SIZE: usize = 32; | ||
|
||
#[derive(Copy, Clone, PartialEq)] | ||
enum RingBufferStatus { | ||
FULL, | ||
EMPTY, | ||
NORMAL, | ||
} | ||
|
||
pub struct PipeRingBuffer { | ||
arr: [u8; RING_BUFFER_SIZE], | ||
head: usize, | ||
tail: usize, | ||
status: RingBufferStatus, | ||
write_end: Option<Weak<Pipe>>, | ||
} | ||
|
||
impl PipeRingBuffer { | ||
pub fn new() -> Self { | ||
Self { | ||
arr: [0; RING_BUFFER_SIZE], | ||
head: 0, | ||
tail: 0, | ||
status: RingBufferStatus::EMPTY, | ||
write_end: None, | ||
} | ||
} | ||
pub fn set_write_end(&mut self, write_end: &Arc<Pipe>) { | ||
self.write_end = Some(Arc::downgrade(write_end)); | ||
} | ||
pub fn write_byte(&mut self, byte: u8) { | ||
self.status = RingBufferStatus::NORMAL; | ||
self.arr[self.tail] = byte; | ||
self.tail = (self.tail + 1) % RING_BUFFER_SIZE; | ||
if self.tail == self.head { | ||
self.status = RingBufferStatus::FULL; | ||
} | ||
} | ||
pub fn read_byte(&mut self) -> u8 { | ||
self.status = RingBufferStatus::NORMAL; | ||
let c = self.arr[self.head]; | ||
self.head = (self.head + 1) % RING_BUFFER_SIZE; | ||
if self.head == self.tail { | ||
self.status = RingBufferStatus::EMPTY; | ||
} | ||
c | ||
} | ||
pub fn available_read(&self) -> usize { | ||
if self.status == RingBufferStatus::EMPTY { | ||
0 | ||
} else { | ||
if self.tail > self.head { | ||
self.tail - self.head | ||
} else { | ||
self.tail + RING_BUFFER_SIZE - self.head | ||
} | ||
} | ||
} | ||
pub fn available_write(&self) -> usize { | ||
if self.status == RingBufferStatus::FULL { | ||
0 | ||
} else { | ||
RING_BUFFER_SIZE - self.available_read() | ||
} | ||
} | ||
pub fn all_write_ends_closed(&self) -> bool { | ||
self.write_end.as_ref().unwrap().upgrade().is_none() | ||
} | ||
} | ||
|
||
/// Return (read_end, write_end) | ||
pub fn make_pipe() -> (Arc<Pipe>, Arc<Pipe>) { | ||
let buffer = Arc::new(Mutex::new(PipeRingBuffer::new())); | ||
let read_end = Arc::new( | ||
Pipe::read_end_with_buffer(buffer.clone()) | ||
); | ||
let write_end = Arc::new( | ||
Pipe::write_end_with_buffer(buffer.clone()) | ||
); | ||
buffer.lock().set_write_end(&write_end); | ||
(read_end, write_end) | ||
} | ||
|
||
impl File for Pipe { | ||
fn read(&self, buf: UserBuffer) -> usize { | ||
assert_eq!(self.readable, true); | ||
let mut buf_iter = buf.into_iter(); | ||
let mut read_size = 0usize; | ||
loop { | ||
let mut ring_buffer = self.buffer.lock(); | ||
let loop_read = ring_buffer.available_read(); | ||
if loop_read == 0 { | ||
if ring_buffer.all_write_ends_closed() { | ||
return read_size; | ||
} | ||
drop(ring_buffer); | ||
suspend_current_and_run_next(); | ||
continue; | ||
} | ||
// read at most loop_read bytes | ||
for _ in 0..loop_read { | ||
if let Some(byte_ref) = buf_iter.next() { | ||
unsafe { *byte_ref = ring_buffer.read_byte(); } | ||
read_size += 1; | ||
} else { | ||
return read_size; | ||
} | ||
} | ||
} | ||
} | ||
fn write(&self, buf: UserBuffer) -> usize { | ||
assert_eq!(self.writable, true); | ||
let mut buf_iter = buf.into_iter(); | ||
let mut write_size = 0usize; | ||
loop { | ||
let mut ring_buffer = self.buffer.lock(); | ||
let loop_write = ring_buffer.available_write(); | ||
if loop_write == 0 { | ||
drop(ring_buffer); | ||
suspend_current_and_run_next(); | ||
continue; | ||
} | ||
// write at most loop_write bytes | ||
for _ in 0..loop_write { | ||
if let Some(byte_ref) = buf_iter.next() { | ||
ring_buffer.write_byte(unsafe { *byte_ref }); | ||
write_size += 1; | ||
} else { | ||
return write_size; | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
use super::File; | ||
use crate::mmu::{UserBuffer}; | ||
use crate::scall_sbi::console_getchar; | ||
use crate::task::suspend_current_and_run_next; | ||
|
||
pub struct Stdin; | ||
|
||
pub struct Stdout; | ||
|
||
impl File for Stdin { | ||
fn read(&self, mut user_buf: UserBuffer) -> usize { | ||
assert_eq!(user_buf.len(), 1); | ||
// busy loop | ||
let mut c: usize; | ||
loop { | ||
c = console_getchar(); | ||
if c == 0 { | ||
suspend_current_and_run_next(); | ||
continue; | ||
} else { | ||
break; | ||
} | ||
} | ||
let ch = c as u8; | ||
unsafe { user_buf.buffers[0].as_mut_ptr().write_volatile(ch); } | ||
1 | ||
} | ||
fn write(&self, _user_buf: UserBuffer) -> usize { | ||
panic!("Cannot write to stdin!"); | ||
} | ||
} | ||
|
||
impl File for Stdout { | ||
fn read(&self, _user_buf: UserBuffer) -> usize{ | ||
panic!("Cannot read from stdout!"); | ||
} | ||
fn write(&self, user_buf: UserBuffer) -> usize { | ||
for buffer in user_buf.buffers.iter() { | ||
print!("{}", core::str::from_utf8(*buffer).unwrap()); | ||
} | ||
user_buf.len() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,7 @@ mod scall_sbi; | |
mod task; | ||
mod timer; | ||
mod trap; | ||
mod fs; | ||
|
||
// use k210_soc::sysctl::{self, clock}; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.