mirror of
https://github.com/rcore-os/rCore-Tutorial-v3.git
synced 2024-11-22 01:16:26 +04:00
add get input_dev events in user app, but still have some problems
This commit is contained in:
parent
9d59a8271f
commit
c3ce372404
@ -13,7 +13,9 @@ buddy_system_allocator = "0.6"
|
|||||||
bitflags = "1.2.1"
|
bitflags = "1.2.1"
|
||||||
xmas-elf = "0.7.0"
|
xmas-elf = "0.7.0"
|
||||||
volatile = "0.3"
|
volatile = "0.3"
|
||||||
virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "4ee80e5" }
|
#virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "4ee80e5" }
|
||||||
|
virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "70b5850" }
|
||||||
|
|
||||||
easy-fs = { path = "../easy-fs" }
|
easy-fs = { path = "../easy-fs" }
|
||||||
virtio-input-decoder = "0.1.4"
|
virtio-input-decoder = "0.1.4"
|
||||||
embedded-graphics = "0.7.1"
|
embedded-graphics = "0.7.1"
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
use crate::drivers::bus::virtio::VirtioHal;
|
use crate::drivers::bus::virtio::VirtioHal;
|
||||||
use crate::sync::UPIntrFreeCell;
|
use crate::sync::{Condvar, UPIntrFreeCell};
|
||||||
|
use crate::task::schedule;
|
||||||
|
use alloc::collections::BTreeMap;
|
||||||
|
use alloc::collections::VecDeque;
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
use core::any::Any;
|
use core::any::Any;
|
||||||
use virtio_drivers::{VirtIOHeader, VirtIOInput};
|
use virtio_drivers::{VirtIOHeader, VirtIOInput};
|
||||||
@ -8,50 +11,113 @@ use virtio_input_decoder::{Decoder, Key, KeyType};
|
|||||||
const VIRTIO5: usize = 0x10005000;
|
const VIRTIO5: usize = 0x10005000;
|
||||||
const VIRTIO6: usize = 0x10006000;
|
const VIRTIO6: usize = 0x10006000;
|
||||||
|
|
||||||
struct VirtIOInputWrapper(UPIntrFreeCell<VirtIOInput<'static, VirtioHal>>);
|
struct VirtIOInputInner {
|
||||||
|
virtio_input: VirtIOInput<'static, VirtioHal>,
|
||||||
|
events: VecDeque<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct VirtIOInputWrapper {
|
||||||
|
inner: UPIntrFreeCell<VirtIOInputInner>,
|
||||||
|
//condvars: BTreeMap<u16, Condvar>,
|
||||||
|
//condvar: Arc::<Condvar> ,
|
||||||
|
condvar:Condvar,
|
||||||
|
}
|
||||||
|
|
||||||
pub trait InputDevice: Send + Sync + Any {
|
pub trait InputDevice: Send + Sync + Any {
|
||||||
|
fn read_event(&self) -> u64;
|
||||||
fn handle_irq(&self);
|
fn handle_irq(&self);
|
||||||
|
// fn events(&self) -> &VecDeque<u64>;
|
||||||
|
fn is_empty(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static::lazy_static!(
|
lazy_static::lazy_static!(
|
||||||
pub static ref KEYBOARD_DEVICE: Arc<dyn InputDevice> = Arc::new(VirtIOInputWrapper::new(VIRTIO5));
|
pub static ref KEYBOARD_DEVICE: Arc<dyn InputDevice> = Arc::new(VirtIOInputWrapper::new(VIRTIO5));
|
||||||
pub static ref MOUSE_DEVICE: Arc<dyn InputDevice> = Arc::new(VirtIOInputWrapper::new(VIRTIO6));
|
pub static ref MOUSE_DEVICE: Arc<dyn InputDevice> = Arc::new(VirtIOInputWrapper::new(VIRTIO6));
|
||||||
|
// pub static ref INPUT_CONDVAR: Arc::<Condvar> = Arc::new(Condvar::new());
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// from virtio-drivers/src/input.rs
|
||||||
|
//const QUEUE_SIZE: u16 = 32;
|
||||||
|
// pub fn read_input_event() -> u64 {
|
||||||
|
// loop {
|
||||||
|
|
||||||
|
// //let mut inner = self.inner.exclusive_access();
|
||||||
|
// let kb=KEYBOARD_DEVICE.clone();
|
||||||
|
// let evs = kb.events();
|
||||||
|
// if let Some(event) = evs.pop_front() {
|
||||||
|
// return event;
|
||||||
|
// } else {
|
||||||
|
// let task_cx_ptr = INPUT_CONDVAR.clone().wait_no_sched();
|
||||||
|
// drop(inner);
|
||||||
|
// schedule(task_cx_ptr);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
impl VirtIOInputWrapper {
|
impl VirtIOInputWrapper {
|
||||||
pub fn new(addr: usize) -> Self {
|
pub fn new(addr: usize) -> Self {
|
||||||
Self(unsafe {
|
let inner = VirtIOInputInner {
|
||||||
UPIntrFreeCell::new(
|
virtio_input: unsafe {
|
||||||
VirtIOInput::<VirtioHal>::new(&mut *(addr as *mut VirtIOHeader)).unwrap(),
|
VirtIOInput::<VirtioHal>::new(&mut *(addr as *mut VirtIOHeader)).unwrap()
|
||||||
)
|
},
|
||||||
})
|
events: VecDeque::new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// let mut condvars = BTreeMap::new();
|
||||||
|
// let channels = QUEUE_SIZE;
|
||||||
|
// for i in 0..channels {
|
||||||
|
// let condvar = Condvar::new();
|
||||||
|
// condvars.insert(i, condvar);
|
||||||
|
// }
|
||||||
|
|
||||||
|
Self {
|
||||||
|
inner: unsafe { UPIntrFreeCell::new(inner) },
|
||||||
|
//condvar: INPUT_CONDVAR.clone(),
|
||||||
|
condvar: Condvar::new(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputDevice for VirtIOInputWrapper {
|
impl InputDevice for VirtIOInputWrapper {
|
||||||
fn handle_irq(&self) {
|
fn is_empty(&self) -> bool {
|
||||||
let mut input = self.0.exclusive_access();
|
self.inner.exclusive_access().events.is_empty()
|
||||||
input.ack_interrupt();
|
}
|
||||||
while let Some(event) = input.pop_pending_event() {
|
|
||||||
let dtype = match Decoder::decode(
|
fn read_event(&self) -> u64 {
|
||||||
event.event_type as usize,
|
loop {
|
||||||
event.code as usize,
|
let mut inner = self.inner.exclusive_access();
|
||||||
event.value as usize,
|
if let Some(event) = inner.events.pop_front() {
|
||||||
) {
|
return event;
|
||||||
Ok(dtype) => dtype,
|
} else {
|
||||||
Err(_) => break,
|
let task_cx_ptr = self.condvar.wait_no_sched();
|
||||||
};
|
drop(inner);
|
||||||
match dtype {
|
schedule(task_cx_ptr);
|
||||||
virtio_input_decoder::DecodeType::Key(key, r#type) => {
|
|
||||||
if r#type == KeyType::Press {
|
|
||||||
match key {
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fn events(&self) -> &VecDeque<u64> {
|
||||||
|
// &self.inner.exclusive_access().events
|
||||||
|
// }
|
||||||
|
|
||||||
|
fn handle_irq(&self) {
|
||||||
|
let mut count = 0;
|
||||||
|
let mut result = 0;
|
||||||
|
let mut key = 0;
|
||||||
|
self.inner.exclusive_session(|inner| {
|
||||||
|
inner.virtio_input.ack_interrupt();
|
||||||
|
while let Some((token, event)) = inner.virtio_input.pop_pending_event() {
|
||||||
|
count += 1;
|
||||||
|
key = token;
|
||||||
|
result = (event.event_type as u64) << 48
|
||||||
|
| (event.code as u64) << 32
|
||||||
|
| (event.value) as u64;
|
||||||
|
inner.events.push_back(result);
|
||||||
|
println!("[KERN] inputdev_handle_irq: event: {:x}", result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if count > 0 {
|
||||||
|
//self.condvars.get(&key).unwrap().signal();
|
||||||
|
self.condvar.signal();
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
#![feature(panic_info_message)]
|
#![feature(panic_info_message)]
|
||||||
#![feature(alloc_error_handler)]
|
#![feature(alloc_error_handler)]
|
||||||
|
|
||||||
|
//use crate::drivers::{GPU_DEVICE, KEYBOARD_DEVICE, MOUSE_DEVICE, INPUT_CONDVAR};
|
||||||
use crate::drivers::{GPU_DEVICE, KEYBOARD_DEVICE, MOUSE_DEVICE};
|
use crate::drivers::{GPU_DEVICE, KEYBOARD_DEVICE, MOUSE_DEVICE};
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
@ -59,6 +59,7 @@ pub fn rust_main() -> ! {
|
|||||||
UART.init();
|
UART.init();
|
||||||
println!("KERN: init gpu");
|
println!("KERN: init gpu");
|
||||||
let _gpu = GPU_DEVICE.clone();
|
let _gpu = GPU_DEVICE.clone();
|
||||||
|
//let _input_condvar = INPUT_CONDVAR.clone();
|
||||||
println!("KERN: init keyboard");
|
println!("KERN: init keyboard");
|
||||||
let _keyboard = KEYBOARD_DEVICE.clone();
|
let _keyboard = KEYBOARD_DEVICE.clone();
|
||||||
println!("KERN: init mouse");
|
println!("KERN: init mouse");
|
||||||
|
17
os/src/syscall/input.rs
Normal file
17
os/src/syscall/input.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
//use crate::drivers::{KEYBOARD_DEVICE,MOUSE_DEVICE,INPUT_CONDVAR,read_input_event};
|
||||||
|
use crate::drivers::{KEYBOARD_DEVICE,MOUSE_DEVICE};
|
||||||
|
|
||||||
|
pub fn sys_event_get() ->isize {
|
||||||
|
let kb = KEYBOARD_DEVICE.clone();
|
||||||
|
let mouse = MOUSE_DEVICE.clone();
|
||||||
|
//let input=INPUT_CONDVAR.clone();
|
||||||
|
//read_input_event() as isize
|
||||||
|
if !kb.is_empty(){
|
||||||
|
kb.read_event() as isize
|
||||||
|
} else if !mouse.is_empty() {
|
||||||
|
mouse.read_event() as isize
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -27,18 +27,21 @@ const SYSCALL_CONDVAR_SIGNAL: usize = 1031;
|
|||||||
const SYSCALL_CONDVAR_WAIT: usize = 1032;
|
const SYSCALL_CONDVAR_WAIT: usize = 1032;
|
||||||
const SYSCALL_FRAMEBUFFER: usize = 2000;
|
const SYSCALL_FRAMEBUFFER: usize = 2000;
|
||||||
const SYSCALL_FRAMEBUFFER_FLUSH: usize = 2001;
|
const SYSCALL_FRAMEBUFFER_FLUSH: usize = 2001;
|
||||||
|
const SYSCALL_EVENT_GET: usize = 3000;
|
||||||
|
|
||||||
mod fs;
|
mod fs;
|
||||||
mod process;
|
mod process;
|
||||||
mod sync;
|
mod sync;
|
||||||
mod thread;
|
mod thread;
|
||||||
mod gui;
|
mod gui;
|
||||||
|
mod input;
|
||||||
|
|
||||||
use fs::*;
|
use fs::*;
|
||||||
use process::*;
|
use process::*;
|
||||||
use sync::*;
|
use sync::*;
|
||||||
use thread::*;
|
use thread::*;
|
||||||
use gui::*;
|
use gui::*;
|
||||||
|
use input::*;
|
||||||
|
|
||||||
pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
|
pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
|
||||||
match syscall_id {
|
match syscall_id {
|
||||||
@ -71,6 +74,7 @@ pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
|
|||||||
SYSCALL_CONDVAR_WAIT => sys_condvar_wait(args[0], args[1]),
|
SYSCALL_CONDVAR_WAIT => sys_condvar_wait(args[0], args[1]),
|
||||||
SYSCALL_FRAMEBUFFER => sys_framebuffer(),
|
SYSCALL_FRAMEBUFFER => sys_framebuffer(),
|
||||||
SYSCALL_FRAMEBUFFER_FLUSH => sys_framebuffer_flush(),
|
SYSCALL_FRAMEBUFFER_FLUSH => sys_framebuffer_flush(),
|
||||||
|
SYSCALL_EVENT_GET => sys_event_get(),
|
||||||
_ => panic!("Unsupported syscall_id: {}", syscall_id),
|
_ => panic!("Unsupported syscall_id: {}", syscall_id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
21
user/src/bin/inputdev_event.rs
Normal file
21
user/src/bin/inputdev_event.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
use user_lib::{event_get};
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate user_lib;
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn main() -> i32 {
|
||||||
|
println!("Input device event test");
|
||||||
|
let mut event=0;
|
||||||
|
for _ in 0..3 {
|
||||||
|
while event==0 {
|
||||||
|
event = event_get();
|
||||||
|
}
|
||||||
|
println!("event: {:?}", event);
|
||||||
|
}
|
||||||
|
|
||||||
|
0
|
||||||
|
}
|
@ -205,6 +205,11 @@ pub fn framebuffer_flush() -> isize {
|
|||||||
sys_framebuffer_flush()
|
sys_framebuffer_flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn event_get() -> isize {
|
||||||
|
sys_event_get()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! vstore {
|
macro_rules! vstore {
|
||||||
($var_ref: expr, $value: expr) => {
|
($var_ref: expr, $value: expr) => {
|
||||||
|
@ -27,6 +27,7 @@ const SYSCALL_CONDVAR_SIGNAL: usize = 1031;
|
|||||||
const SYSCALL_CONDVAR_WAIT: usize = 1032;
|
const SYSCALL_CONDVAR_WAIT: usize = 1032;
|
||||||
const SYSCALL_FRAMEBUFFER: usize = 2000;
|
const SYSCALL_FRAMEBUFFER: usize = 2000;
|
||||||
const SYSCALL_FRAMEBUFFER_FLUSH: usize = 2001;
|
const SYSCALL_FRAMEBUFFER_FLUSH: usize = 2001;
|
||||||
|
const SYSCALL_EVENT_GET: usize = 3000;
|
||||||
|
|
||||||
fn syscall(id: usize, args: [usize; 3]) -> isize {
|
fn syscall(id: usize, args: [usize; 3]) -> isize {
|
||||||
let mut ret: isize;
|
let mut ret: isize;
|
||||||
@ -164,4 +165,8 @@ pub fn sys_framebuffer() -> isize {
|
|||||||
|
|
||||||
pub fn sys_framebuffer_flush() -> isize {
|
pub fn sys_framebuffer_flush() -> isize {
|
||||||
syscall(SYSCALL_FRAMEBUFFER_FLUSH, [0, 0, 0])
|
syscall(SYSCALL_FRAMEBUFFER_FLUSH, [0, 0, 0])
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sys_event_get() -> isize {
|
||||||
|
syscall(SYSCALL_EVENT_GET, [0, 0, 0])
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user