Skip to content

Commit

Permalink
add keyboard task
Browse files Browse the repository at this point in the history
  • Loading branch information
Gege-Wang committed Aug 23, 2024
1 parent 4055bb9 commit bb3952e
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 22 deletions.
36 changes: 20 additions & 16 deletions src/interrupts.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use futures_util::stream::StreamExt;
use crate::task::keyboard::ScancodeStream;
use crate::{gdt::DOUBLE_FAULT_IST_INDEX, print, println};
use lazy_static::lazy_static;
use pic8259::ChainedPics;
Expand Down Expand Up @@ -43,7 +45,7 @@ extern "x86-interrupt" fn timer_interrupt_handler(_stack_frame: InterruptStackFr
}

extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStackFrame) {
use pc_keyboard::{layouts, DecodedKey, HandleControl, Keyboard, ScancodeSet1};
use pc_keyboard::{layouts, HandleControl, Keyboard, ScancodeSet1};
use spin::Mutex;
use x86_64::instructions::port::Port;

Expand All @@ -55,23 +57,31 @@ extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStac
HandleControl::Ignore
));
}
let mut keyboard = KEYBOARD.lock();
let mut port = Port::new(0x60);
let scancode: u8 = unsafe { port.read() };

crate::task::keyboard::add_scancode(scancode);
// if let Ok(Some(key_event)) = keyboard.add_byte(scancode) {
// if let Some(key) = keyboard.process_keyevent(key_event) {
// match key {
// DecodedKey::Unicode(character) => print!("{}", character),
// DecodedKey::RawKey(key) => print!("{:?}", key),
// }
// }
// }
unsafe {
PICS.lock().notify_end_of_interrupt(PIC_1_OFFSET + 1 as u8);
}
}

pub async fn print_keypresses() {
use pc_keyboard::{layouts, DecodedKey, HandleControl, Keyboard, ScancodeSet1};

let mut keyboard = Keyboard::new(ScancodeSet1::new(), layouts::Us104Key, HandleControl::Ignore);
let mut scancodes = ScancodeStream::new();
while let Some(scancode) = scancodes.next().await {
if let Ok(Some(key_event)) = keyboard.add_byte(scancode) {
if let Some(key) = keyboard.process_keyevent(key_event) {
match key {
DecodedKey::Unicode(character) => print!("{}", character),
DecodedKey::RawKey(key) => print!("{:?}", key),
}
}
}
}
}
extern "x86-interrupt" fn page_fault_handler(
stack_frame: InterruptStackFrame,
error_code: PageFaultErrorCode,
Expand All @@ -85,12 +95,6 @@ extern "x86-interrupt" fn page_fault_handler(
crate::hlt_loop();
}

// #[test_case]
// fn test_breakpoint_exception() {
// // invoke a breakpoint exception
// x86_64::instructions::interrupts::int3();
// }

pub const PIC_1_OFFSET: u8 = 32;
pub const PIC_2_OFFSET: u8 = PIC_1_OFFSET + 8;

Expand Down
7 changes: 5 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ use alloc::rc::Rc;
use alloc::{task, vec};
use alloc::vec::Vec;
use bootloader::{entry_point, BootInfo};
use candy::{allocator, hlt_loop, memory, println};
use candy::{allocator, hlt_loop, interrupts, memory, println};
use core::panic::PanicInfo;
use candy::task::Task;
use candy::task::{keyboard, Task};
use candy::task::simple_executor::TaskQueue;

entry_point!(kernel_main);
Expand Down Expand Up @@ -47,8 +47,11 @@ fn kernel_main(boot_info: &'static BootInfo) -> ! {

let mut task_queue = TaskQueue::new();
task_queue.spawn(Task::new(example_async_function()));
task_queue.spawn(Task::new(interrupts::print_keypresses()));
task_queue.run();



#[cfg(test)]
test_main();

Expand Down
19 changes: 15 additions & 4 deletions src/task/keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@ use futures_util::stream::Stream;
use futures_util::task::Context;
use futures_util::task::Poll;
use core::pin::Pin;
use futures_util::task::AtomicWaker;

use crate::println;
static SCANCODE_QUEUE: OnceCell<ArrayQueue<u8>> = OnceCell::uninit();

static WAKER: AtomicWaker = AtomicWaker::new();
pub(crate) fn add_scancode(scancode: u8) {
if let Ok(queue) = SCANCODE_QUEUE.try_get() {
if let Err(_) = queue.push(scancode) {
println!("Scancode queue full; dropping keyboard input");
} else {
WAKER.wake();
}
} else {
println!("Scancode queue uninitialized; dropping keyboard input");
Expand All @@ -34,11 +37,19 @@ impl ScancodeStream {

impl Stream for ScancodeStream {
type Item = u8;
fn poll_next(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
fn poll_next(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<u8>> {
let queue = SCANCODE_QUEUE.try_get().expect("not initialized");
if let Some(scancode) = queue.pop() {
return Poll::Ready(Some(scancode));
}
WAKER.register(&cx.waker());
match queue.pop() {
Some(scancode) => Poll::Ready(Some(scancode)),
Some(scancode) => {
WAKER.take();
Poll::Ready(Some(scancode))

},
None => Poll::Pending,
}
}
}
}

0 comments on commit bb3952e

Please sign in to comment.