在task_table 中增加一项
PUBLIC TASK task_table[NR_TASKS]= {
{task_tty, STACK_SIZE_TTY, "tty"}};
/*======================================================================*
task_tty
*======================================================================*/
PUBLIC void task_tty()
{
TTY* p_tty;
init_keyboard(); //初始化键盘缓冲区,指定中断号和其对应的中断处理程序,打开该中断
for(p_tty=TTY_FIRST;p_tty
init_tty(p_tty); //将tty和其console对应,初始化屏幕
}
select_console(0);
while(1) {
for(p_tty=TTY_FIRST;p_tty
tty_do_read(p_tty);
tty_do_write(p_tty);//从对应的console缓冲区中读出字符,并将其放入显存
}
}
}
/*======================================================================*
init_tty
*======================================================================*/
PRIVATE void init_tty(TTY* p_tty)
{
p_tty->inbuf_count= 0;
p_tty->p_inbuf_head= p_tty->p_inbuf_tail = p_tty->in_buf;
init_screen(p_tty);
}
/*======================================================================*
tty_do_read
*======================================================================*/
PRIVATE void tty_do_read(TTY* p_tty)
{
if(is_current_console(p_tty->p_console)) {//若为当前控制台则
keyboard_read(p_tty);//将键盘的扫描码从缓冲区读出来并解析为用户真正想要的输入,然后调用in_process(key)对输入进行处理
}
}
/*======================================================================*
tty_do_write
*======================================================================*/
PRIVATE void tty_do_write(TTY* p_tty)
{
if(p_tty->inbuf_count) {
charch = *(p_tty->p_inbuf_tail);
p_tty->p_inbuf_tail++;
if(p_tty->p_inbuf_tail == p_tty->in_buf + TTY_IN_BYTES) {
p_tty->p_inbuf_tail= p_tty->in_buf;
}
p_tty->inbuf_count--;
out_char(p_tty->p_console, ch); //将一个字符放在显存中的对应位置,此函数在console .c中
}
}
/*======================================================================*
/*======================================================================*
in_process
*======================================================================*/
PUBLIC void in_process(TTY* p_tty, u32 key)
{
char output[2] = {'\0', '\0'};
if (!(key & FLAG_EXT)) {
put_key(p_tty,key);
}
else {
int raw_code = key &MASK_RAW;
switch(raw_code) {
case ENTER:
put_key(p_tty,'\n');
break;
case BACKSPACE:
put_key(p_tty,'\b');
break;
case UP:
if ((key &FLAG_SHIFT_L) || (key & FLAG_SHIFT_R)) {
scroll_screen(p_tty->p_console,SCR_DN);
}
break;
caseDOWN:
if((key & FLAG_SHIFT_L) || (key & FLAG_SHIFT_R)) {
scroll_screen(p_tty->p_console,SCR_UP);
}
break;
caseF1:
caseF2:
caseF3:
caseF4:
caseF5:
caseF6:
caseF7:
caseF8:
caseF9:
case F10:
caseF11:
caseF12:
/*Alt + F1~F12 */
if((key & FLAG_ALT_L) || (key & FLAG_ALT_R)) {
select_console(raw_code - F1);//选择控制台
}
break;
default:
break;
}
}
}
/*======================================================================*
put_key
*======================================================================*/
PRIVATE void put_key(TTY* p_tty, u32 key)
{
if(p_tty->inbuf_count < TTY_IN_BYTES) {
*(p_tty->p_inbuf_head)= key;
p_tty->p_inbuf_head++;
if(p_tty->p_inbuf_head == p_tty->in_buf + TTY_IN_BYTES) {
p_tty->p_inbuf_head= p_tty->in_buf;
}
p_tty->inbuf_count++;
}
}
tty_write
*======================================================================*/
PUBLIC void tty_write(TTY* p_tty, char*buf, int len)
{
char* p = buf;
int i = len;
while (i) {
out_char(p_tty->p_console,*p++);
i--;
}
}
/*======================================================================*
sys_write
*======================================================================*/
PUBLIC int sys_write(char* buf, int len,PROCESS* p_proc)
{
tty_write(&tty_table[p_proc->nr_tty], buf, len);
return 0;
}
Keyboard 的内容
/*======================================================================*
init_keyboard
*======================================================================*/
PUBLIC void init_keyboard()
{
kb_in.count= 0;
kb_in.p_head= kb_in.p_tail = kb_in.buf;
shift_l = shift_r = 0;
alt_l = alt_r = 0;
ctrl_l = ctrl_r = 0;
caps_lock = 0;
num_lock = 1;
scroll_lock= 0;
set_leds();
put_irq_handler(KEYBOARD_IRQ, keyboard_handler);/*设定键盘中断处理程序*/
enable_irq(KEYBOARD_IRQ); /*开键盘中断*/
}
/*======================================================================*
keyboard_handler 读入到键盘缓冲区
*======================================================================*/
PUBLIC void keyboard_handler(int irq)
{
u8scan_code = in_byte(KB_DATA);
if(kb_in.count < KB_IN_BYTES) {
*(kb_in.p_head)= scan_code;
kb_in.p_head++;
if(kb_in.p_head == kb_in.buf + KB_IN_BYTES) {
kb_in.p_head= kb_in.buf;
}
kb_in.count++;
}
}
/*======================================================================*
keyboard_read
*======================================================================*/
PUBLIC void keyboard_read(TTY* p_tty)
{
u8 scan_code;
char output[2];
int make; /*1: make; 0: break. */
u32 key = 0;/* 用一个整型来表示一个键。比如,如果 Home 被按下,
* 则 key 值将为定义在keyboard.h 中的 'HOME'。
*/
u32* keyrow; /*指向 keymap[] 的某一行 */
if(kb_in.count> 0){
code_with_E0= 0;
scan_code= get_byte_from_kbuf();
/* 下面开始解析扫描码 */一部分省略了
if(scan_code == 0xE1) {
inti;
u8pausebrk_scode[] = {0xE1, 0x1D, 0x45,
0xE1, 0x9D, 0xC5};
intis_pausebreak = 1;
for(i=1;i<6;i++){
if(get_byte_from_kbuf() != pausebrk_scode[i]) {
is_pausebreak= 0;
break;
}
}
if(is_pausebreak) {
key= PAUSEBREAK;
}
}
elseif (scan_code == 0xE0) {
scan_code= get_byte_from_kbuf();
/*PrintScreen 被按下 */
if(scan_code == 0x2A) {
if(get_byte_from_kbuf() == 0xE0) {
if(get_byte_from_kbuf() == 0x37) {
key= PRINTSCREEN;
make= 1;
}
}
}
/*PrintScreen 被释放 */
if(scan_code == 0xB7) {
if(get_byte_from_kbuf() == 0xE0) {
if(get_byte_from_kbuf() == 0xAA) {
key= PRINTSCREEN;
make= 0;
}
}
}
/*不是PrintScreen,此时scan_code为0xE0紧跟的那个值. */
if(key == 0) {
code_with_E0= 1;
}
}
if((key != PAUSEBREAK) && (key != PRINTSCREEN)) {
/*首先判断Make Code 还是 Break Code */
make= (scan_code & FLAG_BREAK ? 0 : 1);
……..
default:
break;
}
in_process(p_tty, key);
}
}
}
}
/*======================================================================*
get_byte_from_kbuf
*======================================================================*/
PRIVATE u8 get_byte_from_kbuf() /* 从键盘缓冲区中读取下一个字节 */
{
u8 scan_code;
while (kb_in.count <= 0) {} /* 等待下一个字节到来 */
disable_int();
scan_code = *(kb_in.p_tail);
kb_in.p_tail++;
if (kb_in.p_tail == kb_in.buf + KB_IN_BYTES) {
kb_in.p_tail = kb_in.buf;
}
kb_in.count--;
enable_int();
returnscan_code;
}