os如何处理键盘的所有按键,显示or不显示,显示是如何显示

【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()函数中,依据扫描码判断键入的字符是否需要打印;(具体代码调用如下图所示)
    这里写图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/332052.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hibernate的缓存机制/会话级缓存机制

Hibernate 中维持了两级缓存。第一级缓存由 Session 实例维护,该缓存区保存着与该 Session 实例有关联的所有实体对象的数据,也称为内部缓存。而第二级缓存则存在于 SessionFactory 实例中,由通过该 SessionFactory 实例获取的所有 Session 实…

orm提取指定列_使用ORM提取数据很容易! 是吗?

orm提取指定列介绍 几乎所有系统都以某种方式与外部数据存储一起运行。 在大多数情况下,它是一个关系数据库,并且通常将数据获取委托给某些ORM实现。 ORM涵盖了很多例程,并且带来了一些新的抽象作为回报。 Martin Fowler写了一篇有关ORM的有…

如何编译文件(gcc + nasm)

【0】README 编译文件(nasm gcc),特别是编译目标文件的依赖文件;本文旨在回顾 gcc 和 nams 编译器的编译命令,以及如果有多个依赖文件该如何编译; 【1】编译文件 1.1)编译 lib/syscall.asm(lib/syscall.asm) nasm …

Hibernate中的Session.load() 和 Session.get() 的区别

文章目录相同点区别懒加载的问题执行语句 session.load(UserInfoBean.class,2) 会先在一级缓存中找 id2 的 UserInfoBean 对象(看红色线条),找不到去二级缓存找,还找不到就不找了,直接获取一个代理对象并返回该对象。当…

python 分布式队列_〖Python〗-- Celery分布式任务队列

【Celery分布式任务队列】一、Celery介绍和基本使用Celery 是一个 基于python开发的分布式异步消息任务队列,通过它可以轻松的实现任务的异步处理, 如果你的业务场景中需要用到异步任务,就可以考虑使用celery, 举几个实例场景中可…

最大子序列和问题的解(共4种,层层推进)

【0】README 0.1) source code and text description are from data structure and alg analysis ; 0.2) there are 4 methods solving maximum sum of subsequence, but the fourth proves to be the best one , the 3rd deser…

java设计模式代理模式_Java中的代理设计模式

java设计模式代理模式代理对象或代理对象为另一个对象提供占位符,以控制对该对象的访问。 代理充当原始对象的轻量级版本或简化版本。 它支持与原始对象相同的操作,但可以将那些请求委托给原始对象以实现它们。 代理设计模式是一种结构模式,…

Struts2参数值自动注入到JavaBean对象的属性中和JavaBean对象的属性值展示在页面中

文章目录参数值自动注入示例代码将JavaBean的属性值显示在页面上示例代码参数值自动注入 注意事项: 1.前端界面的表单项的参数命名格式为:Action属性名.JavaBean的属性名 2.Action的属性必须要有setter/getter方法,注入时会调用setter方法 …

ibmmq 通道命令_IBM MQ常用命令

常用命令创建队列管理器crtmqm –q QMgrName-q是指创建缺省的队列管理器删除队列管理器dltmqm QmgrName启动队列管理器strmqm QmgrName如果是启动默认的队列管理器,可以不带其名字停止队列管理器endmqm QmgrName 受控停止endmqm –i QmgrName 立即停止endmqm –p Qm…

算法运行时间中的对数

【0】README 0.1) source code and text description are from data structure and alg analysis ; 【1】分析算法最混乱的方面大概集中在对数上面, 除分治算法外,可将对数最常出现的规律概括为下列一般法则: 1.1&a…

java项目:永和大王项目_Java项目:书评

java项目:永和大王项目本文是关于这本书的 Peter Verhas撰写的Java Projects Second Edition 我去年写的 这样一篇文章的目的通常是为了促进这本书的销售。 在这种情况下没有什么不同,但是由于这是我写的书,而且我是撰写评论的人,因此赞美这…

Struts2+Hibernate项目中的时间和日期问题

文章目录数据表中的 datetime 的数据如何通过 json 传送给前端仅展示其日期,而不展示时间日期控件日期时间数据展示问题日期时间数据存储问题场景一场景二场景三场景四数据表中的 datetime 的数据如何通过 json 传送给前端仅展示其日期,而不展示时间 数…

把一个人的特点写具体作文_把一个人的特点写具体作文

把一个人的特点写具体作文在日常学习、工作抑或是生活中,大家都跟作文打过交道吧,写作文可以锻炼我们的独处习惯,让自己的心静下来,思考自己未来的方向。那要怎么写好作文呢?下面是小编为大家整理的把一个人的特点写具…

spring boot简介_Spring Boot简介

spring boot简介在本教程中,我们将看一下Spring Boot,看看它与Spring框架有何不同。 我们还将讨论Spring Boot提供的各种功能。 什么是Spring Boot? 在开发企业级应用程序时,Spring是一个功能强大的框架。 它为我们提供了诸如依赖…

C语言的运算符的优先级与结合性+ASCII表

【0】README 0.1) 内容来源于 C程序设计语言, 旨在整理出C语言的运算符的优先级与结合性, 如下图所示(哥子 记了大半年都没有记住,也是醉了,每次都要去翻); 0.2) 再补充…

退货退款的售后,如何返还金币/有偿优惠券的问题

假设买家购买了3个商品,商品的销售价是10元,商品总金额是30元 买家应付金额是 30 元,买家使用5个金币抵扣5元,买家实付金额是 25 元。 后来买家退货 2 件,怎么退款和退币呢? 要将金币分摊到每个商品上&a…

python orm框架sqlalchemy_python ORM框架:SqlAlchemy

ORM,对象关系映射,即Object Relational Mapping的简称,通过ORM框架将编程语言中的对象模型与数据库的关系模型建立映射关系,这样做的目的:简化sql语言操作数据库的繁琐过程(原生sql的编写及拼接等),转而直接使用对象模…

javadoc提取工具_使JavaDoc保持最新状态的工具

javadoc提取工具在许多项目中,文档不是最新的。 更改代码后,很容易忘记更改文档。 原因是可以理解的。 在代码中进行更改,然后进行调试,然后希望在测试中进行更改(或者,如果您使用的是更多TDD,则…

栈应用(中缀表达式转后缀表达式并计算后缀表达式的值)

【0】README 0.1) 本文旨在总结 中缀表达式转后缀表达式并计算后缀表达式的值 的步骤,并给出源代码实现; 0.2) 本文中涉及到的源代码均为原创,是对中缀转后缀和计算后缀的简单实现,(旨在理清它…

用户/账户/账号的理解

文章目录用户账户账号关系用户 用户概念的理解: 用户就是使用者,可以是个人用户,也可以是机构用户。 账户 账户概念的理解: 账户,所谓“账”,就是系统根据“账”来存储和管理数据,类似记账…