【0】README

0.1) source code and text decription are from orange’s implemention of a os , and for complete code , please visit 我待会上传;


【1】 键盘输入缓冲区

  • step1)缓冲区的数据结构如下:

  • step2)对缓冲区进行添加操作:(只是对 keyboard_handler 添加了一些代码, 上述荔枝图)

  • step3)修改后的init_keyboard

  • step4)初始化时钟中断


    【2】用添加的新任务处理键盘操作

  • 终端任务:我们的任务不仅会处理键盘操作、还会处理屏幕输出等内容, 这些操作共同组成同一个任务——终端任务;
  • keyboard_read():将扫描码从缓冲区读出,并打印;缓冲区的r_tail 指针移动, 而你是否记得将扫描码存入缓冲区 是 缓冲区的 head指针移动;


    【3】解析扫描码

    Attention:下面就是对 keyboard_read进行扩展了,像添加对小写字符,数字的处理, 后面是 F1~F12的键处理, shift键处理,home键的处理等等;

Conclusion)修改的代码内容包括:添加了键盘中断缓冲区的代码,修改了 keyboard_handler()函数 + init_keyboard()函数 + 对小写字母和数字的处理代码;

  • C1.1)我们给出修改后的代码调用过程(重点在于 keyboard_handler()函数 + init_keyboard()函数 ):

  • C1.2)如何取到用户键入的数据,以及显示它们;

  • C2)运行结果为:

3.1)处理shift、alt、ctrl
注意:要将键的左右两边加以区分,如左shift和右shift的功能是不同的;(上上图以及说明了)

3.2)处理所有按键

  • 存在的问题-Problems 和 解决方法Solutions:

  • Problem1)如果扫描码更加复杂一些,比如超过3个字符,如今的程序还不足以很好地处理;
    因为当一个扫描码有不止一个字符时, 实际上会产生不止一次中断。

    • 看个荔枝:如果我们按一下Shift + A,产生的 0x2A0x1E0x9E0xAA 是4次中断接收来的;

      • step1) 我们的键盘控制器8042 接收来自 键盘编码器8048 传送过来的键入数据的相应扫描码;
      • step2) 8042收到扫描码后,会把该扫描码 编码成 make code+break code的形式, 并将其放置到输入缓冲区中,而8042的 输入缓冲寄存器只有一个字节来存储扫描码;;
      • step3) 8042告诉 中断控制寄存器8259A 产生中断, 交给键盘中断处理程序去执行;(如果此时键盘又有新的键被按下,键盘控制器8042 将不再接收 键盘编码器8048传送过来的扫描码,一直到缓冲区被清空,所以这就是为什么引入输入缓冲区的原因.)
    • 我们再来个补充(对比假设):
      • 假设1)添加键盘输入缓冲区(占用内存空间)后:只要键入数据,那么就会触发键盘中断处理程序,该程序会从 键盘控制器8042的输入缓冲寄存器中读取键入数据的扫描码,并存储在键盘输入缓冲区中(之前已经建立在内存空间中了),也即让8042的输入缓冲区被清空,这样8042才会接收 键盘编码器8048传送过来的键入数据的 扫描码;
      • 假设2) 如果不添加键盘输入缓冲区(占用内存空间):只要键入数据,那么就会触发键盘中断处理程序,该程序会从 键盘控制器8042的输入缓冲寄存器中读取键入数据的扫描码,并显示该扫描码对应的数据;
      • 假设2中的问题):如果CPU没有立即响应中断处理程序 怎么办? 这使得8042的输入缓冲区不能被清空,反正一句话,就是要尽快让键盘控制器8042的输入缓冲器清空,这样才能使得8042可以连续不断地接受8048 传送过来的扫描码;
  • Solution1)我们将 从键盘控制器 8042 的输入缓冲寄存器(只能缓冲一个字节的数据)中读取数据的代码从 keyboard_read 函数中抽取出来,并封装到 get_byte_from_kbuf()函数中; 这样对于扫描码比较长的字符来说,我们可以通过 keyboard_read 函数多次读取键盘缓冲区中的数据(键入数据的扫描码而已);

  • 键盘缓冲区的作用(function)(干货):

    • 有了键盘缓冲区, 8042 缓冲区 无需受到 task_tty 进程运行状况的影响,因为键盘中断处理程序 是将输入的数据 保存到内存缓冲区去了,这样键盘控制器8042的输入缓冲器被清空,可以继续接受8048传送过来的扫描码;
  • Problem2)关于非打印字符的问题: 如果按下 诸如 F1、F2这样的功能键,系统会把它当做可打印字符来处理,从而打印出一个奇怪的符号;
    Solutions2)我们的意思是: keyboard_read这个函数只是 负责读取扫描码就可以了(一次或多次调用get_byte_from_kbuf 函数 ),至于如何处理, 不应该由它来负责(因为不是所有键入的字符都是需要打印字符, 如Ctrl、Shift、大写锁定键、Esc键等);所以,我们又将打印字符的代码抽取为 in_process ()函数, 在in_process()函数中,依据扫描码判断键入的字符是否需要打印;(具体代码调用如下图所示)
    os如何处理键盘的所有按键,显示or不显示,显示是如何显示

os如何处理键盘的所有按键,显示or不显示,显示是如何显示的更多相关文章

  1. OS X 键盘快捷键

    了解有关常见 OS X 键盘快捷键的信息.键盘快捷键是通过按下键盘上的组合键来调用 OS X 功能的一种方式. 若要使用键盘快捷键或按键组合,您可以同时按修饰键和字符键.例如,同时按下 Command ...

  2. MacBook键盘锁定、按键失效、无反应等问题

    目录 MacBook按键无反应 u,i,o,j,k,l等键失灵 capslock灯不亮 原文链接:joselynzhao·CSDN·MacBook键盘锁定.按键失效.无反应等问题 MacBook按键无 ...

  3. 《连载 | 物联网框架ServerSuperIO教程》- 13.自定义视图显示接口开发,满足不同的显示需求

    1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...

  4. Java基础-多线程编程-1.随便选择两个城市作为预选旅游目标。实现两个独立的线程分别显示10次城市名,每次显示后休眠一段随机时间(1000ms以内),哪个先显示完毕,就决定去哪个城市。分别用Runnable接口和Thread类实现。

    1.随便选择两个城市作为预选旅游目标.实现两个独立的线程分别显示10次城市名,每次显示后休眠一段随机时间(1000ms以内),哪个先显示完毕,就决定去哪个城市.分别用Runnable接口和Thread ...

  5. java显示本地磁盘所有盘符,显示桌面路径

    import java.io.File; import javax.swing.filechooser.FileSystemView; /** 显示本地磁盘根盘符,显示桌面路径 */ public c ...

  6. ajax导致Echarts不显示饼图数据、柱状图数据只显示气泡的问题。

    1.ajax导致Echarts不显示饼图数据.柱状图数据只显示气泡的问题. ajax的同步.这个同步的意思是当JS代码加载到当前ajax的时候会把页面里所有的代码停止加载,页面出去假死状态,当这个aj ...

  7. 百度地图api在Html中显示,在jsp页面中不显示解决方法

    在jsp页面中显示如下 但是在html中正常显示. 原来的代码如下: <script type="text/javascript" src="http://api. ...

  8. swiper默认显示三个,中间放大且显示全部图片两边显示部分图片的实现方法

    本页面内容最后的红色部分有惊喜哦! 最近在做一个活动页面,要求触摸切换图片时,默认在可视区域中显示三张图片,其中中间的一张图片比其他两张都大且全部显示,而其他两张图片只显示部分即可,于是就想到了swi ...

  9. DIV内容超出长度显示省略号,鼠标移上自动显示全部内容(EasyUI DataGrid)

    如果想把DIV中超出的文本显示成省略号,而不是换行全部显示,有2个办法. 注:本文主要是以EasyUI的DataGrid为案例的,如果是其他场景只要底层是用DIV显示文本的应该都能使用. 首先可以给此 ...

随机推荐

  1. Shell中的单引号(‘)双引号(”)和反引号(·)

    在bash中,$.*.?.[.].’.”.`.\.有特殊的含义.类似于编译器的预编译过程,bash在扫描命令行的过程中,会在文本层次上,优先解释所有的特殊字符,之后对转换完成的新命令行,进行内核的系统 ...

  2. linux内核情景分析之信号实现

    信号在进程间通信是异步的,每个进程的task_struct结构有一个sig指针,指向一个signal_struct结构 定义如下 struct signal_struct { atomic_t cou ...

  3. hdu 1395(欧拉函数)

    2^x mod n = 1 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...

  4. hdu 1005(找循环节)

    Number Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  5. Android项目搭建最常用的架构解密

    在完成android项目的时候第一步都是要搭建架构,下面我们来展示一下最常用的架构结构的: 源码下载地址: https://download.csdn.net/download/heishuai123 ...

  6. 牛客网 牛客小白月赛2 H.武-最短路(Dijkstra)

    H.武 链接:https://www.nowcoder.com/acm/contest/86/H 这个题写的有点想发脾气,自己的板子垃圾了,这个题要用优先队列优化版的迪杰斯特拉的板子才可以过,但是自己 ...

  7. HDU 1033 Edge[地图型模拟/给你一串字符串,A代表以此点为参照顺时针90°,V代表逆时针90°]

    Edge Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  8. ansible-playbook启动的多种方式

    #quick start ## start the playbook with no password, it will run "sudo su - root" at the t ...

  9. (入门SpringBoot)SpringBoot后台验证(八)

    后台验证的作用主要是防止postman...等等工具的恶意提交,前后台都判断数据,双保险. .可以在SpringBoot传参数 加上NotNull.... //分组Default,分组的好处就是可重复 ...

  10. MAC(Linux)升级Openssl

    系统上一般默认安装的是0.9.8版本的Openssl,不能满足需要.这时候就要重新安装Openssl. 上官网下载新版openssl:https://www.openssl.org/source/ 解 ...