orange's学习--第七章:c键盘中断处理缓冲区

8042的输入缓冲区大小只有一个字节,所以当一个扫描码有不止一个字符时,实际上会产生不止一次中断。也就是说,如果我们按一下Shift+A,产生的0x2A0x1E0x9E0xAA是4次中断接收来的。这就给我们的程序实现带来了困难,因为第一次中断时收到的0x2A无法让我们知道用户最终会完成什么,说不定是按下Shift又释放,也可能是Shift+Z而不是Shift+A。 

于是,当接收到类似0x2A这样的值的时候,需要先把它保存起来,在随后的过程中慢慢解析用户到底做了什么。 

在这里,向前辈学习,建立一个缓冲区,让keyboard_handler将每次收到的扫描码放入这个缓冲区,然后建立一个新的任务专门用来解析它们并做相应处理。 

键盘程序处理架构:

用户按下键盘-->触发键盘中断处理程序(把按键的扫描码存储到键盘缓冲区)

添加一个系统进程tty(操作系统会不停的调度到它)-->从键盘缓冲区读出数据

/*======================================================================*
                           init_keyboard
*======================================================================*/
PUBLIC void init_keyboard()
{
    kb_in.count = 0;
    kb_in.p_head = kb_in.p_tail = kb_in.buf;

        put_irq_handler(KEYBOARD_IRQ, keyboard_handler);/*设定键盘中断处理程序*/
        enable_irq(KEYBOARD_IRQ);                       /*开键盘中断*/
}

/*======================================================================*
                            keyboard_handler
 *======================================================================*/
PUBLIC void keyboard_handler(int irq)
{
    u8 scan_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()
{
    u8 scan_code;

    if(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();

        disp_int(scan_code);
    }

}

/*======================================================================*
                           task_tty
 *======================================================================*/
PUBLIC void task_tty()
{
    while (1) {
        keyboard_read();    //调用其他文件的函数处理
    }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值