0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
-// TODO 改造成环形缓冲区
uint8_t kbd_scan_code;
void kbd_bh_handler(void* arg) {
kbd_debug(kbd_scan_code);
vt_keyboard_input(ch);
}
+uint64_t kbd_irq_cnt = 0;
void kbd_handler(unsigned int irq, pt_regs_t* regs, void* dev_id) {
kbd_scan_code = inb(0x60);
+ kbd_irq_cnt++;
add_irq_bh_handler(kbd_bh_handler, NULL);
}
-uint64_t kbd_irq_cnt = 0;
void kbd_debug(uint8_t scan_code) {
- kbd_irq_cnt++;
-
switch (scan_code) {
case 0x01: // Esc
break;
#pragma once
#include <types.h>
+#include <wait.h>
+#include <semaphore.h>
#define TTY_MAX_NAME_LEN 32
#define TTY_MAX_COUNT 8
uint8_t in_buf[TTY_MAX_IN_BUF_SIZE];
int ib_head;
int ib_tail;
+ mutex_t ib_mutex;
+ wait_queue_head_t ib_wait;
tty_ops_t* ops;
void* private;
tty->ib_head = 0;
tty->ib_tail = 0;
+ mutex_init(&tty->ib_mutex);
+ init_wait_queue_head(&tty->ib_wait);
tty->ops = &vt_tty_ops;
return 0;
}
+bool _tty_ib_empty(tty_t* tty) {
+ return tty->ib_head == tty->ib_tail;
+}
+
int tty_read(tty_t* tty, char* buf, size_t size) {
assert(tty != NULL);
return -EINVAL;
}
- // TODO
+ size_t n = 0;
- return 0;
+ // 防多进程同时读取输入缓冲区
+ mutex_lock(&tty->ib_mutex);
+ while (true) {
+ unsigned long eflags;
+ irq_save(eflags);
+
+ // 如果输入缓冲区为空,则继续等待
+ if (_tty_ib_empty(tty)) {
+ irq_restore(eflags);
+ mutex_unlock(&tty->ib_mutex);
+ wait_event(&tty->ib_wait, !_tty_ib_empty(tty));
+ mutex_lock(&tty->ib_mutex);
+ continue;
+ }
+
+ irq_restore(eflags);
+
+ // 如果输入缓冲区不为空,则读取输入缓冲区
+ for (n = 0; n < size; n++) {
+ irq_save(eflags);
+
+ if (_tty_ib_empty(tty)) {
+ break;
+ }
+
+ buf[n] = tty->in_buf[tty->ib_tail];
+ tty->ib_tail += 1;
+ tty->ib_tail %= TTY_MAX_IN_BUF_SIZE;
+
+ irq_restore(eflags);
+ }
+
+ break;
+ }
+
+ mutex_unlock(&tty->ib_mutex);
+
+ return n;
}
int tty_input(tty_t* tty, uint8_t c) {
assert(tty != NULL);
+ unsigned long eflags;
+ irq_save(eflags);
+
int next = (tty->ib_head + 1) % TTY_MAX_IN_BUF_SIZE;
if (next == tty->ib_tail) {
+ irq_restore(eflags);
return 0;
}
tty->in_buf[tty->ib_head] = c;
tty->ib_head = next;
+ irq_restore(eflags);
+
// 目前先总是回显
tty_write(tty, (const char*)&c, 1);
- // TODO: 唤醒读进程
+ // 唤醒读进程
+ wake_up(&tty->ib_wait);
return 1;
}
\ No newline at end of file
}
break;
case 's':
- p += write_buf(p, (const char*)va_arg(args, char*), char_fill, char_cnt, align);
+ p += write_buf(p, (const char*)va_arg(args, char*), char_fill, char_cnt, align);
break;
case 'u':
itou(tmp, va_arg(args, uint32_t));